Skip to content
Conduit

skill

android-pentest-ai

AI-powered Android penetration testing skill. Static analysis, Frida bypass generation, OWASP MASVS v2.1.0 mapping. Works with any agent that reads AGENTS.md.

Balzabu/android-pentest-aicommunitylistedunreviewed

Set up

Skills are installed by placing their folder where your agent loads skills.

The download comes from github.com/Balzabu/android-pentest-ai itself, not from our server, so what you get is exactly what its author published.

Install instructions come from the README

Skills do not use an MCP config. Follow the steps in the README below.

README

synced Oct 25, 2026

Android PT Skill

An AI-assisted Android penetration testing skill that works with Claude Code, OpenCode, and Codex.

It covers the VA/PT lifecycle from static analysis through dynamic analysis with Frida to security bypass techniques, with all findings mapped to OWASP MASVS v2.1.0.

What it does

Decompiles APK/XAPK files with jadx + apktool and detects cross-platform frameworks (Flutter, React Native, Xamarin, Unity). Parses the AndroidManifest and the Network Security Config rather than grepping them, so implicitly exported components, the actual strength of each permission guard, the SDK baseline, cleartext allowances and trust anchors are read from structure. Analyzes Java/Kotlin code patterns, hardcoded secrets, and crypto implementations. Identifies protection mechanisms like root detection, SSL pinning, Play Integrity, anti-debug, and anti-hooking. Audits how the APK was signed, which decompiled output cannot show: v1-only signing (Janus, CVE-2017-13156), an Android debug certificate, a deprecated algorithm or a short key. Reviews native .so binary hardening (NX, RELRO, stack canary, FORTIFY) and fingerprints packers and obfuscators with APKiD when installed. Findings map to OWASP MASVS v2.1.0. Only independently validated findings affect the optional 0-100 triage score; scanner candidates remain separate.

Optional external analyzers APKiD, apkleaks, mobsfscan, semgrep, and readelf integrations run when present. Nuclei is detected as an analyst-led active-testing tool but is never launched automatically. The scripts also work without optional analyzers.

Generates Frida scripts based on actual code analysis, not generic templates. Compatible with Frida 17.x and Android 15/16. Tests for WebView exploitation, intent redirection, PendingIntent hijacking, Content Provider injection, tapjacking, and deep link hijacking. Includes mitmproxy/Burp Suite integration guidance for traffic interception.

Requirements

Required

  • Bash 4.0+ (macOS ships 3.2: brew install bash. check-deps.sh reports the version it is running under)
  • Java JDK 17+
  • Python 3.10+ (manifest audit, finding normalization, coverage analysis, triage, reports, and corpus verification)
  • jadx (DEX to Java decompiler)
  • apktool (APK resource decoder)
  • ADB (Android Debug Bridge)
  • curl (Firebase configuration and optional validation workflow)

Recommended

  • Frida 17.6+ + frida-tools (dynamic instrumentation)
  • objection (runtime exploration)
  • mitmproxy (traffic interception)
  • Ghidra (native code reverse engineering)
  • uber-apk-signer (APK signing for repackaging)
  • binutils (readelf) for native .so hardening checks (usually preinstalled)

Optional analyzers

Used when present, and the scripts run without them. check-deps.sh reports which are installed.

  • APKiD (pipx install apkid): packer, obfuscator, and anti-analysis fingerprinting, run during decompilation
  • apkleaks (pipx install apkleaks): curated secret and endpoint corpus over the APK
  • mobsfscan (pipx install mobsfscan): MobSF static rules (AST and dataflow)
  • semgrep (pipx install semgrep): set SEMGREP_RULES (e.g. p/mobsfscan) to enable
  • nuclei: detected for explicitly authorized, analyst-led endpoint validation; it is not run by full-scan.sh

Installation

Clone the repo and open it with your AI tool. Instructions and commands load automatically.

git clone https://github.com/Balzabu/android-pentest-ai.git
cd android-pentest-ai

What each tool loads

AGENTS.md holds every instruction that is not specific to one tool: the methodology pointer, the reference list, the script inventory and the operating rules. It is read natively by a long list of coding agents, so most tools need no per-tool file at all. CLAUDE.md imports it with @AGENTS.md and adds only the Claude Code slash commands, which keeps one source of truth rather than two copies that drift.

ToolInstructionsCommands
Claude CodeCLAUDE.md (imports AGENTS.md).claude/commands/*.md → /scan, /decompile, …
OpenCodeAGENTS.md.opencode/commands/*.md → /scan, /decompile, …
OpenAI CodexAGENTS.md + .agents/skills/android-pt/Skill selected by description match, or $android-pt
Cursor, Gemini CLI, GitHub Copilot, Windsurf, Aider, Zed, Amp, Jules, Devin, Amazon Q, JetBrains Junie, Warp and othersAGENTS.mdUse the tool-neutral prompts in android-pt/commands/

Claude Code and OpenCode get the same ten commands: /scan, /decompile, /check-deps, /find-secrets, /vuln-scan, /frida-targets, /frida-session, /frida-bypass, /report, /firebase-scan, /signature-scan, /protection-map, /native-scan, /extract-endpoints, /triage-finding. The same prompts exist tool-neutrally in android-pt/commands/, and tests/docs.py fails the build if the three sets diverge.

Installing into an existing project

Copy android-pt/ into your project, then add the instruction file. AGENTS.md alone is enough for every tool that reads it:

cp -r android-pt/ /your/project/android-pt/
cp AGENTS.md /your/project/

# Claude Code: CLAUDE.md imports AGENTS.md, so copy both
cp CLAUDE.md /your/project/ && cp -r .claude/ /your/project/.claude/

# OpenCode slash commands
cp -r .opencode/ /your/project/.opencode/

# Codex repository skill
cp -r .agents/ /your/project/.agents/

In a project that is not primarily an Android assessment, consider moving the content into a skill (.claude/skills/android-pt/SKILL.md for Claude Code, .agents/skills/ for Codex) instead of an always-on instruction file, so it loads only when the work calls for it rather than on every request.

Project structure

android-pt-skill/
├── android-pt/                            # Core skill
│   ├── SKILL.md                           # 5-phase methodology (OWASP MASVS v2.1.0)
│   ├── commands/                          # Universal command prompts (any tool)
│   │   ├── scan.md
│   │   ├── decompile.md
│   │   ├── check-deps.md
│   │   ├── find-secrets.md
│   │   ├── vuln-scan.md
│   │   ├── frida-targets.md
│   │   ├── frida-session.md
│   │   ├── frida-bypass.md
│   │   ├── report.md
│   │   └── firebase-scan.md
│   ├── references/
│   │   ├── static-analysis.md
│   │   ├── protection-detection.md
│   │   ├── dynamic-analysis.md
│   │   ├── bypass-techniques.md
│   │   ├── native-analysis.md
│   │   ├── cross-framework.md
│   │   ├── owasp-mastg-map.md
│   │   ├── finding-validation.md
│   │   └── llm-analysis.md
│   ├── scripts/
│       ├── full-scan.sh
│       ├── check-deps.sh
│       ├── decompile.sh
│       ├── find-secrets.sh
│       ├── extract-endpoints.sh
│       ├── vuln-scan.sh
│       ├── protection-map.sh
│       ├── native-scan.sh
│       ├── signature-scan.sh
│       ├── frida-targets.sh
│       ├── frida-session.sh
│       ├── firebase-scan.sh
│       ├── supplementary-scan.sh
│       ├── normalize-findings.sh
│       ├── triage-finding.sh
│       └── generate-report.sh
│   └── schemas/
│       └── finding.schema.json
│
├── .agents/skills/android-pt/             # Agent Skills standard (Codex)
│   └── SKILL.md
├── .claude/commands/                      # Claude Code slash commands
├── .opencode/commands/                    # OpenCode slash commands
│
├── CLAUDE.md                              # Claude Code instructions
├── AGENTS.md                              # OpenCode + Codex instructions
├── tests/                                 # Dependency-free regression suite + Bats adapter
├── .github/workflows/ci.yml               # Ubuntu/macOS syntax, ShellCheck, tests
└── README.md

Usage

Natural language (any AI CLI)

  • "Decompile this APK and find security issues"
  • "Analyze the root detection in this app and generate a bypass"
  • "Create a Frida script to bypass SSL pinning for com.example.app"
  • "Run a full OWASP MASVS assessment on this APK"
  • "What protection mechanisms does this app use?"

Full automated scan

bash android-pt/scripts/full-scan.sh --deobf --install-deps target.apk

This runs the static assessment pipeline: dependency check, decompilation, secret scanning, endpoint extraction, Firebase scanning, vulnerability scanning, native library hardening review, protection mapping, Frida target discovery, report generation, and (when installed) optional external analyzers.

The scan also creates analysis-queue.json (source-linked review tasks and strategic reviews for exported components and auth/session code) and attack-chains.json/.md (potential combinations of findings, with missing proof stated explicitly). A chain is never automatically considered exploitable because two detections occur in the same file. The analyst or AI assistant must verify the complete input-to-impact path before reporting it as a finding.

Record a reviewed chain with:

python3 android-pt/scripts/lib/triage_chain.py <scan-dir> \
  --id <CHAIN-ID> --status validated_static \
  --rationale "Reviewed complete entry-to-sink path" \
  --evidence <file:line-or-artifact>

Other statuses are validated_dynamic, needs_dynamic, and rejected. Static validation records a reviewed code path; only dynamic validation marks observed impact. Regenerate the report afterward.

Pattern scanners default to the detected first-party package while retaining manifests and resources in scope. Pass --all-code when a deliberate third-party dependency review is required.

It does not generate Frida scripts automatically. Frida and bypass generation remain explicit user-triggered workflows.

WSL users: Scripts auto-detect WSL and copy the APK to the native Linux filesystem (/tmp/) for ~10x faster I/O when the source is on /mnt/c/ or /mnt/d/. Results are copied back automatically.

Individual scripts

bash android-pt/scripts/check-deps.sh --install
bash android-pt/scripts/decompile.sh --deobf target.apk
# Point find-secrets at jadx-output (not just sources/) so secrets in resources like
# res/values/strings.xml are covered.
bash android-pt/scripts/find-secrets.sh ./decompiled-target/jadx-output/ --output ./findings/
bash android-pt/scripts/extract-endpoints.sh ./decompiled-target/ --output ./scan-output/
bash android-pt/scripts/vuln-scan.sh ./decompiled-target/ --output ./findings/
bash android-pt/scripts/protection-map.sh ./decompiled-target/ --output ./scan-output/
bash android-pt/scripts/native-scan.sh ./decompiled-target/ --output ./findings/
bash android-pt/scripts/signature-scan.sh target.apk --output ./findings/ --scan-dir ./decompiled-target/
bash android-pt/scripts/frida-targets.sh ./decompiled-target/ --output ./scan-output/
bash android-pt/scripts/frida-session.sh --confirm-active-testing --package com.example.app --spawn --script ./targeted-hook.js
bash android-pt/scripts/firebase-scan.sh ./decompiled-target/ --output ./findings/ --confirm-active-testing
# Temporary write/upload probes require a second explicit authorization flag:
bash android-pt/scripts/firebase-scan.sh ./decompiled-target/ --output ./findings/ --confirm-active-testing --allow-write-probes
bash android-pt/scripts/supplementary-scan.sh ./decompiled-target/ --apk target.apk --output ./scan-output/
bash android-pt/scripts/normalize-findings.sh ./findings/
bash android-pt/scripts/triage-finding.sh ./findings/ --id APT-... --status validated --confidence LIKELY --rationale "Reachable call chain verified in class X"
bash android-pt/scripts/generate-report.sh ./findings/ --output report.md

On platforms where jadx or apktool must be downloaded directly, automatic installation requires JADX_SHA256 or APKTOOL_SHA256 respectively. The installer uses HTTPS, validates the archive structure, and refuses installation when the expected release checksum is absent or mismatched. Package-manager installations do not need these variables.

Finding lifecycle

Scanner output is treated as candidate evidence, not as a confirmed vulnerability. This remains true even when a detector writes Confidence: CONFIRMED: scanner certainty is evidence metadata and cannot substitute for the independent validation pass. normalize-findings.sh creates a canonical findings-index.json, assigns stable IDs, deduplicates equivalent records, and maps legacy scanner certainty labels conservatively. The canonical confidence classes are CONFIRMED, LIKELY, NEEDS_DYNAMIC_CONFIRMATION, and INFORMATIONAL. Only triage-finding.sh can promote a candidate to validated; it records the analyst decision and required rationale in validation-overrides.json, and these decisions survive later normalization runs. Optional --severity, --maswe, and --mastg-test flags record analyst-reviewed impact and verified OWASP IDs; repeat --evidence to link source lines or runtime artifacts. None are inferred from keyword hits.

generate-report.sh scores only records whose validation status is validated. Use --include-candidates to embed pending candidates and observations in the report without allowing them to influence risk counts or the score. A report with no validated finding displays an N/A score rather than implying that the application is secure.

Every full scan also writes decompilation-coverage.json and .md. These artifacts retain JADX/apktool logs, count unreconstructed methods, and separate markers under the detected application package from markers outside that prefix. Package scoping is diagnostic rather than proof of code ownership: applications may place first-party code under additional namespaces, so PARTIAL remains conservative whenever a decompiler reports failures.

Manifest and Network Security Config audit

vuln-scan.sh runs lib/manifest_audit.py over the decoded AndroidManifest.xml and the Network Security Config it references. Attribute matching cannot answer these questions, so the module parses the XML instead:

  • Implicitly exported components: a component with an <intent-filter> and no android:exported attribute is exported by the platform below targetSdk 31. Counting android:exported="true" never reports these.
  • Guard strength, not export count: an export that an android:permission guards is separated from one that nothing guards, and a custom permission declared protectionLevel="normal" (the default when the attribute is omitted) is reported as no guard at all, because the system grants it to any app without user interaction.
  • SDK baseline from both sources: apktool moves <uses-sdk> into apktool.yml, so the audit reads both. targetSdkVersion is compared against the current Google Play floor and minSdkVersion against the API levels where the Network Security Config starts being honoured (24) and cleartext starts being denied by default (28).
  • Network Security Config contents: cleartextTrafficPermitted="true" per domain and <certificates src="user"/> trust anchors. Settings inside <debug-overrides> are recorded as observations, not as release-build weaknesses, because the platform applies them only to debuggable builds.
  • android:sharedUserId and providers with android:grantUriPermissions="true".

Precision is treated as part of correctness: the launcher activity, components explicitly set to android:exported="false", receivers filtering only system-protected broadcasts, and exports guarded by a signature-level permission are excluded from the exposed surface rather than padding it. Every record is still a candidate that the validation pass must confirm.

When python3 is unavailable the audit is skipped with a notice and the scan falls back to the older attribute matching, which is less precise in both directions.

protection-map.sh distinguishes strong pinning indicators (for example OkHttp CertificatePinner, TrustKit, or XML pin sets) from generic custom TLS trust handling. A custom X509TrustManager, HostnameVerifier, or network security configuration is recorded as Custom TLS Trust Handling (Review Required) until source review proves whether it enforces pinning or weakens certificate validation. Generic digest, Signature annotation, Base64, and ClassLoader usage are likewise not treated as proof of anti-tampering or obfuscation.

Firebase configuration discovery stays inside the supplied assessment target (with only the safe sources/resources to JADX-parent expansion). Firebase HTTP validation is read-only with --confirm-active-testing. Mutating database, storage, and anonymous-account probes additionally require --allow-write-probes; failed cleanup is recorded in cleanup-required.tsv.

Run the dependency-free regression suite with bash tests/run.sh, or through Bats with bats tests/findings.bats. CI runs both, plus Bash syntax checks, ShellCheck, ruff check over the Python pipeline (configured in ruff.toml to select defect rules only), and python3 tests/analysis.py, on Ubuntu and macOS.

Benchmark corpus

tests/corpus/expectations.json records a curated set of statically observable signals from PIVAA, InsecureShop, and AndroGoat. After scanning locally obtained official APKs, compare artifacts with:

python3 tests/corpus/verify.py \
  --scan PIVAA=/path/to/scan-PIVAA-* \
  --scan InsecureShop=/path/to/scan-InsecureShop-* \
  --scan AndroGoat=/path/to/scan-AndroGoat-* \
  --output corpus-report.json

The resulting percentage covers only the explicitly modeled static signals, not every vulnerability documented by each training app. Runtime-only flaws, backend authorization, exploitability, and findings hidden by decompilation errors still require independent manual or dynamic validation.

Methodology

The assessment has five phases, aligned to OWASP MASVS v2.1.0:

  1. Reconnaissance and static analysis. Decompile, detect framework, review manifest, audit code.
  2. Security mechanism identification. Map root detection, verified pinning indicators, custom TLS review surfaces, Play Integrity, and anti-debug controls.
  3. Dynamic analysis and instrumentation. Custom Frida hooks and traffic interception, only when explicitly requested.
  4. Bypass and exploitation. Demonstrate impact: SSL bypass, root bypass, WebView exploitation, intent attacks.
  5. Findings and evidence collection. MASVS-mapped report with remediation.

Frida script generation

No pre-built Frida scripts are included. The skill generates scripts from actual code analysis only when the user explicitly asks for dynamic work:

  1. Decompile the target APK
  2. Identify the exact protection implementation (class, method, signature)
  3. Understand the call chain and logic
  4. Generate a targeted Frida script with inline documentation
  5. Include verification logic

A script that hooks com.target.security.PinningManager.validateCertChain() is better evidence than a generic bypass. It also breaks less often, because it targets the actual implementation rather than guessing at method names.

frida-targets.sh can be used before script generation to identify candidate classes and source-linked hook_sites from decompiled code. These are static hints, not verified runtime signatures, and the script does not generate bypasses. frida-session.sh runs only with --confirm-active-testing and stores runtime evidence under dynamic-evidence/.

For an observation-first hook derived from an actual source file:

python3 android-pt/scripts/lib/frida_observe.py \
  --source ./scan-app/decompiled/jadx-output/sources/com/example/Check.java \
  --class com.example.Check --method isRooted \
  --output ./scan-app/hooks/observe-root.js
bash android-pt/scripts/frida-session.sh --confirm-active-testing \
  --package com.example.app --script ./scan-app/hooks/observe-root.js

Add --arg-type once per argument, in order, if the method has multiple overloads. The generated script reports APT_EVENT readiness and invocation without logging arguments or changing the return value. frida-session.sh saves a structured hook-events.json; a hook hit establishes execution, not a vulnerability or bypass. Frida sessions require an available test device and separately authorized scope.

On WSL, device discovery now falls back to Windows adb.exe when Linux adb has no devices. frida-session.sh also accepts --adb-bin adb.exe and --frida-bin .venv/bin/frida. For a non-root emulator using Frida Gadget, attach with --frida-host <reachable-host>:<port> --frida-target Gadget --attach; the Windows ADB forward listens on Windows loopback, so a WSL client needs a separately reachable forwarding endpoint. The runner records both transports and captures logcat without clearing the device-wide log buffer.

Legal disclaimer

This skill is for authorized security assessments only. Use it on applications you have written permission to test. Unauthorized access to computer systems is illegal. The authors assume no liability for misuse.

License

Apache 2.0

↑↓ navigate openesc close