Hacking Team安卓浏览器攻击过程中的漏洞分析 Stage1


发布人:admin分类:网络安全浏览量:33发布时间:2017-12-12

本文原创作者:MarcusAurelius

一、漏洞简介

Hacking team今年爆出了针对android4.0.x-4.3.x android浏览器的漏洞攻击利用代码。该漏洞攻击代码,通过连续利用多个浏览器与内核漏洞,完成通过javascript向虚拟内存写数据,执行代码,提升至root权限,并最终达到向目标手机中植入恶意程序的目的。

此攻击流程共分5个阶段,本人的上一篇文章《Hacking Team安卓浏览器攻击过程中的漏洞分析 Stage0》,已对stage0进行了分析,本文主要分析stage1的工作。

在上一篇文章最后,通过stage0,攻击者已经获得了页块信息(一个4M大小的Javascript数组,后文简称页块)并且泄露出一个指向页块内部的特定字符串(“http://www/w3.org/1999/XSL/Transform”)的线性地址,由于页块是通过javascript申请的4MB空间,而通过stage0所泄漏出的线性地址,无法被判断其在4M页块中偏移。而stage1的工作就是确定所泄露出的线性地址所在的内存页,在页块中的具体偏移。进而推算出4MB的页块在内存中的准确地址。这样就绕过了堆内存地址随机化等保护措施。

二、漏洞详细信息

0.概述

Stage1利用的0Day漏洞原理如下:

stage1存在两个漏洞。

漏洞1属于由于不合理的id生成方式导致的地址泄漏。

图1 generate-id实现代码

generate-id函数的主要功能是为目标对象生成一个id值,可实际在函数执行过程中,生成id的方法如图1红框中所示,将对象的地址值除以对象长度(60)。因此可以通过生成的id乘60的方法,泄露出目标对象的地址信息(地址范围在特定的60byte中),这就达到了地址泄漏的目的。

漏洞2属于未对对象类型进行正确性检查,就直接错误地进行强制类型转换,错误地将一个xmlNs类型的指针当作一个xmlNode类型的指针使用,并导致xmlNs中的一个完全可控的字符串指针(prefix)被当作xmlNode指针(children)所使用。由于字符串转换成xmlNode节点后,节点的类型是未识别类型,因此导致字符串会被当作非法节点从双向链表中移除,在将字符串从链表中摘除的操作中,存在操作cur->prev->next=cur->next操作,导致任意地址写漏洞。攻击者可以通过控制字符串制造任意的xmlNode对象(被cur指向)。

修改prev指针(cur+28位置),再修改next指针(cur+24位置),这样就可以达到向任意的[prev]+24的位置写入任意值(next的值)。漏洞利用的思路是:首先,通过JS将stage0所申请的页中的数据清空。然后,将字符串中+28位置的地址修改为一个在与stage0所泄漏出的虚拟地址相同页的任意一个虚拟地址,+24的位置修改为一个特定值,然后使用漏洞即可向虚拟内存页中的特定地址中写入特定值,然后循环查找页块中的每一个虚拟内存页中的特定地址,当其中的值为特定值时,即可判断出stage0中所泄露出的地址所在的页在页块中的位置。之后通过计算偏移,就可以计算出页块的起始地址。

hacking team在实际使用时对代码还进行了漏洞利用稳定性的优化处理,漏洞利用稳定性的优化处理在三中分析。

下图简单的介绍了程序进入stage1时的情况。

  

图2 stage1输入参数的关系

图2分析了当执行到stage1时程序的状态。图2中的页块(红框范围)代表由javascript所申请的4MB的页,而蓝框中的页代表虚拟内存空间的4KB的页。由stage0泄漏出的指针,指向由javascript所申请的页块中的一个虚拟内存页,正如我们所看到的,通过stage0无法知道泄漏出的指针具体指向哪一个虚拟地址内存页,也无法推算出页块的基地址。而stage1主要达到的效果就是通过stage1的漏洞确定图2中的n的实际值。并通过此值通过计算偏移的方法计算出页块的基地址。

1.触发崩溃的数据结构和利用代码

由于此漏洞是在xsl执行过程中所引发的漏洞,所以此漏洞利用代码有xml部分、xsl部分和填充的内存数据部分:

  

图3 漏洞触发代码 xml部分

图3为触发漏洞所需的xml代码,其主要功能是将引发错误时被强制类型转换的字符串信息写入xmlNs对象中。其中字符串信息(ns)信息会被存入图5中的xmlNs节点中的prefix指针中,nsname会被存入href中。   

图4  漏洞出发代码 xsl部分

图4为触发漏洞所需的xsl代码,我们所须关注的重点是红框画出的部分,其大致含义是,找出节点中的namespace节点,并获取第二个namespace节点(第一个节点为一个合法的xmlNs节点;第二个namespace节点为图3中所创建的包含字符串信息的节点)。

程序在运行过程中会为namespace(xmlNode)节点创建一个副本,然后将副本namespace节点中的next字段设置为图3中的nsuri节点,通过存储此节点来确定副本的归属。之后,对副本namespace节点进行apply-templates操作(此操作为强制类型转换操作)。

在apply-templates函数执行时,其传入参数为一个经过之前的条件检索出的节点,也就是说,被传入的节点为一个xmlNs节点。由于程序每做类型检查,此节点会被当作一个xmlNode节点进行操作。之后函数会循环遍历xmlNs的所有子节点,对节点类型为“未识别”的节点和类型为“DTD类型”的节点进行去链和删除操作,再循环对其他合法节点进行后续处理。由于xmlNs节点是通过字符串构造的,因此在去链操作中会触发任意地址写漏洞。

2.漏洞成因:

程序出现漏洞的根本原因是由于,在xsl执行到apply-templates时,会将传入的节点强制类型转换成xmlNode节点进行操作,而在使用时不进行任何节点类型的检查。

图5 xmlNode对象和xmlNs对象

如图5所示,当xmlNs被转换成为xmlNode对象时,红框中的字符串指针(prefix)会被当作xmlNode节点指针使用。也就是说,攻击者所构造的字符串在apply-templates的执行过程中,会被当作xmlNode使用。

当apply-templates执行时, 函数会遍历所有子节点,当发现字符串节点的类型不可识别时,会将字符串节点去链删除。

图6 清除未识别元素的去链操作

图6是摘除字符串节点时对字符串节点进行去链操作的流程,其中会被攻击者利用的操作为:ztX节点的指针会被存储到字符串节点(转换为xmlNode节点)可控制的内存中(如图6),所以可将ztX节点的地址(ztX节点的地址是被字符串所指向的指针,是stage0泄漏出的地址)写入当前页中的任意地址,在hacking team实际的攻击过程中此地址为虚拟内存页起始地址+0×88。此后程序只要循环读取每页的0×88中的信息,看其是否为stage0泄漏出来的地址,就可以确定指针是否指向此页,并由此推算出整个页块的基地址。

三、漏洞利用稳定性的优化处理

在图4中的xsl代码中,不仅有触发漏洞的代码,同时还有一组代码,而这组代进行了漏洞利用稳定性的优化操作。

由于在漏洞利用阶段,apply-tamplates会将字符串认定为未识别的类型,因此会对字符串指针指向的位置进行清除操作,由于字符串指针在清除时,并没有修改xmlNs节点的prefix指针,导致prefix指针指向了一个被free的内存块。而在后续操作中,程序会循环调用xmlXPathNodeSetFreeNs函数,对所有的namespace节点进行删除操作。

图7 xmlXPathNodeSetFreeNs函数的操作流程

从图7中我们能发现,当ns的next字段所指向的xmlNs节点(此时实际指向了一个xmlNode类型的节点)不为空且节点类型不为XML_NAMESPAC_DECL时,会对ns进行free操作。由于ns->prefix所指向的字符串,在之前的apply-templates中已经被删除,所以此时再进行free会引发可被android操作系统捕获的崩溃。

为了避免此崩溃发生,攻击者采用了将next所指向的xmlNs节点的类型修改为XML_NAMESPACE_DECL的方法,使ns节点不被free。

之前已经说明过,ns->next会指向图3中的nsuri节点,所以用户需要对nsuri节点的类型字段进行修改,当将类型改为0×12(XML_NAMESPAC_DECL所代表的数字)时,namespace节点就会绕过删除操作,从而避免崩溃。此过程分为以下步骤。

1. 获取nsuri节点的地址信息:

图8 通过generate-id获取内存地址信息

攻击者可以通过generate-id()函数获取nsuri节点的一个id值。而这个id值的生成方式是由nsuri节点的内存地址除xmlNode类型的长度(60)获得。

2. 循环填充15个内存区域:

Javascript会循环填充15次如图9中的节点信息,并在每次循环中将documentarea的值循环递减4,由于documentarea是由生成的id乘以60再加上60得来的,通过对其循环递减4,可以使documentarea覆盖整个60个地址长度的内存,其中必有一个指针指向了图3中nsuri所在的位置。

3. 泄漏nsuri节点的准确地址:

图9  此时内存中填入的信息

在图3中,执行红框上面关于ELZ的比较时,会对图9中第一个红框中的地址进行比较,判断其是否是一个确实属于图2中的nsuri节点的数据(判断节点的上下文信息是否指向nsuri+4),只有当图9的第一个红框中的documentarea= nsuri+4时,才会进入第二次apply-templates,由于在15次填充中,必会出现匹配成功的情况,进入到第二次apply-templates,这时apply-templates中执行节点的数据所携带的documentarea地址,正是指向nsuri+4的位置。这就达到了泄漏nsuri地址的目的。

4. 再次进行apply-templates操作:

图10 去除DTD节点的操作

在第二次执行apply-templates会进行与第一次类似的操作,此时会删除DTD类型的节点。而在对DTDOverwrite节点进行去链操作时,函数会将documentarea-24(图9第三个红框中)当作xmlNode类型进行操作(此时修改documentarea-24的next指针就指向nsuri节点的类型字段),此时会将nsuri节点的类型字段赋值为node12节点的地址,而此地址的末尾是0×12。

之后对DTDClear节点进行去链时,会将documentarea-23(图9第二个红框中)当作xmlNode类型进行操作,此时会将nsuri节点的类型字段赋值的前几位清空,使得类型值变为0×12(XML_NAMESPAC_DECL所代表的数字)。这时在运行到图7所示的xmlXPathNodeSetFreeNs函数时,由于cur->next->type=0×12,所以不会对ns节点进行删除操作,从而避免了崩溃。

本文由:3020337181@qq.com和3352444864@qq.com合作完成

*作者:MarcusAurelius,本文属FreeBuf原创奖励计划文章,


被黑站点统计 - 文章版权1、本主题所有言论和图片纯属会员个人意见,与本文章立场无关
2、本站所有主题由该文章作者发表,该文章作者与被黑站点统计享有文章相关版权
3、其他单位或个人使用、转载或引用本文时必须同时征得该文章作者和被黑站点统计的同意
4、文章作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
7、被黑站点统计管理员有权不事先通知发贴者而删除本文

免责声明

本站主要通过网络搜集国内被黑网站信息,统计分析数据,为部署安全型网络提供强有力的依据.本站所有工作人员均不参与黑站,挂马或赢利性行为,所有数据均为网民提供,提交者不一定是黑站人,所有提交采取不记名,先提交先审核的方式,如有任何疑问请及时与我们联系.

admin  的文章


微信公众号

微信公众号


Copyright © 2012-2022被黑网站统计系统All Rights Reserved
页面总访问量:21264380(PV) 页面执行时间:72.06(MS)
  • xml
  • 网站地图