摄像头固件分析RCE漏洞笔记(binwalk)

摄像头固件分析RCE漏洞笔记(binwalk)

Posted by Closure on March 6, 2025

Binwalk 是一个专门用于固件分析的开源工具,从二进制文件(如嵌入式设备固件)中提取文件系统、解压缩数据、查找隐藏内容和固件的分析。

sudo apt install docker.io
sudo apt install git
git clone https://github.com/ReFirmLabs/binwalk

 偏移 (offset) 为 0表示着固件从第 0 字节开始就是一个可识别的 SquashFS 文件系统,没有单独的 Bootloader 分区或其他分区被检测到,进去看是个嵌入式 Linux 根文件系统结构

 没有看启动脚本 init.d,可能是放在其他目录或者修 BusyBox的开机流程将脚本放在只读分区、内置到特定二进制里?

 strings bin/alphapd | grep -i “/setSystemAdmin” 结果是/setform/setSystemAdmin /setform/setSystemAdmin 说明 alphapd 处理了该路径,要是AdminID 未经过滤,就能导致命令注入。

 ind . -name “chpasswd.sh” cat $(find . -name “chpasswd.sh”)

./sbin/chpasswd.sh
#!/bin/sh
#
# $Id: chpasswd.sh, v1.01 2015-03-24 steven
#
# usage: chpasswd.sh
#

user=`nvram_get 2860 AdminID`
pass=`nvram_get 2860 AdminPassword`

if [ "$user" == "" ]; then
    echo "chpasswd: no user name"
    exit 1
fi

echo "$user:$pass" > /tmp/tmpchpw
chpasswd < /tmp/tmpchpw
rm -f /tmp/tmpchpw

nvram_get 2860 AdminID 读取存储的 AdminID 变量。 nvram_get 2860 AdminPassword 读取 AdminPassword 变量。 echo “$user:$pass” > /tmp/tmpchpw 创建* /tmp/tmpchpw* 临时密码文件。 chpasswd < /tmp/tmpchpw *执行密码修改,直接影响 /etc/passwd*

攻击者可以通过 /setSystemAdmin 修改 AdminID 和 AdminPassword,然后触发 chpasswd.sh间接获得 root 访问权限。

strings bin/alphapd | grep -i "chpasswd"

chpasswd.sh被调用了,chpasswd.sh的逻辑在上面,AdminIDAdminPassword 直接影响 /etc/passwd,所以攻击者可以用 /setSystemAdmin 修改 AdminIDAdminPassword,并借此创建新用户和修改 root 密码。

strings bin/alphapd | grep -i "nvram"

nvram_bufget、nvram_bufset、nvram_commit 说明 alphapd 直接操作 nvram 存储,通过 /setSystemAdmin 修改 nvram 变量。比如 AdminID 可能被 nvram_bufset 存入 nvram,chpasswd.sh 再从 nvram_get 读取 AdminID,并写入* /etc/passwd*。


#!/bin/sh
# re-generate SSL Server Keys
cd /etc_ro
mkdir /usr/local
mkdir /usr/local/ssl
cp openssl.cnf /usr/local/ssl
openssl genrsa -out serverkey.pem 1024
openssl req -new -sha256 -x509 -keyout serverkey.pem -out servercert.pem -days 1825 -newkey rsa:1024 -nodes -subj "/C=TW/ST=Taiwan/L=Taipie/O=D-LINK/OU=DHPD Dept./CN=www.dlink.com"
#export SAN=DNS:127.0.0.1,DNS:Current's IP,DNS=DDNS Host Name
#openssl req -new -sha256 -x509 -extensions v3_req -keyout serverkey.pem -out servercert.pem -days 1825 -newkey rsa:1024 -nodes -subj "/C=TW/ST=Taiwan/L=Taipie/O=D-LINK/OU=DHPD Dept./CN=www.dlink.com"
#openssl x509 -text -in /etc_ro/servercert.pem
cd /

所有设备生成的 SSL证书共享都相同的信息,www.dlink.com (?)

openssl x509 -text -noout -in ./etc_ro/servercert.pem

www.dlink.com,确实所有设备可能共享相同的证书

strings bin/alphapd | grep -i "servercert.pem"

设备强制依赖* /etc_ro/servercert.pem* 作为 SSL 证书。

现在思路是servercert.pem 是否可以被替换,alphapd 如何处理 servercert.pem,如果 alphapd 有写入 servercert.pem *的逻辑,说明设备可能在某些情况下自动生成并覆盖 *servercert.pem,可以利用这一逻辑写入自定义证书。

mount | grep "/etc_ro"

看来ro是只读,不能直接替换证书。

objdump: can’t disassemble for architecture UNKNOWN!这是一个 MIPS 可执行文件,所以尝试用file bin/alphapd。

strings bin/alphapd | grep -A 5 -B 5 "servercert.pem"

分析 servercert.pem 在 alphapd 中的使用,alphapd 依赖* servercert.pem* 和 serverkey.pem,alphapd 尝试写入 servercert.pem,设备支持替换 HTTPS 证书?但是试了试找不到触发写入的方式。

find squashfs-root/ -type f -exec file {} + | grep "ELF"

提取所有 ELF 文件

ls -lah squashfs-root/etc_ro/web/

检查 Web 服务器目录

IP回连

8191 HTTP 170.421438 2.65.87.199 2.65.87.200 915 POST /setSystemAdmin HTTP/1.1 (application/x-www-form-urlencoded)

http.request.method == "POST"

看看可疑路径/setSystemAdmin

http.request.method == "POST" && http contains "setSystemAdmin"

POST /setSystemAdmin HTTP/1.1 Host: 2.65.87.200 Content-Length: 123

AdminID=atelnetd AdminPassword=12345

利用 AdminID 传入a\telnetd命令,成功在摄像头上启动 telnetd进程。

获取固件 解包→查找Web端的管理接口→分析二进制ELF→AdminID 传入 telnetd 命令→开启 Telnet,获取 root 权限

补充

固件逆向过程中,不安全的函数:

  • system():直接执行 shell 命令
  • popen():执行命令并返回输出流
  • execve(), execl(), execlp(), execv(), execvp():执行二进制程序
  • eval():执行动态代码,常用于 Web 端的 RCE。
char cmd[256];
sprintf(cmd, "ping %s", user_input);
system(cmd); // 用户可控输入,可能执行恶意命令
strings binary | grep -E "system|popen|exec"
搜索这些函数的交叉引用,检查参数是否直接来自 HTTP 请求或外部输入。

可能导致缓冲区溢出的函数

  • strcpy():不检查目标缓冲区长度,易溢出
  • strcat():字符串拼接时未检查长度,易溢出
  • sprintf():格式化字符串未检查长度
  • gets():读取用户输入时未检查缓冲区
  • scanf()(使用 %s 读取字符串时未指定长度)
strings binary | grep -E "strcpy|sprintf|gets"

判断是否存在命令注入漏洞

  • 检查输入源
  • 来自 Web 界面(HTTP POST/GET 参数):
  • /setSystemAdmin
  • AdminID
  • AdminPassword
  • 来自 环境变量
  • 来自 NVRAM 变量存储(nvram_get() 读取的值)
  • 判断是否有输入过滤
  • 是否使用 strstr() 过滤 ; & $( backticks)?
  • 是否使用 escapeshellcmd()、escapeshellarg() 转义(PHP)?
  • 是否直接拼接字符串形成命令?

使用 execve() 直接调用二进制,而不是 system()。

确认命令是否执行 Wireshark 监控 HTTP 请求是否触发 shell 命令 在固件中查找 /bin/sh、/bin/busybox 相关调用

strings binary | grep -E "/bin/sh|/bin/busybox"

流量分析

HTTP→设备管理、Web UI →命令注入、CSRF、API 攻击 Telnet→远程管理 →弱口令爆破、RCE SSH 远程管理→SSH →Key 窃取 FTP/TFTP→文件上传 →恶意固件上传、配置篡改 RTSP→视频流传输 →未授权视频访问

检测Bootloader 通常存储在 NOR Flash 或 NAND Flash 的前几个 KB 位置,可以确认设备的启动顺序、可以决定设备如何引导 Linux 内核、查找固件解密密钥。

strings firmware.bin | grep "bootcmd"
cu -l /dev/ttyUSB0 -s 115200

-s 115200的意思是设定波特率为 115200 bps ,Baud Rate指的是串口通信中每秒传输的信号单元数,在串口通信中的波特率必须匹配,否则会出现乱码或无法连接。

波特率是什么

lot常见波特率:

  • 9600:低速串口通信,常用于 Arduino、微控制器(MCU)
  • 19200、38400:早期嵌入式设备
  • 57600:一些老式调制解调器
  • 115200:常用于 U-Boot、Linux 串口、ESP8266/ESP32 等
  • 230400、460800:高带宽调试接口
  • 921600:更高端的嵌入式系统或高速调试端口

↑不知道具体波特率的话,用 minicom 或 PuTTY 进行逐步测试/stty读取当前波特率/在 binwalk解析固件时搜索波特率

foremost提取出的图片分析思路

foremost 可以从固件或存储介质中恢复不同类型的文件,实战分析的时候从物联网固件中提取的图片其实能起到很大作用。登录界面截图可能会包含默认用户名/密码,扫码绑定设备的二维码,确认固件来源的厂商 Logo。

foremost -i firmware.bin -o extracted_files
ls extracted_files/jpg/

在一些便宜的设备可能会发现

login_background.jpg
default_password.png
admin_panel.jpg

现在几乎所有的家用智能设备会用二维码进行 Wi-Fi 绑定or账号登录

zbarimg extracted_files/png/qrcode.png

包含二维码的话zbarimg 会输出解码后的内容,例如:QR-Code: WIFI:T:WPA;S:MyWiFi;P:SuperSecretPass;;。 如果是设备的二维码绑定信息,可能解码出QR-Code: http://192.168.1.1/admin?token=qwq

表示管理 URL:http://192.168.1.1/admin 访问 Token:qwq

像摄像头or智能门铃有些会在固件中存储默认截图,因为需要设备启动或初始化测试,这些截图可能用于设备启动界面的背景图&设备调试日检查摄像头模组是否工作正常。摄像头在无法连接网络时,会缓存最近的摄像头截图以供调试,这些快照可能存储在 /var/log/ 或 /mnt/data/ 目录(一瞬绕过物理防护,,,),如果摄像头存储了出厂时的 Wi-Fi 连接信息会暴露设备的物理位置,直接到附近嗅探传输的视频数据x