作者:LoRexxar'@知道創宇404實驗室
時間:2018年12月7日
英文版本:http://www.bjnorthway.com/981/
2018年12月3日,@L3mOn公開了一個Discuz x3.4版本的前臺SSRF,通過利用一個二次跳轉加上兩個解析問題,可以巧妙地完成SSRF攻擊鏈。
https://www.cnblogs.com/iamstudy/articles/discuz_x34_ssrf_1.html
在和小伙伴@Dawu復現過程中發現漏洞本身依賴多個特性,導致可利用環境各種縮減和部分條件的強依賴關系大大減小了該漏洞的危害。后面我們就來詳細分析下這個漏洞。
漏洞產生條件
- 版本小于 41eb5bb0a3a716f84b0ce4e4feb41e6f25a980a3 補丁鏈接
- PHP版本大于PHP 5.3
- php-curl <= 7.54
- DZ運行在80端口
- 默認不影響linux(未100%證實,測試常見linux環境為不影響)
漏洞復現
ssrf
首先漏洞點出現的位置在/source/module/misc/misc_imgcropper.php line 55

這里$prefix變量為/然后后面可控,然后進入函數里
/source/class/class_image.php line 52 Thumb函數

然后跟入init函數(line 118)中

很明顯只要parse_url解得出host就可以通過dfsockopen發起請求
由于這里前面會補一個/,所以這里的source必須是/開頭,一個比較常見的技巧。
//baidu.com
這樣的鏈接會自動補上協議,至于怎么補就要看具體的客戶端怎么寫的了。
我們接著跟dfsockopen到/source/function/function_core.php line 199

然后到source/function/function_filesock.php line 31

主要為紅框部分的代碼,可以看到請求的地址為parse_url下相應的目標。
由于前面提到,鏈接的最前為/,所以這里的parse_url就受到了限制。

由于沒有scheme,所以最終curl訪問的鏈接為
://google.com/
前面自動補協議就成了
http://://google.com/
這里就涉及到了很嚴重的問題,就是對于curl來說,請求一個空host究竟會請求到哪里呢?
在windows環境下,libcurl版本7.53.0

可以看到這里請求了我本機的ipv6的ip。
在linux環境(ubuntu)下,截圖為7.47.0

測試了常見的各種系統,測試過程中沒有找到不會報錯的curl版本,暫時認為只影響windows的服務端環境。
再回到代碼條件下,可以把前面的條件回顧一下:
1、首先我們需要保證/{}可控在解parse_url操作下存在host。
要滿足這個條件,我們首先要對parse_url的結果有個清晰的認識。
在沒有協議的情況下,好像是參數中不能出現協議或者端口(:號),否則就不會把第一段解析成host,雖然還不知道為什么,這里暫且不論。

在這種情況下,我們只需要把后面可能出現的http去掉就好了,因為無協議的情況下會默認補充http在前面(一般來說)。
2、curl必須要能把空host解析成localhost,所以libcurl版本要求在7.54.0以下,而且目前測試只影響windows服務器(歡迎打臉
3、dz必須在80端口下
在滿足上面的所有條件后,我們實際請求了本地的任意目錄
http://://{可控}
===>
http://127.0.0.1/{可控}
但這實際上來說沒有什么用,所以我們還需要一個任意url跳轉才行,否則只能攻擊本地意義就很小了。
任意url跳轉
為了能夠和前面的要求產生聯動,我們需要一個get型、不需要登陸的任意url跳轉。
dz在logout的時候會從referer參數(非header頭參數)中獲取值,然后進入301跳轉,而這里唯一的要求是對host有一定的驗證,讓我們來看看代碼。
/source/function/function_core.php:1498

上面的截圖解釋了這段代碼的主要問題,核心代碼為紅框部分。
為了讓referer不改變,我們必須讓host只有一個字符,但很顯然,如果host只能有一個字符,我們沒辦法控制任意url跳轉。
所以我們需要想辦法讓parse_url和curl對同一個url的目標解析不一致,才有可能達到我們的目標。
http://localhost#@www.baidu.com/
上面這個鏈接parse_url解析出來為localhost,而curl解釋為www.baidu.com
我們抓個包來看看

成功繞過了各種限制
利用
到現在我們手握ssrf+任意url跳轉,我們只需要攻擊鏈連接起來就可以了。攻擊流程如下
cutimg ssrf link
=====>
服務端訪問logout任意url跳轉
====301====>
跳轉到evil服務器
=====302=====>
任意目標,如gophar、http等
當然最開始訪問cutimg頁面時,需要先獲取formhash,而且referer也要相應修改,否則會直接攔截。
exp演示

本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/756/
暫無評論