Skip to content

Latest commit

 

History

History
490 lines (342 loc) · 15.7 KB

2-分析固件.md

File metadata and controls

490 lines (342 loc) · 15.7 KB

2. 分析固件

2.1 提取文件系统

binwalk

杂项工具,用于扫描隐藏文件,分离文件

安装:

git clone https://github.com/ReFirmLabs/binwalk.git
cd binwalk
sudo python3 setup.py install

使用:

binwalk filenamebinwalk 1.mp4
DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
27657186      0x1A603E2       PGP RSA encrypted session key - keyid: 7DEBB57A 854F782F RSA (Encrypt or Sign) 1024b
27820636      0x1A8825C       MySQL ISAM index file Version 8
28976826      0x1BA26BA       HPACK archive data
40994603      0x271872B       PNG image, 941 x 320, 8-bit/color RGBA, non-interlaced
40994644      0x2718754       Zlib compressed data, default compression
# 两列数字是偏移,可以 dd 手动分离
dd if=1.mp4 of=1.jpg skip=40994603 bs=1
# 这里if是指定输入文件,of是指定输出文件,skip是指定从输入文件开头跳过140147个块后再开始复制,bs设置每次读写块的大小为1字节 

可以使用 binwalk 的 -e 参数来提取固件中的文件

binwalk -e test.bin

如果你还指定了 -M 选项,binwalk 会递归扫描文件

binwalk -Me test.bin

如果指定了 -r 选项,则将自动删除无法提取的任何文件签名或导致大小为 0 的文件

binwalk -Mre firmware.bin

还可以使用 binwalk 进行固件比较,指定 -W 选项 或者 -hexdump 指令

binwalk -W test1 test2 test3

firmware-mod-kit

基于binwalk的解打包工具,但是由于很久没用更新,使用场景有限。

安装方法:

首先安装依赖

sudo apt-get install git build-essential zlib1g-dev liblzma-dev python-magic

安装工具

git clone https://github.com/mirror/firmware-mod-kit.git  
  
cd firmware-mod-kit/src  
  
./configure && make

解包固件 将固件 firmware.bin 解包到 working_directory/ 下

./extract_firmware.sh firmware.bin working_directory/

重新打包固件 将新生成的固件放到 output_directory 下

./build_firmware.sh output_directory/ working_directory/

基于binwalk的解打包工具,但是由于很久没用更新,使用场景有限。

2.2 分析文件系统

2.2.1 手动分析

静态分析文件系统

在固件分析中,常常遇到各种文件系统,如 Squashfs、Cramfs、YAFFS2、UBIFS、EXT4等,常见的 squashfs-root 文件系统通常可以将整个文件系统或者某个单一的目录压缩在一起, 存放在某个设备, 某个分区或者普通的文件中

以思科路由器的这个文件系统为例

cisco file system

常用目录的说明:

目录 目录描述
/bin 这个目录包含了系统启动和基本维护所需的核心命令和可执行文件。这些文件在系统引导过程中就需要使用,因此 /bin 目录通常需要与根文件系统位于同一分区,以确保在挂载其他文件系统之前就可以访问这些命令
/dev /dev 目录包含了与设备和设备接口相关的文件。在Linux中,一切都是文件,包括硬件设备。设备文件通常用于与硬件交互,例如磁盘驱动器、键盘、鼠标等。这些设备文件是Linux系统中特有的文件类型,用于实现对硬件的访问和控制
/etc 包含了系统主要的配置文件,包括网络配置、用户帐户配置、服务配置以及其他系统参数。这些配置文件在系统运行时会被读取,因此只有具有 root 权限的用户才能够修改它们
/lib /lib 目录包含了共享库文件和驱动程序,这些文件用于支持系统启动和运行根文件系统中的可执行程序。共享库是系统中多个程序所共享的动态链接库,它们提供了各种功能和服务,以减小可执行文件的大小并提高效率
/var 通常包含可变的数据,例如日志文件、邮件排队目录、临时文件等。这些数据通常会在系统运行时不断变化,因此被放在 /var 目录下,而不是 /usr 或 /bin 目录下,这些目录通常包含不变的系统文件
/proc /proc 目录是一个虚拟文件系统,它提供了有关正在运行的进程和系统内核的信息。这些信息以文件和目录的形式呈现,可以通过 /proc 文件系统来访问。这是一个动态生成的文件系统,用于监控和管理系统进程

因为思科路由器的 web 服务框架为 nginx 框架,所以我们需要找到启动 nginx 的方法,配置文件一般位于 etc 下面,例如 http 服务启动啥的,但是思科用的是 nginx,所以我们找 nginx 即可

在www/cgi-bin/目录下存在3个cgi程序 blockpage.cgi jsonrpc.cgi upload.cgi

然后可以发现 etc 下有个 init.d,这下面就放的是 nginx 的启动文件

etc directory

然后在/etc/nginx/conf.d/目录下有nginx对应的一些配置文件然后在/etc/nginx/conf.d/目录下有nginx对应的一些配置文件。 例如jsonrpcupload

location /jsonrpc {
    include uwsgi_params;
    proxy_buffering off;
    uwsgi_modifier1 9;
    uwsgi_pass jsonrpc;
    uwsgi_read_timeout 3600;
    uwsgi_send_timeout 3600;
}
location /form-file-upload {
    include uwsgi_params;
    proxy_buffering off;
    uwsgi_modifier1 9;
    uwsgi_pass 127.0.0.1:9003;
    uwsgi_read_timeout 3600;
    uwsgi_send_timeout 3600;
}

location /upload {
    upload_pass /form-file-upload;
    upload_store /tmp/upload;
    upload_store_access user:rw group:rw all:rw;
    upload_set_form_field $upload_field_name.name "$upload_file_name";
    upload_set_form_field $upload_field_name.content_type "$upload_content_type";
    upload_set_form_field $upload_field_name.path "$upload_tmp_path";
    upload_aggregate_form_field "$upload_field_name.md5" "$upload_file_md5";
    upload_aggregate_form_field "$upload_field_name.size" "$upload_file_size";
    upload_pass_form_field "^.*$";
    upload_cleanup 400 404 499 500-505;
    upload_resumable on;
}

对应 upload 和 jsonrpc 配置了对应路由,uwsgi 是用于与其他服务器进行通信的本机二进制通信协议,可以在/etc/uwsgi中找到对应的配置,设置了请求处理的对应端口以及对应程序。

[uwsgi]
plugins = cgi
workers = 1
master = 1
uid = www-data
gid = www-data
socket=127.0.0.1:9003
buffer-size=4096
cgi = /www/cgi-bin/upload.cgi
cgi-allowed-ext = .cgi
cgi-allowed-ext = .pl
cgi-timeout = 300
ignore-sigpipe = true

[uwsgi]
plugins = cgi
workers = 4
master = 1
uid = www-data
gid = www-data
socket=127.0.0.1:9000
buffer-size=4096
cgi = /jsonrpc=/www/cgi-bin/jsonrpc.cgi
cgi-allowed-ext = .cgi
cgi-allowed-ext = .pl
cgi-timeout = 3600
ignore-sigpipe = true

2.2.2 工具分析

借助一些自动化的工具对固件的文件系统进行分析,以识别潜在的安全漏洞、后门或恶意代码。

firmwalker

Firmwalker 是一个用于扫描固件文件系统的简单脚本。它搜索敏感信息,如硬编码的密码、私钥、证书等,并检查潜在的安全问题。它将在提取或安装的固件文件系统中搜索感兴趣的内容,例如:

  • etc/shadow 和 etc/passwd
  • 列出 etc/ssl 目录
  • 搜索 SSL 相关文件,例如 .pem、.crt 等。
  • 搜索配置文件
  • 寻找脚本文件
  • 搜索其他 .bin 文件
  • 查找关键字,例如管理员、密码、远程等。
  • 搜索 IoT 设备上使用的常见 Web 服务器
  • 搜索常见的二进制文件,例如 ssh、tftp、dropbear 等。
  • 搜索 URL、电子邮件地址和 IP 地址
  • 使用 Shodan CLI 调用 Shodan API 的实验性支持

使用方法如下,最后会自动生成一个 firmwalker.txt

./firmwalker.sh 固件路径
./firmwalker {path to root file system} {path for firmwalker.txt}

例如:使用firmwalker分析思科路由器的固件

./firmwalker.sh /home/gxh/unblob/RV34X-v1.0.03.18-2020-06-11-11-55-25-AM.img_extract/64-72350826.gzip_extract/gzip.uncompressed_extract/fw.gz_extract/gzip.uncompressed_extract/openwrt-comcerto2000-hgw-rootfs-ubi_nand.img_extract/squashfs-root

firmwalker script runs

可以看到 firmwalker.txt 中生成了分析的结果

firmwalker output1

可以看到此工具会检索etc/shadow和 etc/passwd

firmwalker output2

检索Unix-MD5 hashes

firmwalker output3

然后就是枚举etc/ssl目录下内容

firmwalker output4

还会搜索 SSL相关文件,例如.pem、.crt 等。

firmwalker output5

根据 data 目录中 sslfiles 文件记录的*.crt*.pem*.cer*.p7b*.p12*.key进行关键字检索

firmwalker output6

搜索 SSH相关文件 搜索配置文件:例如data目录中files文件记录的*.conf、.cfg、.ini

firmwalker output7

搜索常见的二进制应用,例如 ssh、tftp、dropbear等

firmwalker output8

fwanalyzer

FwAnalyzer旨在提供一种快速分析文件系统镜像的工具。FwAnalyzer有一个专门的配置文件,该文件定义了文件和目录的各种规则,并针对给定的文件系统镜像运行已配置的检查。FwAnalyzer的输出是一个报告,其中包含违反配置中指定的任何规则的文件列表。该报告还包含有关文件系统镜像的元信息,以及从分析的文件系统中提取的信息(如果已配置)。报告使用JSON格式,因此可以轻松的将其集成到大型的分析步骤当中

fwanalyzer 的命令行选项 cfg:string,配置文件的路径 cfgpath:string,配置文件的路径和包含的文件(可以重复) in:string,文件系统镜像文件或目录路径 out:string,使用'-'将报告输出到文件或标准输出 tree:string,覆盖目录以从中读取filetree文件 ee:如果存在违规,则error退出 invertMatch:反转(invert )正则表达式匹配(用于测试)

官方给的实例

fwanalyzer -cfg system_fwa.toml -in system.img -out system_check_output.json

运行测试样例

cd go/src/github.com/cruise-automation/fwanalyzer
make testsetup
make test

执行

PATH="/go/src/github.com/cruise-automation/fwanalyzer/scripts:/go/src/github.com/cruise-automation/fwanalyzer/test:/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" go test -count=3 -cover ./...

go test -count=3 -cover ./... 命令会运行当前目录及其所有子目录中的所有测试案例,每个测试案例将运行 3 次,并且将生成代码覆盖率报告,显示哪些代码已经被测试覆盖。

code coverage

ok  	github.com/cruise-automation/fwanalyzer/cmd/fwanalyzer	0.018s	coverage: 23.2% of statements
ok  	github.com/cruise-automation/fwanalyzer/pkg/analyzer	0.021s	coverage: 20.0% of statements
ok  	github.com/cruise-automation/fwanalyzer/pkg/analyzer/dataextract	0.076s	coverage: 71.6% of statements
ok  	github.com/cruise-automation/fwanalyzer/pkg/analyzer/dircontent	0.018s	coverage: 83.9% of statements
ok  	github.com/cruise-automation/fwanalyzer/pkg/analyzer/filecmp	0.061s	coverage: 73.5% of statements
ok  	github.com/cruise-automation/fwanalyzer/pkg/analyzer/filecontent	0.032s	coverage: 69.3% of statements
ok  	github.com/cruise-automation/fwanalyzer/pkg/analyzer/filepathowner	0.019s	coverage: 45.8% of statements
ok  	github.com/cruise-automation/fwanalyzer/pkg/analyzer/filestatcheck	0.018s	coverage: 68.3% of statements
ok  	github.com/cruise-automation/fwanalyzer/pkg/analyzer/filetree	0.017s	coverage: 82.2% of statements
ok  	github.com/cruise-automation/fwanalyzer/pkg/analyzer/globalfilechecks	0.013s	coverage: 91.5% of statements
....

跑完测试样例会生成如下 json 文件:

root@32fd7b042660:/go/src/github.com/cruise-automation/fwanalyzer/test# cat oldtree.json 
{
    "files": [
        {
            "name": "/world", 
            "gid": 0, 
            "mode": 33206, 
            "se_linux_label": "-", 
            "uid": 0, 
            "link_target": "", 
            "digest": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 
            "size": 0
        }, 
        {
            "name": "/bin/elf_arm64", 
            "gid": 1001, 
            "mode": 33277, 
            "se_linux_label": "-", 
            "uid": 1001, 
            "link_target": "", 
            "digest": "5e18d8042a38789761dc950cd3aa73b3562d69a4dce2a5ef8530301e71494168", 
            "size": 2110768
        }, 
        {
            "name": "/dir1", 
            "gid": 0, 
            "mode": 16877, 
            "se_linux_label": "-", 
            "uid": 0, 
            "link_target": "", 
            "digest": "0", 
            "size": 1024
        }, 
        {
            "name": "/dir1/dir11", 
            "gid": 0, 
            "mode": 16877, 
            "se_linux_label": "-", 
            "uid": 0, 
            "link_target": "", 
            "digest": "0", 
            "size": 1024
        }
      ....
      .......
    ], 
    "image_name": "test/test.img", 
    "image_digest": "9d5fd9acc98421b46976f283175cc438cf549bb0607a1bca6e881d3e7f323794"
}

该报告还包含有关文件系统映像的元信息,以及从分析的文件系统内的文件中提取的信息(如果配置)。该报告使用 JSON 进行格式化,因此可以轻松地将其集成为更大分析中的一个步骤。

2.2.3 动态分析

设备在正常运行或者在仿真环境中运行中的动态测试

FirmAE

Clone FirmAE

git clone --recursive https://github.com/pr0v3rbs/FirmAE

运行download.sh

./download.sh

运行 install.sh

./install.sh

firmae 的使用 首先执行初始化脚本

./init.sh

检查仿真条件 -c 参数

sudo ./run.sh -c <brand> <firmware>

firmware 填写固件名称 brand 是开发板名称,可以随便填,不影响正常使用

完成run.sh -c后,可debug固件,这样后面进行 debug 时,等待的时间会大大减少

-a 使用分析模式

sudo ./run.sh -a <brand> <firmware>

运行模式,有利于进行网络测试

sudo ./run.sh -r <brand> <firmware>

user-mode 调试固件

sudo ./run.sh -d <brand> <firmware>

system-mode 调试固件

sudo ./run.sh -b <brand> <firmware>

使用 FirmAE 对思科路由器设备漏洞进行仿真

第一步,首先检查仿真条件 使用 -c 参数

sudo ./run.sh -c cisco /home/gxh/iot/Cisco_CVE-2019-1663/RV130X_FW_1.0.3.44.bin

check startup conditions3

可以看到检查仿真条件成功了

完成run.sh -c后,可以 debug 固件,先进行 -c 后面就会快一些,不进行 -c 也可以

然后进行 -r,运行模式,有利于进行网络测试

sudo ./run.sh -r cisco /home/gxh/iot/Cisco_CVE-2019-1663/RV130X_FW_1.0.3.44.bin

running mode

可以看到 -r 运行成功了,然后我们去访问一下看看,可以看到完全访问成功

login interface

用户名和密码都是弱密码 cisco,我们尝试登录,然后修改密码之后,可以访问正常服务

http server