Skip to content

Repository files navigation

AppRay

An integrated mobile security platform for Android applications — SAST + MobSF + emulator‑based dynamic analysis + DAST (Nuclei) + AI‑assisted reporting, all in a single pipeline.

AppRay takes an Android APK from one panel and runs it through static analysis, professional mobile scanning, a live emulator‑based dynamic session, and live‑target DAST verification, then consolidates everything into one unified, AI‑annotated report.

Developed as a graduation thesis project at Amasya University, Department of Computer Engineering. Academic title: “Integrated SAST, DAST and Dynamic Analysis Platform for Android Applications: AppRay”.


⚠️ Responsible Use & Legal Disclaimer — read this first

AppRay is an academic / educational security‑research tool. It is intended for defensive and authorized testing only.

You may use AppRay only on:

  • applications, APIs and infrastructure that you own, or
  • targets for which you have explicit, written authorization to perform security testing.

Do not use AppRay — or any detection rule, exploit template, or integration you build on top of it — to scan, attack, fingerprint, or extract data from applications, services, or networks that you do not own or are not authorized to assess. In particular:

  • 🚫 No malicious use, and no malicious development. Do not extend this project to weaponize it against third parties, to evade detection for offensive purposes, or to harvest credentials/data from systems you don’t control.
  • 🚫 The bundled custom Nuclei templates are deliberately offensive (they dump user tables, perform UNION‑based SQLi, and prove IDOR). By design they are gated to local / staging targets only (see Writing Custom Detection Rules). Do not remove that gating to point them at external hosts.
  • ⚖️ Unauthorized scanning, access, or exploitation of computer systems is illegal in most jurisdictions. You are solely responsible for ensuring your use complies with all applicable laws and contracts.
  • 🤝 If you discover a real vulnerability in third‑party software while learning with this tool, practice responsible disclosure.
  • 🧪 The included ShopNex / VulnShop target is an intentionally vulnerable app meant to be run locally, in an isolated environment, purely for demonstration and learning. Never deploy it on a public network.

This software is provided “as is”, without warranty of any kind (see LICENSE.md). The authors accept no liability for any misuse or damage caused by this tool.

By using or forking this repository, you agree to use it lawfully and ethically.


Table of Contents


Key Features

  • Multi‑source APK intake — upload a file, download from a URL (with mirror fallback), build straight from a GitHub repository, or fetch by package name (mirror → Play Store fallback). Each source is validated with fail‑fast checks (ZIP magic bytes, package‑name regex).
  • SAST — JADX decompilation + 16 regex categories (Firebase/cloud, secrets, dangerous permissions, hardcoded credentials, log leakage, insecure WebView, exported components, SSL bypass, deep links, Retrofit endpoints, base URLs, weak crypto, backup/debuggable flags, …), live Firebase/bucket testing, and AI‑summarized critical findings.
  • MITRE CWE integration — findings are mapped to the CWE Comprehensive Dictionary (~969 weaknesses); the UI shows an expandable “MITRE CWE Detail” panel with description, likelihood and mitigations, translated to Turkish on demand.
  • Dynamic analysis — APK installed on a Dockerized Android emulator, mitmproxy CA injected, app launched. A manual‑control mode lets the analyst log in / complete OTP & permissions before automated discovery starts, followed by a bounded Monkey fuzzing pass.
  • Live traffic capture — a custom mitmproxy addon captures Authorization tokens and Set‑Cookie sessions, filters out system noise, and feeds real application endpoints into the DAST queue.
  • DAST — captured live targets are scanned with Nuclei, including custom mobile‑API templates; results are summarized by an LLM as a Turkish pentest report.
  • Unified report — SAST and DAST findings are presented together with source badges, severity, technical evidence, and CWE panels.
  • Real‑time UI — a vanilla‑JS Single Page App (clean History‑API URLs) with SignalR live scan progress and notifications, plus dark/light themes.

ℹ️ The product UI is in Turkish (the project’s academic language). The screenshots below are captioned in English.


Screenshots

New scan — select target & start analysis

Pick the APK source (Upload · URL · GitHub Repo · Package Name), name the app, and choose the environment (Production = manual‑login dynamic flow, Test = aggressive fuzzing). The right panel summarizes which modules will run.

New scan page

Source selection (close‑up)

The four intake channels. “GitHub Repo” clones and builds the project; “Package Name” tries public mirrors first, then the Play Store fallback.

Source selection

Scans dashboard

All scans with their status (Completed · Completed with warnings · Failed) and per‑scan counts of vulnerabilities, SAST and DAST findings. Each card offers Detail and Restart.

Scans dashboard

Live scan progress

The pipeline stages (Build → SAST → MobSF → DAST → Done) update in real time over SignalR. In manual mode the “Go to Emulator / I’ve Logged In, Continue” buttons gate the dynamic step.

Scan in progress

Unified security report (SAST + DAST)

A consolidated “RoboApp Report”: an executive brief, severity breakdown (High / Medium / Info), filter pills, and per‑finding cards with technical evidence, CWE / OWASP MASVS tags, source badge, and remediation advice.

Unified report

Settings

Sidebar‑style settings: Play Store integration (for package‑name intake), appearance (dark/light), and platform placeholders.

Settings

ShopNex — the intentionally vulnerable test app

The bundled demo target used to validate the pipeline end‑to‑end.

ShopNex test app


Architecture

   APK Intake → SAST → (parallel) MobSF + Dynamic Analysis → DAST → Unified Report
   Frontend SPA (SignalR)                         Android Emulator (noVNC)
        │                                                  │
        ▼                                                  ▼
   AppRay.WebApi (8080) ──► RabbitMQ ──► AppRay.DastScanner ──► Nuclei ──► live target
        │  orchestration                      ▲
        ├─► AppRay.SastScanner (JADX + regex + CWE KB + AI)
        ├─► MobSF (8000)
        └─► mitmproxy addon ──► token / login webhooks ──┘
                │
                ▼
            PostgreSQL (5433)        Ollama (Llama 3.1 + LLaVA, on host)
Service Port (host) Role
appray-webapi 8080 Orchestrator, SPA host, pipeline manager, SignalR hub
appray-sastscanner JADX decompile + 16 regex categories + Firebase/bucket tests + AI summary
appray-dastscanner RabbitMQ dast_targets consumer → Nuclei → AI pentest report
appray-postgres 5433 PostgreSQL database (scans, findings, sessions)
appray-rabbitmq 5672 / 15672 AMQP queue + management UI
appray-mobsf 8000 MobSF mobile analysis
appray-emulator 6080 Android 11 emulator (browser access via noVNC)
appray-mitmproxy 8887 / 8889 Traffic capture + token/login webhooks
appray-vampi 5000 Intentionally vulnerable REST API (Nuclei test target)
Ollama 11434 Llama 3.1 + LLaVA (runs on the host, outside Docker)

Tech Stack

.NET 8 (C#) · PostgreSQL · RabbitMQ · Docker Compose · Python (mitmproxy addon) · Vanilla JS SPA (History API) · SignalR · JADX · Nuclei · MobSF · Ollama (Llama 3.1 + LLaVA)


Quick Start

Requirements: Docker + Docker Compose, hardware virtualization (/dev/kvm) for the emulator, and (optionally) Ollama on the host for the AI layer.

git clone https://github.com/fuatsimsek/appray.git
cd appray

# JADX is gitignored — download it and extract into ./jadx_tool/
# https://github.com/skylot/jadx/releases

# (optional) AI layer on the host
ollama pull llama3.1
ollama pull llava

docker compose up -d postgres rabbitmq mobsf android-emulator mitmproxy vampi
docker compose up -d webapi dastscanner

Then open:

Service URL
Dashboard http://localhost:8080
Emulator (noVNC) http://localhost:6080
RabbitMQ UI http://localhost:15672 (guest / guest)
MobSF http://localhost:8000
mitmweb http://localhost:8889 (password: appray)

wwwroot/ is volume‑mounted, so HTML/CSS/JS changes apply without a rebuild (just hard‑refresh). C# changes require an image rebuild.


How the Pipeline Works

  1. POST /api/scans records the scan and starts SAST (AppRay.SastScanner).
  2. On SAST success, status becomes sast_done and MobSF + Dynamic analysis run in parallel (Task.Run).
  3. Dynamic: install APK on the emulator, inject the mitmproxy CA, launch the app, hand control to the analyst (manual login/OTP), run bounded Monkey fuzzing, collect traffic + SharedPrefs + logcat.
  4. Captured & normalized URLs (third‑party noise stripped) are pushed to the dast_targets RabbitMQ queue with the captured auth header.
  5. AppRay.DastScanner consumes targets, runs Nuclei, and (on hits) generates a Turkish AI pentest summary.
  6. The pipeline waits for DAST completion before marking the scan completed, so the unified report is always complete when shown.

✍️ Writing Custom Detection Rules

One of AppRay’s goals is to make it easy to add your own detection logic. There are two extension points: SAST regex categories (static) and custom Nuclei templates (dynamic). Below is exactly how the bundled rules (e.g. the SQL‑injection check) were integrated.

1) SAST — add a regex category

Static detections live in a single dictionary in AppRay.SastScanner/Analysis/VulnerabilityAnalyzer.csDeepScanAsync():

var searchPatterns = new Dictionary<string, Regex>
{
    ["🔥 Firebase & Cloud"]      = new Regex(@"https?://[\w\.-]+\.(?:firebaseio\.com|s3\.amazonaws\.com|appspot\.com)", ...),
    ["🔑 Sensitive Keys"]        = new Regex(@"(?:api_key|aws_secret|auth_token|client_secret|...)...", ...),
    // … 16 categories shipped by default …

    // 👉 YOUR NEW RULE — just add another entry:
    ["🧨 Hardcoded JWT"] = new Regex(
        @"eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}",
        RegexOptions.Compiled),
};

That’s the minimum. The key ("emoji Name") becomes the finding category; every match in the decompiled sources is collected, grouped per category, and written to the DB.

To make the finding richer in the UI, also:

  • Filter false positives — extend LibraryNoiseRegex in the same file if your pattern matches framework/library URLs (XML namespaces, license URLs, etc.). Noise matches are dropped before they reach the DB.
  • Map to a CWE / OWASP reference — add a case for your category in VulnerabilityKB.cs (GetInfo) so the report shows the CWE id, OWASP MASVS tag, description and remediation. CWE details/translations are then enriched automatically from the MITRE knowledge base.

Rebuild the scanner image so the new C# is picked up.

2) DAST — add a custom Nuclei template

Dynamic detections are plain Nuclei YAML files in nuclei-custom-templates/. The bundled ones target the mobile API of the test app:

Template Severity What it proves
mobile-api-users-exposure.yaml critical /api/users returns all users + plaintext passwords with no auth
mobile-api-sqli-union.yaml high /api/products?search= is UNION‑SQLi → dumps the users table
mobile-api-idor.yaml high a low‑priv token reads another user’s profile (IDOR / BOLA)

A minimal custom template looks like this (note {{RootURL}}):

id: my-custom-api-check
info:
  name: My Custom Mobile API Check
  author: you
  severity: high
  tags: mobile,api,custom

http:
  - method: GET
    path:
      - "{{RootURL}}/api/secret-endpoint"
    matchers-condition: and
    matchers:
      - type: status
        status: [200]
      - type: word
        words: ["password", "token"]
        condition: and

Rules that matter (learned the hard way):

  • Use {{RootURL}}, not {{BaseURL}}. The pipeline hands Nuclei the full captured URL (path included); {{BaseURL}} would re‑append the path and hit the wrong target.
  • 📦 Mountingdocker-compose.yml mounts the folder into the scanner:
    appray-dastscanner:
      volumes:
        - ./nuclei-custom-templates:/root/nuclei-templates/custom
    Templates are volume‑mounted, so you just restart the scanner (docker compose restart dastscanner) — no rebuild, and don’t hand‑copy files into the container (they’re lost on restart).
  • 🔒 Safety gating (isLocal) — custom templates only run against local / staging targets. In AppRay.WebApi/Program.cs a target is considered local when its host matches host.docker.internal, localhost, 127.*, 10.0.2.2, 172.*, or 192.168.*. Only then does AppRay.DastScanner/ExploitEngine.cs add -t custom/ to the Nuclei command:
    // ExploitEngine.cs — local targets get the aggressive set incl. custom/
    templates = "-t network/ -t http/default-logins/ -t http/misconfiguration/ "
              + "-t http/vulnerabilities/ -t http/exposures/ -t custom/";
    This is intentional: your offensive templates never fire at arbitrary external hosts. Keep it that way.

Test Application — ShopNex / VulnShop

The pipeline is validated against ShopNex (package com.vulnshop), an intentionally vulnerable e‑commerce app (Android client + Flask/SQLite REST API) — see github.com/fuatsimsek/VulnShop. Planted flaws include: SQLi (login + search), IDOR (cart/orders/profile), weak JWT, plaintext passwords, hardcoded secrets, cleartext HTTP, insecure WebView + JavaScript bridge token leak, and MD5 usage — covering both the SAST and DAST sides.

⚠️ ShopNex is deliberately insecure. Run it only in an isolated local environment. Never expose it publicly.


AI Layer

Model Used for
Llama 3.1 SAST/DAST summary reports, URL categorization, password‑realism classification, CWE Turkish translation
LLaVA Interpreting emulator screens (form/button detection) during the manual dynamic session

Principle: AI is an assistive commentary layer, not a decision‑maker. The real detection is done by regex rules, the rule engine, and Nuclei. Ollama runs on the host at http://localhost:11434.


Project Layout

AppRay/
├── docker-compose.yml
├── AppRay.WebApi/          # orchestrator, SPA host, SignalR, pipeline
├── AppRay.SastScanner/     # JADX + regex categories + CWE KB + AI
├── AppRay.DastScanner/     # RabbitMQ consumer + Nuclei + AI report
├── mitmproxy_addon/        # token/login webhooks
├── nuclei-custom-templates/# custom mobile‑API DAST templates
├── android-emulator/       # emulator Dockerfile
├── gplaycli/               # Play Store APK fetcher
└── docs/screenshots/       # README images

License & Academic Note

Released under the MIT License — see LICENSE.md. This is a university graduation project intended for education and authorized security research; please honor the Responsible Use terms above.

Acknowledgements: built on the excellent open‑source work of JADX, Nuclei, MobSF, mitmproxy, RabbitMQ, Ollama, and the OWASP MASTG.

Releases

Packages

Contributors

Languages