测试固件栈溢出漏洞时,需要使用gdb来进行调试。因此记录下gdb如何使用

注意:只成功了QEMU系统模式+GDB本地调试,其他几个方法欢迎各位师傅给予指导,万分感谢!

环境配置

安装gdb-multiarch支持不同架构的程序调试

1
sudo apt install gdb-multiarch

QEMU用户模式+GDB Remote

最好用且方便的调试方法

使用qemu调试执行挂起

1
sudo chroot ./ ./qemu-aarch-static -g ./usr/sbin/shttpd

gdb连接调试

1
2
3
4
5
gdb-multiarch -q ./usr/sbin/shttpd
pwndbg> set architecture aarch64
The target architecture is set to "aarch64".
pwndbg> target remote 127.0.0.1:1234
Remote debugging using 127.0.0.1:1234

QEMU用户模式+GDB Attach

使用qemu用户模式启动目标程序,并使用gdb attach对应程序的pid即可

1
2
3
4
5
6
7
# 开启目标程序
sudo chroot . ./qemu-aarch64-static ./usr/sbin/shttpd
# 查找对应的程序pid
sudo netstat -antp | grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 7268/./qemu-aarch64
# gdb attach 对应程序pid
gdb-multiarch attach 7268

注意此种方法shttpd程序加载基址,使用vmmap查看发现是attach到了qemu-aarch64-static程序上,感觉没什么用。。。(因为没办法下断点)

QEMU GDB本地调试

下载gdb源码

下载gdb源码并且以aarch64架构编译。然后上传到虚拟机上调试

gdb源码下载链接

下载好后解压,这里我选择gdb7.11,交叉编译选择g++-9-aarch64-linux-gnu,注意版本,不同版本可能编译失败

1
tar -xf gdb-7.11.tar.xz

安装交叉编译工具

查找aarch64相关工具,发现有很多版本的交叉编译工具

1
sudo apt-cache search aarch64

gcc与g++的区别

选择g++工具安装

1
sudo apt-get install g++-9-aarch64-linux-gnu

安装好后查看g++版本:

1
aarch64-linux-gnu-g++-9 -v

进入gdb-7.11目录,配置编译选项

1
2
3
mkdir build
cd build
../configure --host=aarch64-linux-gnu

配置无误后,编译即可

1
make -j8

编译问题解决

尝试了好几个gdb版本编译,结果都报这两个错误,因此对源码进行修改。

  1. error: unknown type name ‘gdb_fpregset_t’

    ./gdb/gdb_proc_service.h添加#include "gregset.h"头文件

  2. error: conflicting types for ‘ps_get_thread_area’;

把重定义的文件打开,把重定义的部分注释掉就可以了。

修改./gdb/aarch64-linux-nat.c./gdb/gdb_proc_service.h./gdb/nat/aarch64-linux.h

  1. error: ‘elf_fpregset_t’ {aka ‘struct user_fpregs_struct’} has no member named ‘vregs’

    参考链接

    是交叉编译是CC被configure默认配置为了g++,是x86_64架构的,因此使用以下命令修改:

    1
    2
    3
    4
    CC=aarch64-linux-gnu-gcc-9 \
    CXX=aarch64-linux-gnu-g++-9 \
    ../configure \
    --host='aarch64-linux-gnu'
  2. error: expected identifier before numeric constant # define TRAP_HWBKPT 4

    参考链接

    按照链接内容修改即可

上传gdb到QEMU虚拟机

编译成功后将gdb通过scp工具上传到QEMU虚拟机上

1
scp ./gdb/gdb root@192.168.1.2:/root/ 

成功执行,接下来只需要在虚拟机里调试即可

当然,如果你是在虚拟机中使用chroot . /bin/sh模拟固件,那么你需要将gdb复制到对应根目录下,同时注意将gdb依赖的库文件也复制过去

1
2
3
4
5
6
7
8
9
ldd ./gdb
linux-vdso.so.1 (0x0000ffff8fab7000)
libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000ffff8f350000)
libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000ffff8f1a0000)
/lib/ld-linux-aarch64.so.1 (0x0000ffff8fa7a000)
cp /lib/ld-linux-aarch64.so.1 ./lib/
mkdir ./lib/aarch64-linux-gnu
cp /lib/aarch64-linux-gnu/libm.so.6 /lib/aarch64-linux-gnu/libm.so.6
cp /lib/aarch64-linux-gnu/libc.so.6 /lib/aarch64-linux-gnu/libc.so.6

QEMU gdbserver

一般情况下qemu都会内置gdbserver模块,基于此可以实现对qemu虚拟机的远程调试。

在qemu启动时添加-S -s参数,-S参数表示qemu不要启动程序,处于阻塞状态,等待gdb指令。-s参数表示启动gdb-server监听在TCP端口1234上。

(待完善)