我们来自五湖四海,不为别的,只因有共同的爱好,为中国互联网发展出一分力!

Hacking Team攻击代码分析Part 2:一个Pwn2Own漏洞的奇幻漂流

2015年07月11日00:44 阅读: 23190 次

标签: Hacking Team攻击代码分析, Part 2:一个Pwn2Own, 漏洞的奇幻漂流

之前我们分析了HackingTeam泄露数据中的Flash 0day (bytearray 0day)。而在泄露数据中我们还看到了另外一个名为convolution_filter的flash exploit。?
看了一下这个flash exploit,很快意识到这个漏洞是一个已经修补的漏洞cve-2015-0329,在今年4月份被修补,这也解释了readme文档中,flash后面加了“(April 2015)”,意思是这个洞只能用到今年4月之前的flash版本中:?
(https://helpx.adobe.com/cn/security/products/flash-player/apsb15-06.html)?
这个漏洞有个不平凡的故事,今年的Pwn2Own大赛中,前Vupen主力Nicolas Joly正是用这个漏洞拿下了64位Flash插件:?
?
?
??
所以事情就变得很有趣了,一边是Nico用这个漏洞打 Pwn2Own,另一边HackingTeam(从常理推测,应该是通过其它渠道,和Nico无关)也掌握了这个漏洞并将其用于自己的Exploit工具包中。?
CVE-2015-0349原理分析?
再回头看一下CVE-2015-0349这个漏洞,这是一个ActionScript 3中ConvolutionFilter类的内部matrix数组的一个Use After Free漏洞,这是个非常好用的漏洞,在32位和64位上都可以轻松实现稳定利用。?
我们来看一下HackingTeam泄露的exploit代码,关键部分如下:?
1. ?创建ConvolutionFilter对象:?
// try to allocate two sequential pages of memory: [ matrix ][ MyClass2 ]?
?? ? ? ? ? ? ? ?for(i=20; i?
1. ?设置ConvolutionFilter.matrix?
var m:Array = new Array(bLen);?
m[0] = new Clasz;?
m[1] = m[0];?
??
try { filter.matrix = m; } catch (e:Error){}?
这里有一个关键点,filter.matrix被赋值为m(类型是 Array),而Array m的第一个元素是一个Clasz类,而Clasz类定义了valueOf方法,这个valueOf是漏洞触发的关键点:?
public class Clasz?
?? ?{?
?? ? ? ?…?
?? ? ? ?public function Clasz() { ? }?
?? ? ??
?? ? ? ?prototype.valueOf = function()?
?? ? ? ?{?
…?
}?
2. ?在Clasz的valueOf函数中,设置ConvolutionFilter.matrixX:?
prototype.valueOf = function()?
?? ? ? ?{?
?? ? ? ? ? ?if (filter.matrixX > 14) throw new Error(""); // check for the second valueOf() call?
?? ? ??
?? ? ? ? ? ?ref = new Array(5);?
?? ? ? ? ? ?collect.push(ref); // protect from GC // for RnD?
?? ? ? ? ??
?? ? ? ? ? ?filter.matrixX = 15; // reallocate filter matrix?
?? ? ? ? ??
?? ? ? ? ? ?// reuse freed memory?
?? ? ? ? ? ?for(var i:int; i ;?
?? ? ? ? ? ? ? ?ref.length = bLen;?
?? ? ? ? ? ?}?
?? ? ? ? ??
?? ? ? ? ? ?// return value for vector length overwriting?
?? ? ? ? ? ?return 2; // = 0x40000000 as single precision?
?? ? ? ? ??
?? ? ? ?}?
事实上filter.matrixX = 15执行完毕之后,ConvolutionFilter内部的一个float数组(我们叫他matrixArray)就会被释放,而从valueOf返回之后,已经释放的matrixArray还会继续被使用,并且往里面写入数据,从而造成了Use-After-Free。我们可以看到valueOf函数中,在设置了filter.matrixX之后,分配了一系列的vector,这些vector就是用来占用释放后的matrixArray的内存的。这样当程序继续往被释放后的matrixArray里写数据时,实际上是在往vector对象里面写数据,从而达到修改vector长度字段的目的,便于进一步exploit。?
细节分析?
我们首先先介绍一下ConvolutionFilter的关键结构:?
ConvolutionFilterObject {?
+10 ConvolutionFilter {?
?? ?+14 ? ? int matrixX;?
?? ?+18 ? ? int matrixY;?
?? ?+1C ? ? float *matrixArray;?
+20 ? ? int matrixLength;?
}?
}?
ConvolutionFilter里面有成员存放matrix矩阵,matrixX和matrixY代表矩阵的x和y,matrixArray是动态分配的数组,其大小是由matrixX和matrixY决定的,关系如下:?
matrixArray = alloc( matrixX * matrix * sizeof(float) )?
当matrixX和matrixY改变时,如果原来的matrixArray大小不足以容纳现在的容量,则旧的matrixArray会被释放,然后分配新的matrixArray (UAF就是这么来的)?



当exploit代码创建ConvolutionFilter时,传入的参数是matrixX=14,matrix=15:?
a[j] = new ConvolutionFilter(14,15);?
因此matrixArray初始大小为 14 * 15 * 4 = 840,然后我们看一下第二步,执行?
try { filter.matrix = m; } catch (e:Error){}?
时发生了什么:?
ConvolutionFilter::set_matrix基本上是直接调用了另外一个函数,我们叫他set_matrix_internal:?
.text:102E9604 loc_102E9604: ? ? ? ? ? ? ? ? ? ? ? ? ? ; CODE XREF: sub_102E95ED+Aj?
.text:102E9604 ? ? ? ? ? ? ? ? push ? ?14h?
.text:102E9606 ? ? ? ? ? ? ? ? lea ? ? eax, [esi+24h]?
.text:102E9609 ? ? ? ? ? ? ? ? push ? ?eax?
.text:102E960A ? ? ? ? ? ? ? ? mov ? ? eax, [esi+8]?
.text:102E960D ? ? ? ? ? ? ? ? mov ? ? ecx, [eax+4]?
.text:102E9610 ? ? ? ? ? ? ? ? or ? ? ?edi, 1?
.text:102E9613 ? ? ? ? ? ? ? ? push ? ?edi?
.text:102E9614 ? ? ? ? ? ? ? ? call ? ?set_matrix_internal?
调用该函数时参数如下:?
set_matrix_internal( paramArray, ?matrixArray, ?matrixLength )?
这里的关键点是:matrixArray直接作为参数被传入。我们来看一下set_matrix_internal函数,该函数的功能可以描述为:将paramArray(在exploit里面就是m这个数组)里面的每一项赋值给matrixArray中对应的项,由于matrixArray的类型为float *,因此如果有必要的话得把paramArray中的元素转换成float,对应逻辑的伪代码如下:?
for ( i = 0; I?
还记得我们的m[0]被设置成一个Clasz对象了吗??
m[0] = new Clasz;?
将Clasz对象转换成Number的过程中,会调用Clasz对象的valueOf函数,而前面已经讲过,valueOf函数会设置filter.matrixX=15(原来的matrixX为14),此时由于matrixArray大小不够,于是旧的matrixArray被释放,新的matrixArray被分配。然后从valueOf返回到set_matrix_internal以后,程序继续向matrixArray里面写入值,注意这里用的还是旧的 matrixArray,于是UAF漏洞就这样产生了。?
又是valueOf?
如果你看过我们前一篇分析bytearray 0day的文章,你可能对valueOf这个函数依然印象深刻。事实上这两个洞无论是从产生原理,还是利用方式来讲都非常的相近。背后隐藏的逻辑是脚本语言从native code回调到脚本层(通过toString, valueOf, event等等),还是很容易出现没处理好而造成UAF等情况的发生。类似case已经在chrome, IE, flash, java等等软件中多次出现,有心的读者可以去留意一下。事实上这也是脚本语言漏洞挖掘中的一个值得切入的点。?
漏洞防范?
由于Adobe官方已针对此漏洞发布了安全更新,用户只要及时升级就可避免受此漏洞影响。
分享到: 更多
?2019 安全焦点 版权所有.