avatar

Catalog
QNAP固件解压及动态调试辅助脚本

固件解压

由于QNAP固件经过了加密,但是QNAP的密钥以及都一致为“QNAPNASVERSION4”,因此可利用公开工具qnap-utils对其固件进行解压,但在使用自动化工具之前,需要先编译好解密程序PC1放在相应目录下。按道理是可以先解密,再使用binwalk等工具进行解压,但我没有成功,我使用qnap-utils + PC1完成解压。

  1. Decrypt 镜像文件工具:
    • 解密 pc1.c
      • decrypt工具
      • 编译 gcc pc1.c -o PC1
      • 使用: PC1 d QNAPNASVERSION4 TS-401T_20081128-1.3.0.img decoced_firmware.tar.gz
    • 加密 pc1.c
      • encrypt工具
      • 编译: gcc pc2.c -o PC2
      • 使用:
        • PC1 e QNAPNASVERSION4 unencrypted.img encrypted.img
        • PC2 TS-401T1.3.0.img
      • PC2 retrieve the version number from the image name, so you must keep it the same as the original
  2. 使用自动化解压工具qnap-utils
  • git clone https://github.com/mb2020/qnap-utils.git
  • 将编译好的PC1放在/sbin/目录下
  • ./extract_qnap_fw.sh firmware.img destdir
  • 结果:
    * destdir/fw              files extracted from the firmware.img
    * destdir/sysroot         unpacked initrd/initramfs, rootfs2, rootfs_ext
    * destdir/qpkg            unpacked qpkg.tar

漏洞挖掘

辅助脚本

  1. search_lib.sh
    descripition: 用于寻找utilRequest.cgi中的某个导入函数的实现的动态库

    使用方法:bash search_lib.sh Function_Name  
    Eg:  
    • bash search_lib.sh CGI_Get_Input

    • 输出: /root/disk1/QNAPTS431P2/firm/sysroot/usr/lib/libuLinux_cgi.so.0

bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#! /bin/bash
funName=$1
cgiName='utilRequest.cgi'
cgiPath='/root/disk1/QNAPTS431P2/firm/sysroot/home/httpd/cgi-bin/filemanager'
libPath_array=('/root/disk1/QNAPTS431P2/firm/sysroot/lib' '/root/disk1/QNAPTS431P2/firm/sysroot/usr/lib' '/root/disk1/QNAPTS431P2/firm/sysroot/usr/local/lib')


sos=$(readelf -d $cgiPath"/"$cgiName | grep Shared | awk '{print $5}' | sed -r "s/\[(.*)\]/\1/g")

for libFile in $sos
do
tmpFile=0
for libPath in ${libPath_array[@]}
do
totalibFile=$libPath"/"$libFile
if [ -e $totalibFile ]
then
tmpFile=$totalibFile
fi
done
if [ ${#tmpFile} -eq 0 ]
then
echo $libFile' not found'
else
result=$(readelf -sWD $tmpFile | grep $funName)
if [ ${#result} -ne 0 ]
then
tmp=$(echo $result | awk '{print $3}' | grep -v 00000000) # $3, addrexists, suggest the func is here
if [ ${#tmp} -ne 0 ]
then
#echo $result
echo $tmpFile
fi
fi
fi
done
  1. calc_lib_addr
    Descripition: 程序运行时,通过程序名以及lib库中的偏移地址计算lib中绝对地址。
    Func: bash calc_lib_addr.sh lib_name offset_addr  
    Eg:
> bash calc_lib_addr.sh libuLinux_cgi.so.0.0 0x000037D2  
> **输出:**   
> libuLinux_cgi.so.0.0\'s base is 76e0b000    
> 0x76e0e7d2    
  1. 动态调试脚本:
bash
1
2
3
4
5
6
7
8
#!/bin/bash
export PATH_INFO="/cgi-bin/cgi.cgi"
export HTTP_HOST="127.0.0.1:8080"
export REQUEST_METHOD='GET'
export QUERY_STRING="$1"
export REMOTE_ADDR="192.168.1.1"
export REQUEST_URI="/cgi-bin/cgi.cgi"
LD_LIBRARY_PATH=./usr/local/lib ./gdbserver-7.7.1 0.0.0.0:1222 ./home/httpd/cgi-bin/cgi.cgi

运行脚本如下:

bash
1
sh cgi_script/authLogin_get.sh "c=wget 192.168.1.108;&a=hh&p=hh&pp=hh&u=hhh&u=hhh&p=hhh&o=1233"

Comment