首页
社区
课程
招聘
[原创] CVE-2017-11802分析
发表于: 2017-11-3 00:45 8542

[原创] CVE-2017-11802分析

2017-11-3 00:45
8542

执行POC,异常触发在箭头所示位置

首先这里var是0x1234就是不合法的,因为0x1234理应是个TaggedInt,但是它的49位却为0
var带着值0x1234执行函数RecyclableObject::FromVar导致异常。

可以看下如下对TaggedInt的验证

向上追溯到ProfiledLdElem,箭头所指触发异常

这里element是0x1234,由箭头上一句知element是ProfiledLdElem_FastPath返回值。查看array

地址0x00000224949BC3E0处正是0x1234

之后我们可以看到在ProfilingHelpers::ProfiledLdElem_FastPath中针对array 0x224949bc380进行的操作

至此我们明白了0x00000224949BC3D8是数组元素储存的地址

针对0x000022494a255e0进行分析

因此这个数组本应是储存DynamicObject的,并且也把element1作为DynamicObject解析了,因此我们可以明确这是一个类型混淆导致的crash。

经简化后的POC如下

调试得知arr[1] = 2.3023e-320 + parseInt('a'.replace('a', f));对应的hex值即为0x1234。
</br>
在此我们猜测for循环0x1000次只是为了给opt()函数生成JIT代码,而当对JIT代码传递exp函数进行执行时就会触发漏洞。
</br>
为什么传递exp函数会触发crash?

猜测是JIT后的代码执行exp函数造成了arr由float类型混淆为Object类型数组。

梳理一下,多次调用后opt()被JIT,之后Jstring.prototype.replace调用用户定义exp(),而exp()暗含类型混淆的操作导致crash发生。
梳理清这点之后,可以提出几个问题:

为解决这些问题,需要定位string.prototype.replace函数,经调试发现函数会调用以下函数N次(for)

推测string.prototype.replace对应于RegexHelper::StringReplace,查看RegexHelper::StringReplace对应的三个参数

根据POC可以得到对应关系

根据RegexHelper::StringReplace发现一重载函数,replace参数为JavascriptFunction*

同时这里可以根据调用关系提取出JIT函数,这个JIT函数就是对应于POC中的opt()

TIM图片20171025020628.png-49.6kB
由JIT执行的函数流程如下

未经JIT的opt()函数是由bytecode解释执行的,执行流程如下。

之后通过仔细观察Js::RegexHelper::StringReplace函数的代码,发现是以下代码调用了用户自定义的函数(注意其中的replacefn->GetEntryPoint)

为了进一步解决问题,我们根据补丁的情况发现修补前的代码如下

修补后如下

可以看到是以ExecuteImplicitCall替换了CALL_FUNCTION来调用用户提供的函数

通过观察上面的函数可以发现,只有当满足一定的条件时,用户定义的implicitCall才会被调用,否则会返回undefined。

 

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 1
支持
分享
最新回复 (1)
雪    币: 5676
活跃值: (1303)
能力值: ( LV17,RANK:1185 )
在线值:
发帖
回帖
粉丝
2
膜9A82师傅
2017-11-3 01:02
0
游客
登录 | 注册 方可回帖
返回
//