跳至主要内容

CVE-2010-3333 Microsoft RTF栈溢出漏洞

https://ift.tt/2QHInV6

分析环境

  • 测试系统
    • windows xp 2003
  • 动态调试器
    • windbg 6.1
  • 测试用例生成主机
    • kali 2018.1
  • 分析软件
    • office 2003 sp3

MSF生成样本

查找漏洞利用程序

选择

目标机器和生成的rtf文件的名称

生成

分析样本

打开word,windbg附加到word上,然后通过word打开rtf文件

报错信息如上,在进行movs指令的时候发生了崩溃,并且崩溃单在mso.dll中

查看一下edi 的状态

发现edi是一个只读的内存区域

去看了以下汇编代码发现,rep movs就相当于memcpy,而memcpy的次数是由ecx决定的,之类没有控制ecx的大小,因此复制过多,到了0x130000这个只读内存区域30ed442c。上面是猜测ecx的来源,还不能确定,现在要去找调用函数。
通过kb命令查看,发现此时栈用已经变得乱套了,记住这个地址,我们重新打开word,下断点,然后查看栈中的调用情况,回溯调用的函数。

通过windbg的call stacks,发现调用函数是0x30f0b5c2.
也可以使用ub 命令来查看调用关系,+0x16b0是出现问题的函数,+0x2581是调用者堆栈的返回地址,可以网上回溯.
找到调用函数之后,重启windbg,在这个调用函数下断点.

单步按p或者f10跟踪,发现在0x30f0b5f8发生了崩溃.

可以发现,这里调用的是[eax+1ch],是函数0x30ed4406,按t或者f8跟进.
通过返汇编窗口就发现了造成崩溃的点.

通过跟踪分析发现ecx的复制.

这个漏洞是office在Open Xml文件格式转换器在处理RTF中的'pFragments'属性的时候发生了异常,存在栈溢出。
通过分析下图:

可以得知add ecx,0xffff其实就是清理前4位保留后四位,那么原本的ecx=0004c8ac中,有用的值也就是c8ac,转成正常序就是acc8 ,使用010editor 打开被问题文档

发现异常数据有两处,这里我们也不知道到底是哪了,而且都是pFrqments的段,这里重新改一下数据试试

最后证明就是这里是控制ecx大小的值

movs 时候的esi指向的就是后面的shellcode


edi是0x123dc0,ebp是0x123dd0,ret address 也就是0x123dd4.
也就是说要覆盖到返回地址需要 0x123dd4-0x123dc0 =0x14个字节.
通过这条信息我们可以编写shellcode了,shellcode的编写略过,因为实验环境是xp,这里的shellcode编写要简单很多

The post CVE-2010-3333 Microsoft RTF栈溢出漏洞 appeared first on cole.

https://ift.tt/2xxKEcW Assembly, reverse engineering, vul, cve-2010-3333, office, 漏洞分析 September 19, 2018 at 01:26PM

评论

此博客中的热门博文

反Hook 之自己实现GetProcAddress和LoadLibraryA(c++ version)

http://ift.tt/2AocAD0 // 课上练习.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <windows.h> //要实现的功能: /* 自己实现GerProcAddress LoadLibraryA */ //思路: /* GerProcAddress和LoadLibraryA都是在Kernel32.dll中的 首要的任务就是找到Kernel32.dll,然后遍历IAT就能找到这两个函数 现在首要的难点就是如何找到kernel32.dll() 通过dll的加载顺序可以找到,而且虽然需要使用未文档化的API,但是好在windgb可以直接看,而且用到的也并不是很多 懒得去晚上搜了,直接自己实现一个得了,作为演示,能用就行(最好还是搜一个正规的结构体) */ /* 0: kd> dt _TEB /a nt!_TEB +0x000 NtTib : _NT_TIB +0x01c EnvironmentPointer : Ptr32 Void +0x020 ClientId : _CLIENT_ID +0x028 ActiveRpcHandle : Ptr32 Void +0x02c ThreadLocalStoragePointer : Ptr32 Void +0x030 ProcessEnvironmentBlock : Ptr32 _PEB //首先实现部分TEB结构体,因为只需要用的PEB的部分,所以实现到这就ok了 */ //构建 TEB typedef struct _TEB { //保证0x30是peb的结构体就ok了 struct _tem { DWORD a1; DWORD a2; DWORD a3; DWORD a4; DWORD a5; DWORD a6; DWORD a7; DWORD a8; DWORD a9; DWORD a10; ...

IDA动态调试ELF中遇到的问题(1)

https://ift.tt/2Gxnf2F 遇到 got SIGCHLD singal(child status has changed)...这种提示 singal fork了子进程 直接点yes,然后继续单步执行,出来提示 pass to application就行了 内存查看 用od习惯了之后,凡事都想右键看一下内存,但是IDA中好像没有那么如意, 目前只是在栈中右键发现有查看hex的选项 动态调试的时候的nop ida保存动态调试的时候修改的数据 方法一:在程序运行的时候保存 The post IDA动态调试ELF中遇到的问题(1) appeared first on cole . https://ift.tt/2q9Qf5g WHATEVER April 05, 2018 at 09:44AM

手工加壳Demo- C++Version

http://ift.tt/2AAEutK // 手动加壳demo.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <windows.h> #include <string.h> typedef struct _StubConf { IMAGE_NT_HEADERS ntheader; }STUBCONF; class PeFile { public: PeFile(); ~PeFile(); bool OpenFile(const char*FilePath); bool InitHdrs(); PIMAGE_SECTION_HEADER addSection(const char * secName, DWORD dwSecSzie); PIMAGE_SECTION_HEADER getSection(const char* secName); DWORD Size2ALi(DWORD dwSize, DWORD dwALi); void peclose(); void setOpe(DWORD newOep); LPVOID peGetProcAddress(const char* szFnName); DWORD RVATOOFFSET(DWORD rva); ULONG_PTR getfileBuff(); PIMAGE_NT_HEADERS getNtHeader(); PIMAGE_OPTIONAL_HEADER getOptionHeader(); void fixStubReloc(DWORD oldImageBase, DWORD newImageBase, DWORD oldSectionRva, DWORD newSectionRva); void setSecData(IMAGE_SECTION_HEADER* pScn, void* pSectionData, DWORD dwSectionSize); bool savea...