<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    CVE-2022-1040 Sophos Firewall 服務架構與認證繞過漏洞分析之旅

    VSole2022-06-20 06:28:51

    漏洞信息

    前端時間 Sophos Firewall 爆出了一個認證繞過漏洞 CVE-2022-1040 ,最近在深入分析 Sophos 服務架構的同時,完整復現了該漏洞。主要是在 `User Portal` 及 `Webadmin` 兩個接口存在認證繞過漏洞,漏洞巧妙利用了 Java 和 Perl 處理解析 JSON 數據的差異性,實現了變量覆蓋,從而導致認證繞過及命令執行。漏洞適用范圍為 Sophos Firewall v18.5 MR3 及以下版本。

    環境搭建

    首先從官網下載老版本虛擬機。本文研究下載版本為 `VI-18.5.2_MR-2.VMW-380`:

    按照提示很容易完成安裝。Sophos 的 Web 接口主要通過 Java 實現,由啟動命令可以看出 Sophos 使用的是 openjdk 環境,如果在 Java 啟動參數中直接添加調試參數,將會出現找不到 `libjdwp.so` 動態鏈接庫的錯誤:

    可以通過自行上傳完整 JDK 來解決這個問題:

    重啟 Java 服務即可看到監聽的端口。

    服務架構

    Sophos 中的服務架構不是很復雜,主要使用了 Apache 、 Jetty 等 web 服務,第一層語言為 Java 通過網絡通信的方式與后端 Perl 服務進行交互:

    0x01 Apache 配置

    Apache 的啟動命令如下:


    apache -d /_conf/httpd -DFOREGROUND
    

    進入 `/_conf/httpd` 目錄,存放有 Apache 的配置文件,通過分析 `httpd.conf`,了解 Apache 引用了 `/cfs/web/apache/httpd.conf` 配置:


    Define userportal_listen_port 65004Define webconsole_https_port 65003Define SSLCertificateFileWithPath "/conf/certificate/ApplianceCertificate.pem"Define SSLCertificateKeyFileWithPath "/conf/certificate/private/ApplianceCertificate.key"Define https_cert_valid true
    

    從配置中可以看出 Apache 開放了兩個主要的端口 `userportal 65004` 和 `webconsole 65003` :

    在 Apache 配置目錄下搜索 `ProxyPass`,找到的代理轉發配置如下:


    ./ssl.conf:53:    ProxyPass /webconsole/images !./ssl.conf:54:    ProxyPass /webconsole/css !./ssl.conf:55:    ProxyPass /webconsole/javascript !./ssl.conf:56:    ProxyPass /webconsole http://localhost:8009/webconsole./ssl.conf:57:    ProxyPassReverse /webconsole http://localhost:8009/webconsole./userportal-static.conf:64:    ProxyPass /userportal/images !./userportal-static.conf:65:    ProxyPass /userportal/CRSSL !./userportal-static.conf:66:    ProxyPass /userportal http://localhost:8009/userportal./userportal-static.conf:67:    ProxyPassReverse /userportal http://localhost:8009/userportal
    

    代理轉發策略將 `webconsole` 和 `userportal` 端口分別代理到 `8009` 端口的不同 URL :


    ProxyPass /webconsole http://localhost:8009/webconsoleProxyPass /userportal http://localhost:8009/userportal
    

    0x02 Jetty 配置

    Jetty 配置文件為 `/usr/share/jetty/start.ini`,開啟了本地服務的 `8009` 端口:

    Jetty 的啟動參數在 `/usr/bin/jetty` 腳本中配置,如果要修改可直接修改該文件最后 Java 執行部分。

    0x03 CSC 配置

    CSC 是 Sophos 的主要服務之一,主要負責啟動各個服務進程及提供 API 接口供其他程序服務調用。其啟動命令為:


    csc -L 3 -w -c /_conf/cscconf.bin
    


    CSC 為標準的 ELF 32bit 可執行程序,可通過逆向分析其中功能。`cscconf.bin` 中在 CSC 程序中有調用解壓,猜測是一個加密壓縮包。

    `/usr/bin/csc` 由 C 語言編寫,負責啟動加載其他的服務以及加載 Perl 代碼,在虛擬機中 CSC 啟動部分服務如下:

    程序中的 `extract_conf` 函數負責解密 `cscconf.bin` 并提取壓縮包中的內容:

    `decrypt_bin` 函數主要是通過異或算法將 `cscconf.bin` 數據解密為 `cscconf.tar.gz` 壓縮包格式:

    每次取 `0x420` 個字節通過 `xor_decrypt` 函數進行加密塊解異或解密,將解密后數據中的 `0x400` 個字節寫入 `tar.gz` 文件:

    `xor_decrypt` 核心代碼如下,主要通過與 `0x80DCB40` 地址中實現存放的 64 字節逐一進行異或處理:

    通過逆向該算法,使用 Python 編寫出加解密算法實現代碼。解密得到 `cscconf.tar.gz` 壓縮包,解開壓縮包目錄如下:

    在壓縮包中的其中一個目錄名為 `service` ,推測 CSC 通過該目錄下的配置文件啟動相關服務:

    補丁對比

    配置 Sophos vmware 網卡連網后等待一段時間,將虛擬機上的文件與原來的文件進行對比,其中有兩個修改的地方,一處為 `web.xml`,另一處添加了 `RequestCheckFilter.class` 文件:

    web.xml` 增加了一段配置,主要給 Sophos Java 代碼添加 `RequestCheckFilter `過濾器,過濾器主要檢測 request 請求包中的 JSON 參數是否包含不可見字符:

    檢測規則中,JSON 參數的每個字符都必須是 `32~127` 之間,如果超出范圍則會跳轉到登錄界面:

    那么給我們的啟發就是此次漏洞和 JSON 參數中的不可見字符有著直接的關系,應該是字符編碼導致的認證繞過。

    JSON 解析差異性分析

    漏洞原理可簡單理解為 Java 在使用 `unicode \u0000` 時,JSON 認為 `key` 是兩個不同的 `key` 并沒有 `0` 字節截斷,當 Java 把含有 unicode 編碼的 `key` 發送給后端的 Perl處理時 `\u0000` 產生了截斷效果,使得帶有 unicode 編碼的 `key` 變為了 `mode`, Perl 可以處理重復 `key` 的 JSON,如果重復則后面覆蓋前面的值:

    我們可以通過一個示例來對比不同語言處理 JSON 重復鍵的差異性。Java 處理帶有 unicode 編碼的 `key` 時可以正常解析:


    import org.json.JSONObject;import org.json.JSONException;import java.io.*;class test {    public static void main(String[] args) {        try{          System.out.println(new JSONObject("{ \"name\": \"test\", \"name\\u0000ef\": \"test2\"}"));        }catch (JSONException e){          System.out.println(e);        }    }}
    

    Perl 處理 Java 傳遞過來的零字節字符串就會產生截斷效果,在處理相同 `key` 值的 JSON 時會取最后一個 `key` 對應的 `value` :


    #!/usr/bin/perluse JSON;
    my %rec_hash = ('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5, 'a' => 6);my $json = encode_json \%rec_hash;print "$json";
    

    其結果為 `a` 被覆蓋為了最后一個 `a` 的值:

    不同語言對 JSON 解析的差異性是此次認證繞過漏洞的核心原理。Java 接收來自用戶的以下數據(其中 `\u0000` 后面的 `ef` 是為了讓 JSON中 `key` 的 hash 排序將 `716` 排到 `151` 的后面):


    {"mode":151,"mode\u0000ef":716}
    

    登錄認證分析

    通過登錄 `webadmin` 獲取登錄數據包:

    根據 `/webconsole/Controller` 及 `mode=151` 尋找 Java 代碼中的處理邏輯,首先分析 `web.xml` 中路由對應的 Servlet :

    主要由 `CyberoamCommonServlet` 進行處理,該類主要解析 `mode` 值,并通過 `mode` 進行分發:

    進入 `_doPost` 函數繼續進行分發, `EventBean` 從數據庫中獲取 `mode` 對應的屬性,其中就包括關鍵屬性 `Requesttype` :

    通過 `Requesttype` 將請求分為了三種:

    •  `Requesttype` 為 `1` ,使用 `CyberoamAjaxHelper` 處理;
    •  `Requesttype` 為 `2` ,使用 `CyberoamCustomHelper` 處理;
    •  `Requesttype` 為其他值時,使用 `generateAndSendOpcode` 處理。

    進入 `CyberoamCustomHelper` 之后,通過匹配 `mode` 值進行分發,將會進入 `WebAdminAuth` 類中進行處理:

    `process` 函數對請求中的 JSON 字段進行解析,獲取 `jsonObject` 之后將會給 `cscClient` 通過 `localhost:299` 發送給 CSC 進程進行處理:

    比較有意思的是 Sophos 通過 `cscClient` 返回的 Status code 判斷是否登錄成功,因此在 Java 代碼中是看不到登錄認證的完整過程的,如下圖所示如果返回為 `200` 則會生成合法 `sessionBean` :

    合法 `sessionBean` 生成過程如下,將 `session` 中填充 `username` 、 `userid` 、 `csrftoken` 等關鍵信息:

    因此我們只需要找到后臺返回 `200` 的函數即可。

    CSC Perl API 分析

    因為 webadmin login mode 151 的 `Requesttype` 為 `2` ,在 `_send` 函數最后獲取返回值的時候使用 `getStatusFromResponse` 進行解析:

    使用 `eventBean` 判斷 `Requesttype` ,因為該 `eventBean` 在數據包剛開始處理的時候就根據 `mode` 值在數據庫中進行搜索匹配,中間沒有修改的可能性。在如下 `else` 分支中需要獲取 JSON 結果的 `status` 字段:


    因此在尋找可返回 `200` 的 `mode` 值時需要考慮的是要能夠同時返回 `status` 字段,通過搜索數據庫找到所有 `Requesttype` 為 `2` 的 `OPCODE` ,其中有 `716` 符合條件。注意 Perl 代碼獲取了 `request` 中的 `accessaction` 字段,并且需要該字段為 `1` 才能返回 `200` 。

    漏洞復現

    通過前面的分析,我們很容易構造特殊的 JSON 數據包實現認證繞過。如果數據包中返回 `status` 的為 `200` ,并且 `redirectionURL` 路由為 `index.jsp` 即為認證成功,直接取 `Set-Cookie` 中的 `JSESSIONID` 進行使用:

    在未登錄條件下在瀏覽器中添加上述認證后返回的 `session`,操作如下:

    替換瀏覽器中的 `JSESSIONID` ,并在 url 處輸入 `index.jsp` 回車進行跳轉:

    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    'User Portal' 及 'Webadmin' 兩個接口存在認證繞過漏洞,漏洞巧妙利用了 Java 和 Perl 處理解析 JSON 數據的差異性,實現了變量覆蓋,從而導致認證繞過及命令執行。
    Hive勒索軟件操作已將其VMware ESXi Linux加密程序轉換為Rust編程語言,并添加了新功能,使安全研究人員更難窺探受害者的勒索談判。
    來自 Cisco Talos 的研究人員發現了一種不常見的惡意軟件,該惡意軟件被用于針對烏克蘭一家大型軟件開發公司的攻擊。
    域滲透重要漏洞匯總
    域滲透歷史漏洞匯總
    2022-04-12 06:53:58
    域滲透歷史漏洞匯總
    一個內網安全攻防的知識倉庫
    谷歌周二推出了適用于桌面的Chrome瀏覽器補丁,來解決在野外積極利用的高嚴重性零日漏洞。跟蹤為CVE-2022-2856,該漏洞是關于對Intents中不可信輸入驗證不足的情況。安全研究人員Ashley Shen和谷歌威脅分析集團的Christian Resell于2022年7月19日報告了該漏洞。
    事實上,微軟在2021年7月1日到2022年6月30日期間,發出的最大單筆獎金達到20萬美元,獎勵的是Hyper-V虛擬機管理程序中的一個嚴重漏洞。今年,該公司還打算進一步引入新的研究挑戰和高影響攻擊場景。跟蹤為CVE-2022-2856,該漏洞是關于對Intents中不可信輸入驗證不足的情況。
    unserialize()函數能夠重新把字符串變回php原來的值。為了能夠unserialize()一個對象,這個對象的類必須已經定義過。如果序列化類A的一個對象,將會返回一個跟類A相關,而且包含了對象所有變量值的字符串。將對象格式化成有序的字符串。序列化的目的是方便數據的傳輸和存儲,在PHP中,序列化和反序列化一般用做緩存,比如session緩存,cookie等。
    在一些開啟了 Hyper-V 的電腦上,RouterOS 可能無法在 VMWare Workstation 中模擬運行或啟動非常緩慢,如果遇到無法運行的情況,請酌情考慮關閉 Hyper-V,如果能成功運行但是啟動緩慢,可以及時拍攝快照。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类