快捷搜索:  网络  后门  CVE  渗透  木马  扫描  黑客  as

CVE-2018-8174:从UAF到任意地址读写

*

0×00 违景

2018年5月9日,360发表Blog “Analysis of CVE-2018-8174 VBScript 0day and APT actor related toOffice targeted attack” 揭破了行使“双杀”0day提议的APT攻击,其中使用的漏洞就是IE vbscript 0day:CVE-2018-8174,不久该样本就在互联网被公布。由于360的Blog并没有对漏洞道理以及任意地址读写的行使要领具体先容,且原始样本混淆严重,笔者对样本进行了简化,重点说明该漏洞的道理以及怎么样行使该漏洞完成任意地址读写,希翼帮助人人更好的理解这个漏洞行使程序。

0×01 漏洞道理

poc以下:

CVE-2018-8174:从UAF到任意地址读写

poc中起首定义了两个数组array_a以及array_b,并声明晰一个类Trigger,Trigger中重载了析构函数Class_Terminate,在UAF函数中,创建了一个Trigger的实例赋值给数组array_a (1),并通过Erase array_a清空array_a中的元素,这时辰候在析构array_a中的元素的时辰会触发脚本中Class_Terminate的调用,在Class_Terminate中增添了一个array_b(0)对Trigger实例的引用(Trigger实例引用计数+1),再通过array_a (1)= 1删除array_a (1) 对Trigger实例的引用(Trigger实例引用计数-1)来平衡引用计数,这时辰候Trigger实例会被开释,然则array_b(0)仍旧保留了这个Trigger实例的引用,从而array_b(0)指向了被开释的Trigger实例的内存,终极在TriggerVuln中通过b(0) = 0走访未调配内存触发漏洞。开启hpa以及ust观察漏洞现场: 

CVE-2018-8174:从UAF到任意地址读写

显著eax已经在vbscript!VbsErase的调用栈中被开释了,vbscript!VbsErase即对应了脚本中的Erase,而eax恰是被VBScriptClass::Release函数开释的VBScriptClass对象也就是脚本中的Trigger实例。这里看下VBScriptClass::Release的逻辑: 

CVE-2018-8174:从UAF到任意地址读写

VBScriptClass::Release中起首对VBScriptClass的引用计数-1(&VBScriptClass+0×4),要是引用计数=0则调用VBScriptClass::TerminateClass,调用VBScriptClass::TerminateClass时因为在脚本中重载了Class_Terminate函数,所以获患了一次脚本执行的机会,这里就可以在开释VBScriptClass的内存前将即将开释的VBScriptClass内存地址保存脚本控制的变量中(Set array_b(0) =array_a(1)),并通过array_a (1) = 1平衡引用计数,终极开释内存。

1) Set array_a(1) = New Trigger:此时VBScriptClass引用计数=2

CVE-2018-8174:从UAF到任意地址读写

2) Erase array_a返归后: 

CVE-2018-8174:从UAF到任意地址读写

此时Trigger指向的内存已经被开释,然则array_b(0)仍旧指向这块被开释的内存,形成吊挂指针。 

0×02 漏洞行使 

UAF漏洞行使的症结是怎么样使用这个吊挂指针操作内存。通过阐发漏洞道理知道array_b(0)指向被开释的VBScriptClass的内存(大小为0×30),这时辰候可以用一个VBScriptClass占位(这里称为MyClass2),接着行使吊挂指针array_b(0)开释这块内存再用另外一个VBScriptClass占位(这里称为MyClass1),此时MyClass1以及MyClass2将同时指向这块内存。此外VBScriptClass在+0×08处是保存了VBScriptClass成员变量以及成员函数NameTbl对象(大小为0×88)的指针,NameTbl对象从+0×48最先保存成员变量以及成员函数的指针:

CVE-2018-8174:从UAF到任意地址读写可以理解为下图,通过UAF MyClass1 以及MyClass2都指向VBScriptClass的内存,同时MyClass1 MyClass2的变量也都保存在NameTbl中,要是MyClass1 MyClass2的变量在NameTbl内存是错位排列的,那么就有可能通过控制其中一个对象变量的值来修改另一个对象变量的属性,从而完成类型混淆:

CVE-2018-8174:从UAF到任意地址读写简化后的任意地址读写poc:

CVE-2018-8174:从UAF到任意地址读写CVE-2018-8174:从UAF到任意地址读写

起首在UAF函数中创建了一些VBScriptClass对象盘踞体系堆碎片为后面UAF预备,然通过触发漏洞获得指向已开释的Trigger对象内存的array_b,接着通过“Set mycls2 = New MyClass2”,用MyClass2占位开释的内存,此时array_b的7个元素以及MyClass2都指向这块内存。

在InitObjects函数的“mycls2.SetProp(myconf)”中会触发Confusion类的Public Default Property Get P函数调用,并将返归值“P=174088534690791e-324”保存在MyClass2的成员变量mem中。在PublicDefault Property Get P函数调用中,再次行使吊挂指针array_b(i)开释了MyClass2的内存,然后用MyClass1占位并将字符串FAKESAFEARRAY赋值给MyClass1的成员变量mem,由于MyClass2依然指向这块内存,因此MyClass2.mem = MyClass1.mem = FAKESAFEARRAY。

注意到之前Public Default Property Get P函数调用的返归值“P=174088534690791e-324”会保存在MyClass2的成员变量mem中,然则此时MyClass2内存已经被开释,返归值“P=174088534690791e-324”仍旧会保存在原来的MyClass2的mem指向的内存地址,poc中的被开释的MyClass2的mem以及MyClass1的mem有0xC字节的错位,而“P=174088534690791e-324”对应的VARIANT在内存中的值为“00000005 00000000 00000000 0000200C”,工控黑客 ,从而行使错位的“0000200c”将BSTR混淆为VARIANT|ARRAY,而FAKESAFEARRAY的内容偏偏是一个肇始地址为0×00000000长度为0x7FFFFFFF每一个元素占1Byte的数组,终极完成任意地址读写。

1)Set mycls2 = New MyClass2后MyClass2的内存布局:

CVE-2018-8174:从UAF到任意地址读写2)PublicDefault Property Get P中MyClass2被开释,MyClass1占位: 

CVE-2018-8174:从UAF到任意地址读写

可以看到MyClass1.mem(0x020066C6C)以及开释前的MyClass2.mem(0x020066C60)相差0xC Byte 

3)PublicDefault Property Get 返归后通过“P=174088534690791e-324”修改开释前的 MyClass2.mem为“00000005 00000000 00000000 0000200c”完成类型混淆:

CVE-2018-8174:从UAF到任意地址读写

终极myClass2.mem获得任意地址读写权限。

同理BSTR也能够被混淆成Long类型用来泄露shellcode的内存地址:

CVE-2018-8174:从UAF到任意地址读写CVE-2018-8174:从UAF到任意地址读写

关于对象地址泄露以及shellcode执行,可以参考360那篇Blog,当然DVE也是可行的,再也不胪陈。

*

您可能还会对下面的文章感兴趣: