梳理一些漏洞思路和案例,需要和《安卓开发》搭配着看
大多数内容来源于网络公开资源,侵删
漏洞之战:https://bbs.kanxue.com/thread-269211.htm
OVAA:https://oversecured.com/vulnerabilities
数据统计
统计时间范围:2020.1 - 2025.2
内容范围:google android framework and system
EoP:提权 RCE:远程代码执行
ID:信息泄露 DoS:拒绝服务
可以看到近5年批漏的漏洞分类比重大概是6:2:1:1
- EoP漏洞主要的话还是深度依赖于代码审计包括一些Fuzz之类的手段去挖掘。这个大比重也从侧面反映了近10年在Android安全研究中权限机制占比是非常之深的【可见S&P词云分析】
- ID漏洞挖掘以自动化工具主导,主要就是对于数据流的分析,近十年来创造的各种xxxdroid非常多,占比也会稍微高一点
- DoS更多的依赖于fuzz+人工验证,漏洞成因多是应用层组件(如
Activity
、BroadcastReceiver
)未校验输入导致崩溃,或内核资源耗尽(如触发OOM)等等。可以通过Fuzzing批量发现,但是一般不影响系统完整性,可能优先级就不会太高了 - RCE通常需绕过沙箱隔离(如浏览器引擎漏洞、媒体解析漏洞),结合EoP实现完全控制,价值大但是挖掘难度也大,再加上地址空间随机化、沙箱隔离等等安全机制相对少是正常的
常规漏洞点
Manifest.xml
- 常规检测点,漏扫都做了
1 | android:debuggable="true" //调试 |
Activity
- activity的利用通常会是整个利用链中比较关键的一环,例如通过启动未导出activity实现越权、扩展攻击面到整个app
LaunchAnyWhere
隐式Intent启动Activity
1 | <activity android:name=".SecondActivity"> |
- 不指出特定包特定Activity,可直接编写恶意Activity让受害app拉起
1 | Intent intent = Intent("com.example.test.ACTION_START"); |
Activity劫持
- 可以利用activity覆盖等手法窃取信息
- https://github.com/jussi-sky/UIhijack/tree/v1.0.0
PendingIntent的劫持重定向
参数设置非FLAG_IMMUTABLE
不过这种低级问题现在应该很少会有:(
详细介绍:AppWidget的风险分析与防护建议
敏感页面无防截屏
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
禁止截图:屏幕内容无法通过普通的截图功能捕获(如按键截图或屏幕录制)。
保护在最近任务中显示:在最近任务列表中,应用窗口内容会被隐藏或模糊,防止敏感信息泄露。
限制非安全显示设备:如果屏幕内容被投屏到外部设备(如智能电视或投影仪),则会阻止显示。
Content Provider
sql注入
- CVE-2021-41434
目录遍历
getAbsolutePath():获取绝对路径
Uri.getLastPathSegment():截取Uri中文件名
1 | private static String IMAGE_DIRECTORY = localFile.getAbsolutePath(); |
1 | private static String IMAGE_DIRECTORY = localFile.getAbsolutePath(); |
- CVE-2021-41256【FileProvider】
Broadcast Receiver
基于广播优先权的发送竞争
- 有序广播setPriority
粘滞广播导致信息泄露
- 粘滞广播在发送后会一直保持有效状态,允许后续注册的接收器在注册时立即接收到该广播的最后一个粘滞事件
- sendStickyBroadcast
广播无反注册
- 广播再利用
- 内存泄露UAF
1 | BroadcastReceiver broadcastReceiver=null; |
Fragment问题
信息泄露
敏感信息外部存储
1 | private String filename = "myfile"; |
- 合规处理(存入应用私有目录)
1 | private String filename = "myfile"; |
Log打印敏感信息(可使用ProGuard编写规则自动化删除特定日志)
1 | Log.d(): 用于打印调试信息。示例:Log.d(TAG, "Debug message"); |
数据缓存泄露
1 | 例如: |
1 | webView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT); |
合规处理
- clearCache()方法
- LOAD_NO_CACHE标记
ZIP路径穿越
- 当然不只是zip,所有可填写路径的地方不做过滤自然有可能绕过
1 | //可能利用../访问到其他非压缩包目录 |
- CVE-2018-1261 CVE-2018-8084 CVE-2018-10067 CVE-2018-5722
Webview
部分敏感行为
其实客观来讲这些操作被使用太正常了,全靠校验防护,白名单什么的
- setJavaScriptEnabled(True):允许执行JS代码
- setPluginState(True):启用Webview插件
- setAllowFileAccess(True):启用webview中的文件访问【默认true】
- setAllowContentAccess(True):启用webview中的内容URL访问【默认true】
- setAllowFileAccessFromFileURLs(True):允许webview中页面使用file协议访问本地文件
- setAllowUniversalAccessFromFileURLs(True):允许webview使用file协议访问外部资源
- setWebContentsDebuggingEnabled(true):允许调试
白名单校验对抗
URL无校验
1 | public class MyBrowser extends Activity { |
Intent Scheme URI 安全风险
1 | webView.setWebViewClient(new WebViewClient() { |
一些文章
Deeplink
deeplink作为一个启动组件的桥梁,主要的问题来源于deeplink的部分参数可控导致攻击面的暴露
- xss
- 结合webview loadurl
- 历史上pwn2own爆的洞很多
验证码/账密
- 这里就偏向web了
- 爆破
- 无限重放
- 修改response绕过检测机制
通信
网络通信
- MITM
- 信息泄露
- url校验
- 证书校验
- Crypto攻击,私钥泄露
进程通信
Handler内存泄露
原因
Handler一般作为Activity内部类,可以发送延迟执行的消息
在延迟阶段,把Activity关掉
Activity还被内部类Handler持有,导致Activity无法回收,造成内存泄露
防护
1.
Handler定义为静态内部类,持有Activity的弱引用。在Activity的onDestroy中调用handler.removeCallbacksAndMessages(null)及时移除所有消息
这一个方法在《Android开发》的代码中也有用到
2.
把Handler抽离作为BaseHandler,在Activity需要用Handler时extends BaseHandler
异常
- 这块儿大概有两大类吧 信息泄露 & 拒绝服务
- 异常提示本身就是一种信息,自然就存在信息泄露的可能。像
文件不存在
这种提示信息,只要有足够的时间 就有 理论的文件目录枚举爆破可能 - 另一方面如果有异常被遗漏,没有捕捉到,就会存在被拒绝服务的可能,轻则卡顿,重则闪退乃至利用异常扩展攻击面
- 异常提示本身就是一种信息,自然就存在信息泄露的可能。像
异常名称 | 可能导致的利用 |
---|---|
java.sql.SQLException | 数据库结构、用户名枚举 |
java.net .BindException | 客户端可以选择服务器端口时,枚举开放端口 |
java.util.ConcurrentModificationException(结构体被同时遍历时触发) | 可能提供有关线程不安全代码的信息 |
java.util.MissingResourceException | 资源枚举 |
java.lang.OutOfMemoryError | 拒绝服务 |
java.lang.StackOverflowError | 拒绝服务 |
java.io .FileNotFoundException | 文件系统结构、用户名枚举 |
javax.naming.InsufficientResourcesException | 服务器资源不足(可能有助于 DoS) |
零散
数据格式转换导致精度丢失、功能失效、触发异常等
1 | BigInteger x = new BigInteger("530500452766"); |
正则校验可绕过
1 | public static void FindLogEntry(String search) { |
native函数公开–>函数输入参数可控–>二进制攻击面
1 | public final class NativeMethod { |
数据公开可读可写权限
- MODE_WORLD_WRITABLE | MODE_WORLD_READABLE
1 | openFileOutput("someFile", MODE_WORLD_READABLE); |
Janus签名漏洞
- 前提是有v1签名无v2签名,就不展开了
CVE/顶会/Blackhat
Deeplink、webview
One-click Open-redirect to own Samsung S22 at Pwn2Own 2022
- The Old, The New and The Bypass - One-click/Open-redirect to own Samsung S22 at Pwn2Own 2022 | STAR Labs
- deeplink–>xss –> webview loadurl –> js任意代码执行
Binder通信
- 【“移动互联网安全”论坛回顾】向小波:安卓系统服务中的Binder事务重定向攻击
- CVE-2025-0099:7946586c33503bc383403faec48ffcea39e365ac - platform/frameworks/base - Git at Google
parcel序列化问题
- LaunchAnyWhere 补丁绕过:Android Bundle Mismatch 系列漏洞 复现与分析 | Clang裁缝店
- 再谈Parcelable反序列化漏洞和Bundle mismatch – 小路的博客
权限机制问题
BlackHat EU 2021:PendingIntent重定向
DOS
零散
DirtyStream
CVE-2024-0015【DayDream】
- [原创]CVE-2024-0015复现 (DubheCTF DayDream)-Android安全-看雪-安全社区|安全招聘|kanxue.com
- one-click,自定义屏保功能的校验功能不够
- 通过继承DreamService类自定义屏保,在manifest的service参数里设置想启动的activity
- 当用户选择自定义屏保时造成任意activity启动,用户无感
CVE-2015-3878【屏幕录制UI欺骗】
- 屏幕录制用户请求代码没有做显示的文字长度限制,可以伪造信息不显示屏幕录制的相关提示,欺诈用户实现录屏
- 类似还有CVE-2018-9432、CVE-2017-13242。基本都是显示的页面元素长度可控,利用各种换行、替换等操作隐藏真实目的的显示
小米
敏感API
C
1 | gets |
Java/Smail
1 | # serresult劫持intent |