pwntools调试命令集合

之前做分析pwn题时,命令经常记不住,今天有时间了总结下调试pwn时一直常用的命令。

0x1 编译

文章中用到的test都是文件名

1
2
gcc test.c -0 test
gcc -fno-stack-protector -z execstack -o test test.c

使用这条命令编译程序,-fno-stack-protector-z execstack这两个参数会分别关掉DEP和Stack Protestor。

0x2 gdb调试技巧

  1. n:执行一条源代码但不进入函数内部
  2. ni:执行一条汇编代码但不进入函数内部
  3. s:执行一条源代码且进入函数内部
  4. si:执行一条汇编代码且进入函数内部
  5. c:继续执行到下一个断点
  6. 下断点:b 函数名 或是 b *addr
  7. 查看寄存器的值:info register
  8. 查看内存:x/数字 wx 以十六进制,4字节显示指定内存
    x/数字 gx 以十六进制,4字节显示指定内存
    

0x3 调试命令

1
checksec //查看程序开启的保护机制

常见的保护措施有以下几种:

  1. CANARY:栈溢出检查,用Canary金丝雀值是否变化来检测,Canary found表示开启。金丝雀最早指的是矿工曾利用金丝雀来确认是否有气体泄漏,如果金丝雀因为气体泄漏而中毒死亡,可以给矿工预警。这里是一种缓冲区溢出攻击缓解手段:启用栈保护后,函数开始执行的时候会先往栈里插入cookie信息,当函数真正返回的时候会验证cookie信息是否合法,如果不合法就停止程序运行。攻击者在覆盖返回地址的时候往往也会将cookie信息给覆盖掉,导致栈保护检查失败而阻止shellcode的执行。在Linux将cookie信息称为Canary。

  2. FORTIFY:FORTIFY_SOURCE机制对格式化字符串有两个限制:(1)包含%n的格式化字符串不能位于程序内存中的可写地址 (2)当使用位置参数时,必须使用范围内的所有参数。

  3. NX:NX enabled如果这个保护开启就是意味着栈中数据没有执行权限,以前的经常用的call esp或者jmp esp的方法就不能使用,但是可以利用rop这种方法绕过。

  4. PIE:PIE enabled如果程序开启这个地址随机化选项就意味着程序每次运行的时候地址都会变化,而如果没有开PIE的话那么No PIE (0x400000),括号内的数据就是程序的基地址。

  5. RELRO:RELRO会有Partial RELRO和FULL RELRO,如果开启FULL RELRO,意味着我们无法修改got表。

1
2
cat /proc/sys/kernel/randomize_va_space //查看地址随机化保护是否开启
ldd test

可以通过这两种方法来查看是否开启了地址随机化保护。控制ASLR有3中状态:
0:表示关闭ASLR

1: mmap base、stack、vdso page将随机化。这意味着.so文件将被加载到随机地址。链接时指定了-pie选项的可执行程序,其代码段加载地址将被随机化。配置内核时如果指定了CONFIG_COMPAT_BRK,randomize_va_space缺省为1。此时heap没有随机化。

2:在1的基础上增加了heap随机化。配置内核时如果禁用CONFIG_COMPAT_BRK,randomize_va_space缺省为2。

关闭ASLR,切换至Root用户,输入命令

1
echo 0 > /proc/sys/kernel/randomize_va_space

开启ASLR,切换至Root用户,输入命令

1
echo 2 > /proc/sys/kernel/randomize_va_space

0x4 端口映射

目标程序作为一个服务绑定到服务器的某个端口上,可以使用socat这个工具来完成,命令如下:

1
socat TCP4-LISTEN:5555,fork EXEC:./test

这个程序的IO就被重定向到5555这个端口上,并且可以使用nc 127.0.0.1 5555来访问目标程序服务。

0x5 文件分析

查看程序是多少位,可以使用file这条命令

1
2
@ubuntu:~/Desktop$ file test
test: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=76b50d733400542b34d5e8fa23f0f12dc951d4ef, stripped

查看系统调用

1
strace ./test

查看操作系统libc的版本

1
dpkg -l | grep libc

查看pid,但是需要注意的是,先让程序运行再执行命令,否则pid一直在变化

1
ps -aef | grep file

查看程序在栈上的权限

1
cat /proc/[pid]/maps | grep stack

获取plt函数和函数对应的got表

1
2
objdump -d -j .plt test //plt表
objdump -R test //got表

.bss段是用来保存全局变量的值,地址固定,并且可以读可写,可以通过如下的命令获取.bss段的地址。

1
2
3
4
5
6
7
8
9
10
11
12
13
$ readelf -S test
....
[23] .got PROGBITS 08049ffc 000ffc 000004 04 WA 0 0 4
[24] .got.plt PROGBITS 0804a000 001000 000018 04 WA 0 0 4
[25] .data PROGBITS 0804a018 001018 000008 00 WA 0 0 4
[26] .bss NOBITS 0804a020 001020 000004 00 WA 0 0 1
[27] .comment PROGBITS 00000000 001020 000034 01 MS 0 0 1
[28] .shstrtab STRTAB 00000000 001054 0000fa 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
....