CVE-2010-2883 Luckycat
实验目的
本实验漏洞利用的知识点有PDF格式、TTF字体格式、缓冲区溢出漏洞利用、PE文件格式、软件脱壳和恶意代码分析。
实验环境
虚拟机:Win7 X86 SP3、Kali
调试工具:IDA、ollydbg
目标软件:Adobe Acrobat Reader 9.0
16进制编辑器:010Editor
实验原理
Adobe Reader 是流行的PDF阅读软件。CVE-2010-2883 Adobe Reader TTF 字体 SING 表栈溢出漏洞的成因是Adobe Reader和 Acrobat 9.3.4中的 CoolType.dll 在解析 PDF 中的字体时未检查数据的长度,导致缓冲区溢出。
实验步骤
漏洞复现
1.登录"Kali"操作机,打开终端,打开msf,输入如下命令构造我们的EXP
下面是各个命令的说明
search cve-2010-2883: 这个命令用于搜索与指定 CVE(公共漏洞和暴露)编号相关的漏洞利用模块。在这里,是针对 Adobe CoolType 的一个已知漏洞。
Matching Modules: 这个部分列出了符合搜索条件的可用漏洞模块。每个条目包括模块名称、披露日期、等级和描述。
use 1: 这个命令通过索引号(此处为 1)选择漏洞模块,并设置该模块以进行进一步配置和使用。
[*] No payload configured, defaulting to windows/meterpreter/reverse_tcp: 如果未指定有效载荷,Metasploit 会默认使用一个常见的有效载荷(windows/meterpreter/reverse_tcp)。
set payload windows/exec: 这将有效载荷设置为 windows/exec,允许在目标系统上执行指定命令。
set cmd calc.exe: 这将有效载荷配置为在目标系统上执行 calc.exe 命令(Windows 计算器)。
exploit: 这个命令生成带有配置有效载荷的漏洞文件(在这里是 msf.pdf)。
2.把Kali中的Exp拖到本机,再拷贝到Win xp中,拖到Adobe中
弹出计算器,证明漏洞存在,Exp也没有问题。
基于字符串定位的漏洞分析方法
接下来的操作都在我们的Windows xp上进行
首先我们需要做几个准备工作,1、改掉随机基址,省的麻烦,把用010Editor打开Adobe,修改如下地方:
因为已知漏洞问题是在CoolType.dll,直接在安装文件夹下找到这个dll,拖到Ida中:

然后Alt+T,搜索sing:

找到箭头所指那条
我们双击后进行审计,找到了危险函数strcat

选中strcat,f5后查看
int v18; // [esp+44h] [ebp-24h]
............
char Destination[260]; // [esp+68h] [ebp+0h] BYREF
if ( v18 )
{
if ( !(unsigned __int16)*(_DWORD *)v18 || (unsigned __int16)*(_DWORD*)v18 == 256 )
{
Destination[0] = 0;
strcat(Destination, (const char *)(v18 + 16));
sub_8001243(Destination);
v6 = v18;
}
v21 = 1;
}
其中,v18 +16是 uniqueName相对于 SING的偏移量

由上可知,Adobe Reader在调用strcat时,未对uniqueName字段的字符串长度进行检测,将其直接复制到固定大小的栈空间,最终导致栈溢出。
样本Exploit技术分析(三级标题)
首先,用PdfStreamDumper(下载地址:http://sandsprite.com/blogs/index.php?uid=7&pid=57)提取出PDF样本里的TTF文件,在工具里选中相应Object,单击鼠标右键选择“Save Decompressed Streams”选项即可保存到本地。TTF中关于SING表的TableEntry结构数据


实际上的sing表结构

动态调试
我们用ollydbg打开Adobe Reader,按Ctrl+G搜索在ida找到的内存地址

然后下上断点
我们可以看到这些就是我们的关键部分
0803DB6A 68 E4DA1908 push CoolType.0819DAE4 ; 压入地址 CoolType.0819DAE4,可能是字符串 "ING"
0803DB6F 57 push edi ; 将寄存器 edi 的值压入栈
0803DB70 8D4D DC lea ecx,dword ptr ss:[ebp-0x24] ; 将 ebp-0x24 地址加载到 ecx 寄存器
0803DB73 E8 AB3EFEFF call CoolType.08021A23 ; 调用函数 CoolType.08021A23
0803DB78 8B45 DC mov eax,dword ptr ss:[ebp-0x24] ; 将 [ebp-0x24] 中的值加载到 eax 寄存器
0803DB7B 3BC6 cmp eax,esi ; 比较eax和esi的值,esi 可能是一个特定的值
0803DB7D C645 FC 02 mov byte ptr ss:[ebp-0x4],0x2 ; 如果比较结果为真(eax != esi),则将值 0x2 存入 [ebp-0x4] 内存位置
0803DB81 74 37 je short CoolType.0803DBBA ;如果比较结果为真(eax == esi),跳转到 0803DBBA
0803DB83 8B08 mov ecx,dword ptr ds:[eax] ; 将 [eax] 地址的内容加载到 ecx 寄存器
0803DB85 81E1 FFFF0000 and ecx,0xFFFF ; 对 ecx 执行 0xFFFF 的按位与操作(保留低16位)
0803DB8B 74 08 je short CoolType.0803DB95 ; 如果 ecx 为 0,跳转到 0803DB95
0803DB8D 81F9 00010000 cmp ecx,0x100 ; 比较 ecx 和 0x100
0803DB93 75 21 jnz short CoolType.0803DBB6 ; 如果 ecx != 0x100,跳转到 0803DBB6
0803DB95 83C0 10 add eax,0x10 ; 如果 ecx == 0x100,eax 加上 0x10
0803DB98 50 push eax ; 将 eax 压入栈,可能用于函数调用
0803DB99 8D45 00 lea eax,dword ptr ss:[ebp] ; 将 ebp 的地址加载到 eax 寄存器
0803DB9C 50 push eax ; 将 eax 压入栈,可能用于函数调用
0803DB9D C645 00 00 mov byte ptr ss:[ebp],0x0 ; 将 [ebp] 地址的值设置为 0
0803DBA1 E8 02391300 call <jmp.&MSVCR80.strcat> ; 调用 MSVCR80 库中的 strcat 函数

栈顶push一个sing

Push一个edi,edi地址为0012E744

给ECX付了个地址

这时ECX的值也变了

ECX指针把值付给EAX,EAX的值是CoolType.08021A23函数返回的值,很明显这是一个地址
我们可以在数据窗口跟随这个地址

这个其实就是sing表
我们继续往下调试分析

接下来我们单步步过strcat函数

可以看到EBP中数据已经改变,返回地址已变成了0C0C0C0C,它是我们构造在堆区的一个地址,里面存放着我们的shellcode。
我们在反汇编窗口跟随返回地址

可以看到,这里pop 一个esp,其实就是0C0C0C0C,然后在这里设个断点,一直运行到这

此处用到了ROP技术绕过DEP,执行这两条指令的作用是将栈中跳转地址的下一地址的内容(此处为0x0C0C0C0C)赋值给esp,产生的作用等同于 mov esp,0x0C0C0C0C;此时的esp被修改为0x0c0c0c0c,这时就将代码执行流引导至地址0x0C0C0C0C处,可以看到,我们的的栈顶变成了0C0C0C0C,我们继续运行,这时esp就要变成0C0C0C0C

然后在运行,接着会返回

可以看到返回之后栈顶就要发生改变,这个栈顶放了很多返回地址,每个返回地址都对应一个retn,相当于构成了一个ROP链。我们接着往下调试

这个CreatefileA是一个库函数,继续跟进ROP链,看到先后调用函数CreateFile 、CreateFileMapping、MapOfViewMap创建了文件iso88591:


通过这样一套流程,我们的shellcode可以绕过防护直接进入内存被执行
实验总结
掌握CVE-2010-2883 luckycat漏洞原理以及基本方法

1342

被折叠的 条评论
为什么被折叠?



