type
status
date
slug
summary
tags
category
icon
password
 
 
 

一、漏洞APP分析

 

1. AndroidManifest.xml

AndroidManifest 中声明了MainActivity。声明了VulProvider,而且该Provider为导出的 ,android:name="com.bytectf.golddroid.VulProvider" android:exported="true" android:authorities="slipme"FlagReceiver 用于设置flag
剩下的无需分析。
 

2. MainActivity

MainActivity 在外置数据目录中创建/sandbox/file1文件,并向其中写入内容,其绝对路径为/storage/emulated/0/Android/data/com.bytectf.golddroid/files/sandbox/file1
 

3. VulProvider

VulProvider 重写openFile ,使其使用外置数据目录的sandbox与uri.getLastPathSegment() 进行拼接得到路径,然后使用ParcelFileDescriptor.open(file, 268435456)读取文件,模式为只读。
在读取之前还需要通过!file.getCanonicalPath().startsWith(root.getCanonicalPath()) 进行校验,getCanonicalPath 就是取绝对路径的意思,根据Android官方的说明,getCanonicalPath 返回的地址是绝对且唯一的,该方法将会识别并剔除路径中的... ,最终得到绝对路径。校验原理就是获取file 的绝对路径,判断是否以sandbox 的绝对路径/storage/emulated/0/Android/data/com.bytectf.golddroid/files/sandbox开头 ,如果不是则抛出异常。
这里如果使用软链接,则会返回软链接指向的路径,这是本题的关键点。

二、攻击APP构造

 

1. 攻击方案

  • 首先想到可以通过路径穿越的方法读取flag,例如构造content://slipme/file1/../../../../../../../../../../../../../../../../../../../../data/data/com.bytectf.golddroid/files/flag 这样的uri,但是实际问题在于存在路径的校验,所以不能直接读取,除此之外还需要注意由于存在getLastPathSegment 所以需要到uri进行编码
  • 因此可以想到使用软链接的方法进行读取,可以通过在pwngolddroid的数据目录下创建软链接指向/data/data/com.bytectf.golddroid/files/flag ,然后进行读取,但是软链接同样无法通过校验,因为校验会直接拿到软链接指向的实际路径。但是通过观察发现虽然校验是获取了绝对路径,但是读取还是直接使用file进行读取,所以可以想到不断的切换创建的软链接指向的实际文件,进行条件竞争,直到flag被成功读取。
    • 编写pwngolddroid反复链接两个文件,利用条件竞争读取flag
      • 两个线程,其中一个不断改变symlink的指向,指向合法的files和非法的flag,另外一个不断请求provider读取symlink ,等待请求到flag开头的数据就通过http回传(真实环境不是flag开头,而是ByteCTF)
    ⚠️
    这里需要注意必须要捕获IllegalArgumentException e 异常,来处理校验不通过时的情况,否则抛出异常而不进行异常捕获,APP将会直接退出。
    ⚠️
    这里还需要注意,如果targetSdk设置为30及以上,需要在pwngolddroidManifest中添加provider的需求声明,否则无法访问provider ,如果设置为27进行编译,则不需要进行声明
    在创建应用时,请务必考虑您的应用需要与之交互的设备中的其他应用。如果您的应用以 Android 11(API 级别 30)或更高版本为目标平台,在默认情况下,系统会自动让部分应用对您的应用可见,但会过滤掉其他应用。本指南将介绍如何让上述其他应用对您的应用可见。
    如果您的应用以 Android 11 或更高版本为目标平台,并且需要与并非自动可见的应用交互,请在您应用的清单文件中添加 <queries> 元素。在 <queries> 元素中,按软件包名称按 intent 签名按提供程序授权指定其他应用,如以下部分所述。
    targetSdk 32
    notion image
    targetSdk 27
    notion image
    ⚠️
    目录权限问题:必须要给/data/data/com.bytectf.pwngolddroid 目录及以下文件777权限,创建完软链接后,还要给/data/data/com.bytectf.pwngolddroid/files 目录及以下文件777权限,否则可能会出现软链接无法读取或者绝对路径判断错误等问题。
     

    2. 攻击结果

    本地测试
    notion image
    notion image
     
    官方Docker环境
    notion image
    notion image
    ⚠️
    注意官方给的docker环境中flag不是以flag 开头的,因此需要改一下flag或者改pwngolddroid的源码
     

    三、总结

    • getLastPathSegment 路径穿越漏洞
    • getCanonicalPath 软链接处理特性
    • 条件竞争,通过getCanonicalPath 检测后再读取非法文件
     

    参考

    1. ‍‬⁡⁣⁤⁣⁣‌‬⁤⁡⁢‬⁣⁤⁤‬‬‌‬‌⁢⁢⁢‬‌⁤⁤⁡⁣⁢‌⁤‬ByteCTF 2022 官方writeup - 飞书云文档
    1. ByteCTF 2022 Android Writeup - wjh's blog
    1. 判断文件是否为软链接或硬链接_安卓文件软链接-CSDN博客
    1. [原创]ByteCTF2022 mobile系列-Android安全-看雪-安全社区|安全招聘|kanxue.com
    1. 声明软件包可见性需求  |  Android 开发者  |  Android Developers (google.cn)
    1. File  |  Android Developers
    ByteCTF2022 MITM复现ByteCTF2022 SilverDroid复现
    • Twikoo