漏洞利用简析——如何用11个exp攻破三星S8

阅读量    414064 | 评论 6

分享到: QQ空间 新浪微博 微信 QQ facebook twitter

Author:  Sniperhg@Vulpecker Team 、MissCoconut@Vulpecker Team

前言

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

 

初探

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

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

这段代码的作用是为了调试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已经等着配置文件来进行下一步攻击了。

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

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

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

这里我们可以猜想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,可接收外部传入的参数,并打开指定的应用,具体代码如下所示:

并且这个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代码:

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

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

先取得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。

小结

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

结合官方给出的图示:

顺序就是:

  1. SBrowser访问index.html,index.html页面里也许使用<iframe>嵌入了一个payload.html,这个时候利用force-download特性将payload.html下载到手机里再利用googlechrome://navigate?url=content://com.android.chrome.FileProvider/downloads/payload.html唤起Chrome并加载payload.html;
  2. 在payload.html中我们枚举出memo文件占位ID,接着请求下载了memo文件,再跳转market://details?url=content://media/external/file/350&id=com.samsung.android.app.notes唤起了Android Vending;
  3. Android Vending被唤起后发送Intent继而唤醒Samsung Notes访问memo文件进行解压缩释放了配置文件saconfig.ini。

 

进一步利用

Step 6 如何突破比赛时间限制?

进行到这里我们已经有了这个配置文件,虽然配置文件能控制Galaxy Apps的行为去劫持下载,但是由于其使用的是Android Job Scheduler,Scheduler的执行间隔是15分钟,而比赛的规则是每次尝试只有5分钟时间,所以这里碰到了一个限制需要突破:如何让Scheduler快速执行?

由于Galaxy Apps在启动时会去加载这个配置文件,这里想到了让Galaxy Apps重启。由于Galaxy Apps是系统应用,会在系统启动时自启动,那么这里面临着两个选择,是选择crash掉一个App还是crash system引起手机重启?MWR Labs选择了后者。

Step 7 如何重启系统?

在这一步的攻击中,利用了系统进程“com.android.server.telecom”中的组件“com.android.server.telecom.components.UserCallActivity”中存在一处隐藏的空指针异常未捕获的问题:

如果外部直接启动这个Activity不带任何data进来,URI将会为null,null传给getScheme()方法时就会产生空指针异常,系统进程的崩溃意味着系统的崩溃,这个时候手机就会重启,由于Galaxy Apps会在系统启动时自启动,那么重启手机之后,Galaxy App也会重新启动并加载我们的配置文件。

Step 8 如何发送特定Intent?

如何能发送这样一个Intent呢,一个只带包名和组件名,不会填充data数据的Intent?这里利用了另外一个跳板——Samsung Members:

Samsung Members中的导出组件LauncherActivity可在浏览器中使用其自定义协议voc://唤起,并且可传入特定的包名和组件名。

Step 9 如何唤醒Samsung Members?

在这一步中,依旧利用Chrome来进行跳转,“voc://activity/general?packageName=com.android.server.telecom&className=com.android.server.telecom.components.UserCallActivity”,这个URI会被Samsung Members所接收到。所以Chrome在整个攻击链中要执行2次打开其他应用的任务,一次是为了唤起Android Vending跳板,另外一次是为了唤醒Samsung Members跳板。这里我们能注意到被当作跳板的组件的一个共同点:都响应了“android.intent.category.browsable”Action,导致攻击者可以通过浏览器打开进行远程利用,这里对我们来说算是一个小Tips吧,今后的漏洞挖掘工作中,对可通过浏览器打开的组件需要格外关注。

后续利用

Step 10 中间人劫持App更新

Galaxy Apps启动后加载配置文件,这个时候就会去请求这个攻击者的中间地址,攻击者再将所有的请求转发给真正的升级服务器https://uk-odc.samsungapps.com/,同时也会将服务器的响应返回给手机。

Galaxy Apps进行更新请求时会与服务器产生三次交互:

  1. 客户端发送当前所有的App列表给服务器/服务端做出响应告知客户端所有App的最新版本
  2. 客户端如果发现版本比自己高的App则请求这个App的最新信息/服务端返回App的包名版本等信息
  3. 客户端请求最新App的下载地址等/服务器返回下载地址以及App大小签名等信息

中间人在这里修改了1次请求和3次返回的包,让Galaxy Apps误以为自己手机上的某个App是旧版本的,然后下载了攻击者执行的App进行了安装。

Step 11 如何绕过权限申请弹窗?

在Android 6.0及后续版本中,App申请危险权限时,系统会弹出对话框询问用户是否授予其特定权限,这里绕过的方式也很简单,编译apk时将targetSdkVersion设置为18及以下即可。

Step 12 如何启动恶意App?

根据slide中的描述,MWR的研究人员也以为到这里就够了,恶意App已经成功安装,还有什么不能做的呢?但是ZDI却要求现场就能运行App并进行敏感数据的窃取等操作。所以这里就涉及到一个问题:Android 3.1以后,新安装的App默认都是停止状态的。

接着研究人员发现,三星对Android Contacts Provider进行了重度修改,在一个App的状态发生改变时,会有一个方法去做一次query查询:

所以在恶意App里创建一个provider,meta-data中写上android.content.ContactDirectory属性为true,则可以在安装上之后,执行provider中的query方法。

到此为止,恶意App成功安装并启动。

 

总结

经过对整个攻击链的分析,将这么多“不起眼”的逻辑漏洞(或bug)利用起来,居然能从浏览器到代码执行做远程攻击。在这个攻击链中,总共涉及到了6个App、3个系统组件以及系统的总共11个逻辑漏洞(或bug甚至只是特性),我们再来回顾一下:

组件 作用
三星SBrowser 支持强制下载,保存了payload.html
Chrome 支持googlechrome://协议,加载payload.html文件
Android Vending

(Play Store)

跳板1,可被浏览器用scheme唤醒并发送Intent
Android Media Provider 系统特性,通过id能访问到相应的文件
Samsung Notes 解压缩目录穿越漏洞,为释放配置文件提供了便利
Samsung Members 跳板2,同样可被浏览器用scheme唤醒并发送Intent
Android Telecom 空指针异常,可被利用来重启系统
Galaxy Apps 遗留调试代码,可指定任意服务器调试App的升级更新过程;且存在中间人攻击风险
三星定制Android Contacts Provider App更新时会去执行query方法导致恶意App自启动
系统特性 通过设置targetSdkVersion绕过权限弹框

 

参考链接

  1. https://labs.mwrinfosecurity.com/publications/chainspotting-building-exploit-chains-with-logic-bugs/
  2. https://www.zerodayinitiative.com/advisories/ZDI-18-562/
  3. https://www.zerodayinitiative.com/advisories/ZDI-18-561/
  4. https://www.zerodayinitiative.com/advisories/ZDI-18-560/

 

关于Vulpecker Team

360威派克团队(Vulpecker Team)隶属于360信息安全部,负责集团内部移动APP和OS类产品安全攻防, 制定了公司内部安卓产品安全开发规范,自主开发并维护了在线安卓应用安全审计系统-360显危镜。同时团队高度活跃在谷歌、三星、华为等各大手机厂商的致谢名单中,截止2018年,累计获得近百个CVE编号和官方致谢,多次在国内外各大安全会议上分享研究成果。

分享到: QQ空间 新浪微博 微信 QQ facebook twitter
|推荐阅读
|发表评论
|评论列表
加载更多