LaunchAnyWhere学习笔记
这是一个
AccountManagerService
的漏洞,利用这个漏洞,我们可以任意调起任意未导出的Activity,突破进程间组件访问隔离的限制。
1 AccountManagerService
The steps we’ll performs to get this done:
- Creating our Authenticator - the brain behind this operation
- Creating the Activities - in those the user will enter his credentials
- Creating the Service - through it we can communicate with the authenticator
AccountManagerService同样也是系统服务之一,暴露给开发者的的接口是AccountManager。该服务用于管理用户各种网络账号。
当我们在调用addAcount
方法时会发生以下调用:
上图是Android
处理身份认证的过程
假设AppA
是setting
,有AppB
提供了账号授权功能。
当我们在setting中点击添加账户的时候
setting
调用AccountManager.addAccount()
方法- 产生系统调用,在
system_server
层调用addAccount
方法 - AccountManager会去查找提供账号的应用
AppB
的Authentctor
类 - 调用
Authentctor.addAccount
方法,返回一个Intent
- 系统将
Intent
转发给setting
AccountManagerResponse
在AppA
的进程空间内调用startActivity(intent)
调起一个Activity
。而AppA
对此并不知情。
如果第四步代码如下:
1 | // 添加账户 |
而在第六步的时后有:
1 | /** Handles the responses from the AccountManager */ |
那么当我们在setting
中点击添加账户的时候就会自启动ChooseLockPassword
2 利用
如果假设
AppA
是Settings
,AppB
是攻击程序。那么只要能让Settings
触发addAcount
的操作,就能够让AppB
launchAnyWhere
。而问题是,怎么才能让Settings触发添加账户呢?如果从“设置->添加账户”的页面去触发,则需要用户手工点击才能触发,这样攻击的成功率将大大降低,因为一般用户是很少从这里添加账户的,用户往往习惯直接从应用本身登陆。
其实Settings早已经给我们留下触发接口。只要我们调用
com.android.settings.accounts.AddAccountSettings
,并给Intent带上特定的参数,即可让Settings触发launchAnyWhere
:
1 | Intent intent1 = new Intent(); |
3 应用场景
3.1 重置pin码
1 | intent.setComponent(new ComponentName( |
3.2 调用微信内置浏览器:
1 | public final static String HTML2 = |
3.3 调用支付宝钱包内置浏览器
1 | Intent intent = new Intent(); |
4 修复
在
Response
的onResult
方法中添加了检查返回的intent所指向的Activity和AppB是否有相同签名的方法
1 |
|
5 修复后测试
1 | 2020-04-12 15:08:49.957 1451-1731/system_process I/ActivityManager: START u0 {flg=0x8000 cmp=com.android.settings/.Settings$AccountSettingsActivity (has extras)} from uid 1000 on display 0 |