Lilang Wu(吴东洋),深信服安全专家,主要从事Mobile、 Mac/Linux漏洞挖掘和恶意软件分析。
曾参加过BlackHat USA 2018/2019、 BlackHat EU/Aisa、HITB、CodeBlue等安全会议。
下面我们来介绍一下相关的攻击方式,以及它是如何实现自身权限的提升的。首先看iOS的部分,它主要采用了一个没有CVE的漏洞。这个漏洞是在去年6月19日的时候第一次被修复,但相应的修复并没有merge到Safari,在去年7月5日,有人公布了针对Safari的一个PoC,6号的时候也公布了相关漏洞的EXP,苹果在去年7月22号修复了这个漏洞。在这个期间,它作为0Day已经存活了17天,受影响的Safari版本是12.1.1。
上图是这个漏洞的PoC,这个漏洞也是JIT的一个类型混淆漏洞,相关JIT的知识在上一位演讲者已经介绍过了。JIT会将使用非常频繁的代码进行编译优化,下一次运行时会检索已经编译过的代码去执行。PoC的第一步就是通过循环执行一万次先将victim函数JIT化;第二步是victim函数中使用let r = 5 in ob来触发原型中的has函数;第三步当victim()函数JIT化后将hack置1,此时第四步再去调用victim()函数的话,原型当中的函数就会被执行,数组也因此由ArrayWithDouble类型转化为ArrayWithContigous类型。
下面介绍一下攻击者如何利用这个漏洞,首先构造addrof和fakeobj原语,前者是获取任意对象的地址,后者是在任意地址上去创建一个对象。相关的利用手法已经比较成熟了,如果有感兴趣的可以看一下下面这个链接。
攻击者主要是利用这两个原语去实现Safari进程空间的任意地址读写,在喷射完相关的对象之后,构造一个如下内存布局的js对象,红色框代表的是js对象的内部属性和butterfly的结构,蓝色框代表的是js对象的外部属性。我们都知道js对象的外部属性是顺序排在butterfly地址之后的,因此如果通过js对象的外部属性伪造一个对象,这个时候我们再去检索fake_wasmBuffer_addr地址时,js引擎就会认为其外部属性是一个js的对象,因此攻击者可以通过一个对象的外部属性来操控这个伪造的对象,显然这个地方攻击者想操作的对象是WebAssembly.Memory。
另外js对象的类型解析主要是由内部属性当中的structureID决定的,攻击者之前已经喷射了0x5000个Float64Array对象和50个WebAssembly.Memory,此时以0x5000为structureID来检索js对象时,很大概率会是一个Float64Array对象,当然也有可能是WebAssembly.Memory对象。攻击者使用instanceof函数来判断当前对象的类型,如果不是已喷射的WebAssembly.Memory对象,会通过修改structureID的值继续向后检索内存,直到找到之前喷射的Memory对象。
在找到这个对象之后,攻击者又构造了一个如下图所示的对象,并将其复制到wasmBuffer对象的memory外部属性中。这个时候攻击者就可以通过这两个对象的外部属性来操纵之前伪造的对象,从而拿到操作WebAssembly.Memory的桥梁。
这个是攻击者的具体实现,两次调用了fake_ob*相关的函数来实现上述两次fake对象的目的。在拿到初步的进程内存访问的条件之后,攻击者通过一段WebAssembly代码进一步实现内存读写的原语,包括64bit,32bit和8bit等内存空间的读写原语。通过这些原语,就可以实现Safari进程空间的任意地址的读写。在拿到读写权限之后,攻击者其实是想执行存放在payload.dylib中的本地提权代码,这个时候主要使用的步骤是先将payload中本地提权的代码写入到内存,并将其以macho的结构拷贝进JIT区域当中,通过payload中的bridge函数执行其中的本地提权代码。
此次间谍攻击本地提权的攻击范围是较新的操作系统iOS12.1到iOS 12.2。本地提权部分使用的是CVE-2019-8605,这个漏洞经历也比较曲折,它第一次被修复的时间是在去年的5月13日,相应的版本是iOS12.3,但在iOS12.4的时候又引入了该漏洞,苹果于去年iOS12.4.1版本中第二次修复了这个漏洞。在这段时间,相应的一些开源的漏洞利用都已经公布出来了,除了原作者之外,jakeajames将这个漏洞实现了对iOS10到iOS12还有iOS12.4全设备的支持,并开源到github中。
其实此次间谍攻击的作者也直接使用了这个开源的代码实现了内核的tfp0。我们知道tfp0只是实现了内核的任意地址读写,想要执行后续的监控模块还需要内核的任意代码执行。攻击者这里是借助IOConnectTrap6函数实现的内核态任意代码执行,IOConnectTrap6的工作原理如下,该函数首先调用iokit_user_client_trap函数,传入的参数是IOService对应的connection对象和trap所对应的index值。该函数通过解引用的userclient对象调用getTargetAndTrapForIndex函数去检索一个IOExternalTrap的对象,并返回到下面的执行部分,IOExternalTrap对象主要包含两个变量,一个是IOService对应的内核对象,另外一个是trap函数。最终通过这个内核对象调用对应的trap函数。其实这个地方只要我们能够控制这个IOExternalTrap的对象,就可以通过整个这条链路来实现内核空间的代码执行。
具体的实现方式首先是构造一个userclient对象,上述的两个函数其实都是userclient对象的虚函数,当虚函数getTargetAndTrapForIndex调用getExternalTrapForIndex函数时,大部分的userclient对象是没有实现这个虚函数的,这也给替换userclient对象当中该函数的指针创造了一定的条件。
攻击者是通过使用一个fakeuserclient对象来实现这个功能。首先这个对象复制了原始userclient对象的虚表空间。然后将getExternalTrapForIndex的函数指向如下的代码片断,这个地方的x0指针其实就是this指针,因此,getTargetAndTrapForIndex函数的返回值就是this+0x40。其实这个this指针就是fakeuserclient对象。
因此,攻击者只要在fakeuserclient偏移0x40的地方构造一个IOExternatTrap对象就可以实现任意的执行。
而对于安卓部分,由于其采用的是malware的方式来监控用户,因此这种方式只要申请足够多的敏感权限就可以了,包括读短信,读通讯录以及各种各样的资源的权限。在拿到这些权限之后,我们来介绍一下攻击者是如何获取用户的信息以及获取用户的哪些信息。
在拿到权限之后,payload.dylib会将后续所有的监控子模块下载到目标用户本地的手机上,然后通过launchctl执行一个irc_loader的daemon进程,传入的参数包括C2的地址。后续light模块启动的参数,还包括了一个下载地址。
这个下载地址初步猜测应该是供后续的升级监控主模块使用的。当irc_loader运行之后会启动light监控主模块来控制其它监控子模块的执行,我们称之为LightSpy。
LightSpy主模块如下图所示,主要通过libwebsockets模块实现远程指令收发,如右图所示,当case 8的时候,其实是实现接收服务端下发的指令,并且去执行对应的子模块中的代码。
此次间谍攻击事件主要的一些监控子模块和监控的对象有很多,监控的APP对象主要包括QQ、微信和Telegram等等。
其中ShellCommandaaa模块主要是实现接收并执行控制端下发的shell命令,然后通过popen,fgets等函数实现shell命令的执行,并把结果发送到C2中。Screenaaa模块主要是通过开源的MMLanScan模块实现扫描目标用户同一网络下的所有其他设备。FileManage模块主要是去实现远程的文件操作,包括上传、拷贝、移动和删除文件,主要的操作的对象是QQ、微信等等。
SoftInfoaaa模块是用来获取目标用户中所有安装的应用以及当前设备中所有运行的进程列表。WifiList模块主要是获取用户设备之前连接的Wifi历史和当前的Wifi列表。另外,即使用户的Wifi是关闭的,攻击者还是会打开Wifi实施扫描。Browser这个模块主要是获取Chrome和Safari的浏览历史。Location模块主要是获取目标用户的地理位置,其中包括一些精确度比较高的位置数据。
对于特定APP的监控,像微信、QQ和Telegram等,间谍软件是能获取用户的详细信息的,包括聊天信息、好友列表、聊天头像以及用户登陆信息等。如下图中右上角的图其实就是用来获取微信信息所用到的一些函数。另外,右下角的图主要是实现获取微信好友列表的功能。
其实相应的一些手法都是比较类似的,首先定位App内部相关的敏感数据文件,然后再根据相应的格式去解析。当然这个格式解析其实比较复杂,因为微信、QQ还有Telegram,它们的敏感数据的存储经过各种各样的格式转化,并且使用了一些简单的加密手段,这些都是要通过一些细致的研究之后才能解析出来,最后攻击者会把数据上传到服务端。
对于安卓部分,当申请到相应的权限之后,收集数据就比较简单了,包括收集用户的设备信息,地理位置、SD Card里面的文件信息,通讯录、短信等信息,同时注册了相关Receiver来监控目标用户实时接收的一些短信。
2020看雪SDC议题回顾 | 逃逸IE浏览器沙箱:在野0Day漏洞利用复现
……
更多议题回顾尽情期待!!