作者:Chu
來源:微信公眾號:sh3ll

1. 前言

老板前一段給買了幾款路由把玩,研究了下 D-Link DIR 629、DIR 823 這兩款板子。

發現在 soap.cgi 中存在幾處棧溢出,均可以遠程利用,并且其他型號的路由也有對 soap 這一部分代碼的復用。

2. 逆向分析與漏洞挖掘

因為是想挖幾個能遠程利用的洞,首先去看了 HTTP 服務,也就是 /htdocs/cgibin。

D-Link HTTP 服務由cgibin提供,并通過軟鏈接的文件名進入到不同的處理分支:

在各個 cgi 處理函數中,會通過 cgibin_parse_request 來解析用戶輸入,其函數原型大致如下:

參數 save_param_func 用于傳入解析/存儲 HTTP 請求的具體 handler,讀取 HTTP 請求后使用該 handler 具體處理用戶輸入。在 soapcgi_main(0x00418E28)中傳入了漏洞函數 vulnerable_sprintf_parser(0x0041893C)

跟進 vulnerable_sprintf_parser 可以發現程序未進行邊界檢查便將全局變量 g_http_soapaction 通過 sprintf 寫到棧上:

g_http_soapaction 來自于 soapcgi_main 中對 HTTP Header SOAPACTION 字段的解析:

取 HTTP_SOAPACTION:

取 # 后的值:

至此漏洞原理已經明了:soapcgi_main 中未進行邊界檢查便將 HTTP Header 中的 SOAPACTION 字段存儲至棧上,導致棧溢出。

3. 漏洞利用

基礎信息:

MIPS 大端序,開啟了 NX,未開啟 ASLR、PIE,只需要做個 ROP。

溢出的崩潰現場如下:

S2-S3、SP 指向的內存可控,要編寫 ROP 只能在這幾個寄存器上做文章,最終用 ropper 在 uClibc 中找了個很不錯的 gadget:

現在需要做的就是找到 libc 加載的實際基址。

在隔壁開鎖王師傅的指導下把板子拆開,接上串口:

成功獲取到 shell:

拿到 shell 后讀 /proc/pid/maps 就可以獲取到libc的加載基址。

最終編寫 ROP 如下:

攻擊演示:


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