【漏洞分析】如何用11个exp攻破三星S8

【漏洞分析】如何用11个exp攻破三星S8_第1张图片

Author:  Sniperhg@Vulpecker Team 、MissCoconut@Vulpecker Team

前言

在去年Mobile Pwn2Own上MWR Labs成功攻破了三星S8,据官方报道整个攻击链总共由11个exp构成,是目前Pwn2Own历史上最长利用链。上周MWR Labs公开了他们的Slide,在本次攻击中,其高深之处并不在于使用了多少个0day,而是使用的都是系统自带App层面的逻辑漏洞甚至是App特性的一连串的精巧组合而形成的攻击链。本文根据这个slide来对其攻击思路和步骤进行简要分析。

初探

【漏洞分析】如何用11个exp攻破三星S8_第2张图片

纵观整个利用链,攻击者的代码得以成功执行以及敏感信息得以成功获取,其中最关键的漏洞出现在三星手机自带的应用商店Galaxy Apps中。

由于开发者疏忽,release版本的Galaxy Apps中存在如下遗留的调试代码:

【漏洞分析】如何用11个exp攻破三星S8_第3张图片

这段代码的作用是为了调试Galaxy Apps与升级服务器之间的连通性而去加载SD卡上的配置文件(/sdcard/saconfig.ini),为方便本地调试,配置文件中可以手动指定升级服务器地址,配置文件格式如下所示:


攻击者通过指定升级服务器地址,再加上中间人转发请求,可以让Galaxy Apps安装攻击者指定的任意App。一般我们在平时的审计中,可以写一个App去释放这个配置文件或是直接adb push配置文件到/sdcard中,但在Pwn2Own比赛环境下,是无法连接USB进行adb install的,有限的物理接触也仅能进行点击浏览器,打开url等操作。那么这里是如何生成或是释放这个关键的saconfig.ini文件的,以及如何通过浏览器发动这个远程攻击的,笔者就来根据slide大胆猜测一下攻击思路,一步步进行逆向探究。

在探究之前我们先要明确一点:起点入口是三星自带的浏览器SBrowser,最终目标是在Galaxy S8上执行攻击者的代码并窃取隐私文件。我们从整个利用链的最后一环入手来倒序分析,假定此时Galaxy Apps已经等着配置文件来进行下一步攻击了。

【漏洞分析】如何用11个exp攻破三星S8_第4张图片

Step 1 如何释放saconfig.ini配置文件?

由于代码中硬编码了配置文件路径(/sdcard/saconfig.ini),我们必须在指定目录下生成配置文件,那么该如何生成到指定目录?通过浏览器强制下载?显然不可,下载的文件位于Download目录内。这里利用了Samsung Notes中的一处Zip解压缩目录穿越漏洞。Samsung Notes中存在一处导出组件,可加载memo类型的文件,memo类型文件本质上是个zip压缩包,在Samsung Notes加载memo文件时会调用一个方法去解压这个memo文件,通过解压恶意构造的memo文件来准确释放文件到/sdcard下:

【漏洞分析】如何用11个exp攻破三星S8_第5张图片

存在漏洞的组件:com.samsung.android.app.notes.composer.ConvertToSdocActivity

【漏洞分析】如何用11个exp攻破三星S8_第6张图片

这里我们可以猜想memo文件的构成,其中有个文件的路径应该是这样的:”../../../../../../sdcard/saconfig.ini”,组合上面代码会产生路径“/data/data/com.samsung.android.app.notes/cache/unzip_1529565489/../../../../../../sdcard/saconfig.ini”,这样最终的路径就变成“/sdcard/saconfig.ini”了。

Step 2 如何让Samsung Notes打开memo文件?

如何打开特定App的特定activity?我们知道平时开发过程中直接使用Context.startActivity()即可,但在比赛环境下,并不能这样方便的执行代码,而且Samsumg Nots中存在问题的组件,并没有响应“android.intent.category.BROWSABLE”action,也无法通过浏览器打开。

所以安全人员这里找了一个跳板——Android Vending,也就是Google Play应用商店。在这个App中存在一个导出的Activity——LaunchUrlHandlerActivity,可接收外部传入的参数,并打开指定的应用,具体代码如下所示:

【漏洞分析】如何用11个exp攻破三星S8_第7张图片

并且这个Activity是响应“android.intent.category.BROWSABLE”的,意味着我们能通过浏览器利用其自定义协议进行调用。安全人员随后测试了http协议、file协议以及content协议,发现这里只能使用content协议,随后尝试了Chrome的Content Provider和系统Media Provider,最终确定了可行的URI:
market://details?url=content://media/external/file/350&id=com.samsung.android.app.notes

这样Android Vending会唤起com.samsung.android.app.notes并把content://media/external/file/{file_id}作为data传递给Samsung Notes。

Step 3 如何确定file_id?

Step 2中,我们看到URI中有一个content://media/external/file/{file_id},这个file_id是不确定的数字,代表的是memo文件在系统 Media Provider里对应的ID,至于如何确定,下面是MWR给出的一段JS代码:

【漏洞分析】如何用11个exp攻破三星S8_第8张图片

这段JS的意思是从id=300开始向下枚举Meida Provider中的文件,如果文件不存在的话就一直递减,直到出现一个存在的文件正确显示在页面上。

如下图示是上一个下载的文件payload.html: 

【漏洞分析】如何用11个exp攻破三星S8_第9张图片

先取得memo文件将占位的ID(这个时候memo文件还没下载呢),然后保证这个时候手机的外部储存里不会多出任何文件,因为任何文件的出现都会让ID变化。如果发现i=100的时候出现了payload.html页面,那么101就是memo文件将会存在的ID值。

Step 4 这段JS由谁执行?

MWR Labs安全人员指出:


由于三星自带的浏览器不支持content协议,所以这里需要用Chrome来加载payload.html,那么如何唤起Chrome?这里利用Chrome的特性即可:

googlechrome://navigate?url=content://com.android.chrome.FileProvider/downloads/payload.html

Step 5 payload.html从何而来?

三星浏览器SBrowser支持Content-Type: application/force-download; ,通过配置攻击者的Web服务器使其强制下载payload.html:


经过强制下载后,payload.html是保存在/sdcard/Download下的。巧合的是Chrome中的一个Content Provider指向路径即为/sdcard/Download,所以这里通过传入:
googlechrome://navigate?url=content://com.android.chrome.FileProvider/downloads/payload.html即可引导Chrome打开payload.html。

【漏洞分析】如何用11个exp攻破三星S8_第10张图片

小结

到这里暂时休息整理一下,我们从后往前看,就是从浏览器访问一个页面到释放配置文件的过程了。

结合官方给出的图示:【漏洞分析】如何用11个exp攻破三星S8_第11张图片

【漏洞分析】如何用11个exp攻破三星S8_第12张图片

【漏洞分析】如何用11个exp攻破三星S8_第13张图片

顺序就是:

  1. SBrowser访问index.html,index.html页面里也许使用