也许现在还研究Activex就是挖坟,但是呢,笔者是摸金校尉,挖坟,呸!盗墓是笔者的本职工作。
额,不扯了,本次研究的是阿里旺旺ActiveX控件imageMan.dll栈溢出漏洞,来源于《漏洞战争》一书,书中简单介绍了漏洞情况,没有详述。笔者在研究过程中产生了很多疑问,比如为什么要在DispCallFunc函数处下段?为什么覆盖SEH,能不能使用覆盖返回地址的方式进行漏洞利用?
随着笔者研究的深入,愈发感觉此洞的精妙之处,真是恨不得立即和大家分享。
1. 前言
漏洞软件:阿里旺旺imageMan.dll(见附件)
分析环境:WinXP SP3
参考资料:
《漏洞战争:软件漏洞分析精要》
《0day安全:软件漏洞分析技术》
https://www.cnblogs.com/qguohog/archive/2013/01/22/2871805.html
http://blog.sina.com.cn/s/blog_6a5e54710102x2jt.html
https://wenku.baidu.com/view/59a3229f172ded630b1cb6dc.html
2. ActiveX基础知识
2.1. 什么是ActiveX
2.1.1. 是一种插件简单的说 ActiveX是浏览器插件,它是一些软件组件或对象,可以将其插入到WEB网页或其他应用程序中。一般软件需要用户单独下载然后执行安装,而ActiveX插件是当用户浏览到特定的网页时,IE浏览器即可自动下载并提示用户安装。
正是有了插件,浏览器才能够用于阅读文档、观看电影、欣赏音乐、社交、网络购物等。
浏览器插件总体可以划分为两大阵营,即IE支持的插件以及非IE支持的插件。虽说Activex是微软的亲儿子,但是,现在win10默认安装的Edge浏览器已经不再支持Activex。再过几年还有多少人能记得Activex?
2.1.2. 是一种组件对象模型(COM)核心技术是COM,所以独立于语言开发。
既然使用的是COM技术,那么就会在注册表中注册CLSID:
注册COM命令: regsvr32 ***.dll
2.1.3. 查看已经安装的ActiveX插件
右键IE-Internet属性-程序-管理加载项:
3. ActiveX逆向分析基础
3.1. classid
每个ActiveX组件中可能包含多个class类,每个class类可能包含了多个接口,每个接口可能包含了多个函数。每个class类有一个自己的classid。在调用ActiveX中的某个函数的时候,会事先通过classid来引入class。
注册表 HKEY_CLASSES_ROOT\CLSID中记录的就是classid。每个 classid下面有个typelib,typelib记录的是所属com组件的id。组件id记录在注册表的HKEY_CLASSES_ROOT\TypeLib目录下。
3.2. 分发函数
ActiveX组件中调用函数的机制叫做分发。com组件在调用某个函数时,首先使用被调用函数的函数名来调用GetIDsOfNames函数,返回值是函数编号(DISPID,又名调度ID),再使用该函数编号和函数参数来调用Invoke函数。Invoke函数内部调用DispCallFunc(OLEAUT32!DispCallFunc(HWND ActiveX_instant, dispatchID id))获取函数地址。
分发接口其实就是存在两个数组,一个存放dispid与接口方法名称的对值(pair),一个存放的是dispid与接口方法指针(函数指针)的对值。先通过函数名来找函数编号,然后利用函数编号来调用函数。GetIDsOfNames函数和Invoke(OLEAUT32!DispCallFunc)函数中分别使用了函数名称表和函数地址表。
Idispatch接口如下:
interface IDispatch : IUnknown { virtual HRESULT GetTypeInfoCount(UINT* pctinfo) = 0; //GetTypeInfoCount用于获取自动化组件支持的ITypeInfo接口的数目 virtual HRESULT GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo) = 0; //GetTypeInfo用于获取ITypeInfo接口的指针,通过该指针将能够判断自动化服务程序所提供的自动化支持 virtual HRESULT GetIDsOfNames (REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid) = 0; //GetIDsOfNames读取一个函