win pwn初探(一)
首发于:先知社区
一直都感觉win pwn很难所以就没接触过,但是看了一些CVE之后还有ZDI最近公布的一些CVE,发现win/软件上的漏洞占比要比linux上的占比多很多,所以打算从最基础的开始学习。笔者在这win pwn方面纯属小白,如有错误欢迎指正
win pwn初探(一)
环境搭建
首先笔者给出自己的本机环境和虚拟机环境
本机环境:m1 pro
虚拟机环境:PD 17,Windows 11 专业版-21H2
虽然是arm windows但是可以运行x32和x64的程序
安装checksec
这里笔者摸索了挺长时间的,winchecksec笔者因为各种各样的环境问题导致没有安装成功,但是笔者找到了一个在win上可以直接checksec的github项目,只需要去它的releases下载checksec.exe即可。
安装winpwn
这个就和linux下的pwntools类似,使用地址,安装的话直接执行以下命令即可
- pip3 install winpwn
- pip3 install pefile
- pip3 install keystone-engine
- pip3 install install capstone
安装完成之后就可以from winpwn import *
了
安装windbg
其实可以直接用ollydbg、x32dbg、x64dbg,但是笔者看见很多win上CVE复现都用的是windbg,所以笔者也去装了一个
直接去windows的store商店搜索windbg,直接点击安装即可
笔者学到目前为止只用到了上面的这三个工具,后续用到其他的话就继续添加吧
winpwn保护机制
win上的保护要比linux上的保护多上很多,这里笔者写了一个测试程序然后使用vs2022 preview默认编译成x64的exe
1 |
|
.\checksec.exe 目标程序
就可以看见目标程序的保护机制
NX:这个在win上其实是DEP,堆栈不可执行保护
Canary:这个在win上其实是GS,可能这个工具的开发者为了让我们更好理解才写了Canary,但是需要注意的是这个工具的canary检测可能检测不准
ASLR:通俗讲就是地址随机化,让exe和dll的地址全部随机,所以就有了大名鼎鼎Heap Spray(堆喷)利用技术,Heap Spray是在shellcode的前面加上大量的slide code(滑板指令),组成一个注入代码段。然后向系统申请大量内存,并且反复用注入代码段来填充。这样就使得进程的地址空间被大量的注入代码所占据。然后结合其他的漏洞攻击技术控制程序流,使得程序执行到堆上,最终将导致shellcode的执行。
Dynamic Base:程序编译时可通过/DYNAMICBASE编译选项指示程序是否利用ASLR的功能
High Entropy VA:如果指定此选项,则当内核将进程的地址空间布局随机化为 ASLR 的一部分时,兼容版本的 Windows 内核可以使用更高的熵。 如果内核使用更高的熵,则可以将更多的地址分配给堆栈和堆等内存区域。 因此,更难猜测特定内存区域的位置。当该选项打开时,当这些模块作为 64 位进程运行时,目标可执行文件和它所依赖的任何模块必须能够处理大于 4 GB 的指针值。
SEH:结构化异常处理(Structured Exception Handling,简称 SEH)是一种Windows 操作系统对错误或异常提供的处理技术。SEH 是 Windows操作系统的一种系统机制,本身与具体的程序设计语言无关。SEH 为Windows的设计者提供了程序错误或异常的处理途径,使得系统更加健壮
SafeSEH:为了防止攻击者通过覆盖堆栈上的异常处理函数句柄,从而控制程序执行流程的攻击,在调用异常处理函数之前,对要调用的异常处理函数进行一系列的有效性校验,如果发现异常处理函数不可靠,立即终止异常处理函数的调用。不过SafeSEH需要编译器和系统双重支持,缺少一个则保护能力基本就丧失了
Force Integrity:强制签名保护
Control Flow Guard:控制Flow防护 (CFG) 是一项高度优化的平台安全功能,旨在打击内存损坏漏洞。 通过严格限制应用程序可以从何处执行代码,利用漏洞(如缓冲区溢出)执行任意代码会更加困难
Isolation:隔离保护,默认会开启
Authenticode:签名保护
以上是checksec的每个保护机制的简要解释,看到这里可能还会迷迷糊糊的,后续的win pwn文章利用会有绕过这些保护,到时候会详细的解释,包括什么是TIB,TEB等
初探栈溢出
这里用比较经典的root-me PE32 - Stack buffer overflow basic
win pwn题来上手熟悉一下
题目地址,题目也给出了源码
1 |
|
checksec
将程序利用scp下载到本地,然后checksec看一下保护机制
上面显示开了Canary,但是在ida分析的时候是没有开canary的
1 | int __cdecl main(int argc, const char **argv, const char **envp) |
笔者修了一下之后ida分析结果最后如上
这个程序意思就是输入buf,然后把buf的小写字母转换成大写字母最后输出出来,但是gets的话会导致栈溢出漏洞
现在我们以linux平台下的攻击思路来的话就是一个ret2text,后门地址是0x401000
1 | .text:00401000 ;org 401000h |
ida分析之后发现偏移为0x14,所以payload = b'a' * (0x14 + 4) + p32(0x401000)
发送过去之后成功的劫持了程序流到后门地址上,成功获取一个shell
最终exp
1 | from winpwn import * |
总结
这篇初探文章只是简单的了解了windows下的保护机制,和winpwn的一个用法,后续会学习如何调试,如何绕过这些保护,包括如何用pwntools来写exp