CVE-2010-2883 Luckycat

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:

12314sda

找到箭头所指那条

我们双击后进行审计,找到了危险函数strcat

421468c32d3e2d1df5d9b066a3aa11ee

选中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的偏移量

image-20241125201119179

由上可知,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结构数据

image-20241125201946716

image-20241125202544897

实际上的sing表结构

image-20241125202751901

动态调试

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

img

然后下上断点

我们可以看到这些就是我们的关键部分

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 函数

img

栈顶push一个sing

img

Push一个edi,edi地址为0012E744

img

给ECX付了个地址

img

这时ECX的值也变了

ECX指针把值付给EAX,EAX的值是CoolType.08021A23函数返回的值,很明显这是一个地址

我们可以在数据窗口跟随这个地址

img

这个其实就是sing表

我们继续往下调试分析

image-20241125210435775

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

image-20241125210931755

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

我们在反汇编窗口跟随返回地址

image-20241125211620728

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

image-20241125212511152

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

image-20241125212758031

然后在运行,接着会返回

image-20241125213009435

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

image-20241125213541568

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

image-20241125214113666

image-20241125214427604

通过这样一套流程,我们的shellcode可以绕过防护直接进入内存被执行

实验总结

掌握CVE-2010-2883 luckycat漏洞原理以及基本方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值