目录
  1. 1. 一、导出组件漏洞
    1. 1.1. Activity 劫持
    2. 1.2. Service 劫持
    3. 1.3. BroadcastReceiver 劫持
  2. 2. 二、WebView 远程代码执行
  3. 3. 三、不安全的文件存储
  4. 4. 四、ContentProvider SQL 注入
  5. 5. 五、Logcat 信息泄露
  6. 6. 六、Intent 注入与 Sniffing
  7. 7. 面试常考问题
【逆向安全技术-实战篇】常见应用漏洞分析

一、导出组件漏洞

Android 四大组件(Activity、Service、BroadcastReceiver、ContentProvider)若设置 android:exported="true" 且未做权限保护,可能被第三方应用恶意调用。

Activity 劫持

// 恶意应用直接启动目标应用的导出 Activity
Intent intent = new Intent();
intent.setClassName("com.victim.app", "com.victim.app.SecretActivity");
intent.putExtra("token", "attacker_controlled_value");
startActivity(intent);

修复:设置 android:exported="false" 或添加 android:permission 保护。

Service 劫持

导出 Service 可直接绑定并调用其方法:

Intent intent = new Intent();
intent.setClassName("com.victim.app", "com.victim.app.SensitiveService");
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);

BroadcastReceiver 劫持

// 发送伪造广播,触发内置逻辑
Intent intent = new Intent();
intent.setAction("com.victim.app.ACTION_SEND_SMS");
intent.putExtra("phone", "5551234567");
intent.putExtra("message", "malicious");
sendBroadcast(intent);

二、WebView 远程代码执行

Android API 16 及以下,使用 addJavascriptInterface 存在严重 RCE 漏洞:

// 危险代码:JS 可反射调用 Java 对象的方法
webView.addJavascriptInterface(new JSInterface(), "Android");

恶意网页可执行:

// 通过反射执行系统命令
Android.getClass().forName("java.lang.Runtime")
.getMethod("getRuntime").invoke(null)
.exec("rm -rf /data/data/com.victim.app/*");

修复方案:

  • targetSdkVersion 提高到 17+,使用 @JavascriptInterface 注解限制
  • 避免在 WebView 中暴露敏感 Java 对象
  • 使用 WebView 安全配置:setAllowFileAccess(false)

三、不安全的文件存储

// 危险:明文存储密码
SharedPreferences sp = getSharedPreferences("config", MODE_WORLD_READABLE);
sp.edit().putString("password", "admin123").apply();

// 危险:敏感数据存储在外部存储
FileOutputStream fos = new FileOutputStream(
Environment.getExternalStorageDirectory() + "/secrets.txt");

修复:使用 MODE_PRIVATE + 加密存储,敏感文件放 /data/data/ 内部目录。

四、ContentProvider SQL 注入

// ContentProvider query 实现中存在拼接 SQL
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteDatabase db = mDbHelper.getReadableDatabase();
// 危险:selectionArgs 参数未被正确使用,拼接了 selection
String sql = "SELECT * FROM users WHERE name = '" + selection + "'";
return db.rawQuery(sql, null);
}

攻击者构造 selection = "admin' OR '1'='1" 实现注入,获取全表数据。

五、Logcat 信息泄露

// 敏感信息写入日志
Log.d("LoginActivity", "User login: " + username + ":" + password);
Log.e("Payment", "Card number: " + cardNum);

检查命令:

adb logcat | grep -iE "password|token|secret|apikey|card"

六、Intent 注入与 Sniffing

// 敏感数据通过隐式 Intent 传递
Intent intent = new Intent("com.victim.app.RESULT");
intent.putExtra("auth_token", tokenString);
sendBroadcast(intent); // 任何应用都可以接收!

使用 setPackage() 限定接收者,或使用 LocalBroadcastManager

面试常考问题

Q1:如何快速判断一个应用是否存在导出组件漏洞?
A:使用 drozerhttps://github.com/WithSecureLabs/drozer)扫描应用的攻击面:`run app.package.attacksurface com.target.app。它可以列出所有导出组件、可读取 ContentProvider URI、可调用的 Service 等。也可用 aapt dump xmltree target.apk AndroidManifest.xml | grep exported` 手动检查。

Q2:WebView 安全除了 addJavascriptInterface 还有哪些常见问题?
A:(1)setAllowFileAccess(true) 允许 WebView 通过 file:// 协议访问本地文件;(2)SSL 错误处理不当,onReceivedSslError 中直接 handler.proceed();(3)未验证 URL,导致 URL 跳转劫持;(4)WebView 中泄露 Cookie 或 Session 信息。

Q3:ContentProvider 的 SQL 注入和 Web SQL 注入有什么异同?
A:原理相同,都是通过未经过滤的用户输入拼接 SQL 语句。不同点在于攻击入口:Web SQL 注入通过 HTTP 参数传入,ContentProvider SQL 注入通过其他应用构造的 ContentResolver 调用传入。防御方式也类似:使用参数化查询(selectionArgs),对输入做严格校验。

打赏
  • 微信
  • 支付宝

评论