kill.exe溢出漏洞分析与EXP讨论

1. 前言
前几日,笔者在exploit-db上发现了一个kill.exe的溢出漏洞,在众多的UAF漏洞中,这种单纯的溢出漏洞简直如一股清泉一般,遂将其捡了出来,深入地看了看 。
原计划写一个完整的可用EXP,但貌似失败了 。所以,这里以半介绍半讨论的形式聊一聊这个EXP的问题 。对于在这方面比较有经验有见解的读者,笔者诚恳的请求不吝赐教;而对于这方面不太了解的读者,希望这篇可以把一些基本信息介绍给大家 。
2. 漏洞分析
Kill.exe是微软发行的Windows调试工具包的一个小工具,用于终止一个或多个进程,以及它们的所有线程 。在exploit-db中提到的包含漏洞的kill.exe的版本号为:6.3.9600.17298 。在安装Windows Driver Kit (WDK)8.1时,会自动安装该版本的kill.exe工具 。
此外,在6.1.7650.0版本的kill.exe工具中,同样存在类似的问题 。该版本的kill.exe工具可以通过安装WDK 7.1获取 。
下面首先分析一下6.3.9600.17298版本的kill.exe的漏洞函数 。Kill.exe在处理命令行参数时触发了栈溢出漏洞,可以向栈内写数据:

kill.exe溢出漏洞分析与EXP讨论

文章插图
该漏洞函数的内部逻辑也较为简单,当只接受到一个参数时,可以概述为:
kill.exe溢出漏洞分析与EXP讨论

文章插图
当有多个参数时,用一个循环把上述内容进去,即针对每个参数判断是否为数字然后进行相应操作并保存结果 。需要注意的是,原函数的内容要比这种表述复杂的多,该图只是示意图,用于帮助读者理解该函数的所做工作 。
下面仔细说明漏洞函数的两个分支:左侧分支代表接收到了一串数字字符串为参数,则计算该字符串所代表的数值 。其中,v1为字符串起始地址,v7为最终的计算结果 。48为’0’的ascII码值,*10表示乘以权重 。右侧分支表示接收到了一串字符串,则将字符串内容复制到栈上 。其中,v1为字符串起始地址,v5为指向某栈空间的指针 。
如果仔细研究的话,可以发现在左侧分支中同样存在一个漏洞:v7存在整数溢出漏洞,汇编代码如下:
kill.exe溢出漏洞分析与EXP讨论

文章插图
上部分用于判断字符串的下一位是否为数字,下部分用于计算其数值 。显然,EAX存在整数溢出的问题 。但是,这漏洞并没有什么用 。恭喜你,获得“认真的代码阅读者”成就 。
下面着重看右侧分支也存在一个漏洞,即栈溢出漏洞 。其执行复制操作的汇编指令如下:
kill.exe溢出漏洞分析与EXP讨论

文章插图
图中的3次判断的含义为:该字符是否为空格,是否为制表符,是否为空,如果是则终止复制;否则继续复制下一个字符 。
当笔者以长串的’A’作为其参数启动kill.exe之后,可以观察到栈被覆盖的情况:
kill.exe溢出漏洞分析与EXP讨论

文章插图
3. EXP讨论
与Win XP相比,Win 7环境更加复杂多变,所以本节将EXP相关的讨论放在Win XP环境下 。首先,将kill.exe程序复制到Win XP的虚拟机中,然后考虑漏洞的利用方法 。
粗略的归纳一下,常见的栈溢出漏洞的利用方式有3种:
1. 覆盖函数返回地址 。
2. 覆盖SEH结构 。
3. 覆盖其他有用数据或关键数据,如对象以及虚表指针等 。
下面开始分开讨论kill.exe的情况,并试图找出可行的可用方式 。
3.1 覆盖返回地址
在WinXP环境下,覆盖返回地址当然是一种简单可靠地利用,但是这里存在一个问题:kill.exe是有stack cookie保护的,即有/GS标记:
kill.exe溢出漏洞分析与EXP讨论

文章插图
自然而然地想到,有没有办法过掉这个stack cookie 。首先,可以肯定的是,这个cookie并非是静态的值 。进一步的,有些文献表示可以计算或猜测这个cookie的大致取值范围,以减少/GS的保护能力,但在这里不打算选用这类方法 。最后,由于kill.exe中的栈溢出漏洞只能覆盖部分栈中的内容,无法覆盖到位于.data段中的数据,所以修改cookie值也是不可行的 。
无奈之下,只能选用覆盖SEH结构的利用方法,当然这也是一种有效绕过/GS保护的EXP方法 。
3.2 覆盖SEH结构
覆盖SEH结构同样是一种颇为有效的利用手法 。但是这里同样存在着一个问题:kill.exe是有Safeseh保护的,即有/Safeseh标记:
kill.exe溢出漏洞分析与EXP讨论