You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何利用缓冲区溢出调用CTF中地址004011e9的print flag函数

缓冲区溢出利用方案(针对给定CTF代码)

核心分析

目标函数FUN_00401350中,char Input1[16]是栈上的16字节缓冲区,最后一次输入调用了不安全的gets()——这个函数不会限制输入长度,完全可以用来覆盖栈帧的返回地址,直接跳转到0x004011e9的print flag函数。

步骤拆解

  1. 计算缓冲区到返回地址的偏移量

    • 以32位程序为例,栈结构为:Input1[16] → 保存的EBP(4字节) → 返回地址(4字节),因此从缓冲区起始到返回地址的偏移是 16(缓冲区大小) + 4(EBP) = 20 字节。
    • 若是64位程序,保存的RBP占8字节,偏移则为16+8=24字节。不确定位数时,用gdb等调试工具确认:在gets()处下断点,查看Input1的地址与当前EBP/RBP的差值,再加EBP/RBP到返回地址的长度即可。
  2. 构造Payload

    • 前两次输入由fgets()读取,后续还有getchar()吃掉换行符,随便输入内容即可(比如第一次输abc回车,第二次输def回车),不影响溢出操作。
    • 第三次输入(gets())的Payload格式:
      [填充缓冲区的字节] + [覆盖EBP/RBP的字节(可随意填充)] + [小端序的print flag函数地址]
      
      32位示例:地址0x004011e9的小端序为\xE9\x11\x40\x00,完整Payload是'a'*20 + '\xE9\x11\x40\x00'。
      64位示例:地址0x004011e9的小端序为\xE9\x11\x40\x00\x00\x00\x00\x00,完整Payload是'a'*24 + '\xE9\x11\x40\x00\x00\x00\x00\x00'。
  3. 处理换行符问题

    • gets()会自动将输入末尾的换行符替换为\0,但只要\0出现在返回地址之后,就不会影响跳转逻辑。输入Payload时直接一次性输入所有字符,最后按回车即可,回车被gets()处理成\0,不会覆盖已写入的返回地址。

常见问题排查

  • 若之前尝试无效,大概率是偏移量计算错误:必须用调试工具确认栈布局,比如在gdb中打印&Input1和$ebp(32位)的差值,才能得到准确的填充字节数。
  • 注意字节序:x86架构为小端序,地址必须倒序写入,比如0x004011e9不能直接写\x00\x40\x11\xe9,必须是\xe9\x11\x40\x00。

内容的提问来源于stack exchange,提问作者Wynn Berry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 11:37:27