Miniupnpc Miniwget緩衝區溢位漏洞再分析
*本文作者:j0hnShi,本文屬 FreeBuf 原創獎勵計劃,未經許可禁止轉載。
0×00 引言
由於最近在挖掘一款程式漏洞, 看到此程式呼叫了 miniupnpc.dll 1.6.xxx 所以下載了個相應版本的miniupnpc 進行了程式碼審計, 發現存在幾處安全漏洞, 查詢相關漏洞庫, 發現這是已存在並且已在高版本中修復的安全問題, 本篇我們重點分析如何發現和如何驗證的一些方法。
0×01 如何發現
在原始碼審計的過程中,使用關鍵字查詢、輸入流跟蹤等方式進行初步的審計,當到Miniwget.c 的時候, 發現了此安全問題。
漏洞存在位置: miniwget.cgetHTTPResponse函式memcpy(content_buf + content_buf_used, buf + i, bytestocopy);中。
其中 bytestocopy是可以控制的, 而這次的安全問題也是出現在這, bytestocopy < 0 則會產生漏洞。我們縣驗證下是否會產出fault。
我們把bytestocopy 直接賦值 0×8000000。
執行結果:
發生 segmentation fault 。
我們來看下bytestocopy的整個資料流:
unsigned int bytestocopy = 0; ... bytestocopy = ((int)chunksize < n - i)?chunksize:(n - i); memcpy(content_buf + content_buf_used, buf + i, bytestocopy);
然而bytestocopy 是 chunksize, 我們看下chunksize的資料流:
unsigned int chunksize = 0; ... for(j = 0; j < chunksize_buf_index; j++) { if(chunksize_buf[j] >= '0' && chunksize_buf[j] <= '9') chunksize = (chunksize << 4) + (chunksize_buf[j] - '0'); else chunksize = (chunksize << 4) + ((chunksize_buf[j] | 32) - 'a' + 10); } ...
從中我們可以看出 chunksize 會通過一些運算來最終得到 chunksize, 而且運算也比較容易得出。
0×02 漏洞除錯和驗證
至此, 我們已經找到那個問題點, 然後這個點也是可以控制的, 那我們如何構造這個資料讓原始程式可以走到並且產生問題呢?
從原始碼中也可以看到chunksize 是從Body中獲取的:
通過閱讀他的原始碼, 發現他解析的是http 的 response 響應體, 並且需要有幾個必須的欄位:
Content-Type: text/html Transfer-Encoding: chunked Content-Length: 1
然後是Body資料, 而我們需要控制的是 Body中的資料。
那我們如何來構造資料呢?
構造如下response 響應體:
HTTP/1.1 200 OK Transfer-Encoding: chunked Content-Length: 1 Content-Type: text/html f <xml>test</xml> 80000000 Test
即可出發漏洞, 為了驗證漏洞, 我吧getHTTPResponse函式進行了單獨編譯, 並製作成socket服務方便除錯。
編譯執行此檔案:
使用python 編寫一個POC:
執行此POC:
同樣出現了 segmentation fault。
0×03 結語
最後查詢了一些相關文件,發現此漏洞早已存在,並且新版本已經修復,但由於很多應用會使用低版本的miniupnpc, 同樣會出現這個漏洞。漏洞的具體利用就不在闡述, 可以檢視CVE-2017-8798。
所編寫的程式碼:
連結: https://pan.baidu.com/s/1PcT09Td3BB14rLbHBVb98A 提取碼:q69e
*本文作者:j0hnShi,本文屬 FreeBuf 原創獎勵計劃,未經許可禁止轉載。