MobSF: Complete Guide to Mobile Application Security Testing and Malware Analysis Using Kali Linux

MobSF: Complete Guide to Mobile Application Security Testing and Malware Analysis Using Kali Linux

Mobile Security Framework (MobSF) is an open-source, automated, all-in-one mobile application penetration testing, malware analysis, and security assessment framework. It is written in Python 3 and is developed and maintained by Ajin Abraham and the MobSF community. MobSF is capable of performing both static analysis and dynamic analysis on Android (APK, XAPK, source code ZIP), iOS (IPA, source code ZIP), and Windows (APPX) application binaries.

MobSF exposes a browser-based web interface (by default at http://127.0.0.1:8000) that a tester uses to upload a mobile application file, after which MobSF automatically:

MobSF also ships a REST API, which allows the entire scan lifecycle (upload, scan, generate report, delete scan) to be automated from the command line or integrated into a CI/CD pipeline, which is the primary way this chapter demonstrates “command-line” usage of what is fundamentally a web application.

How to Install

MobSF can be installed on Kali Linux using either Docker (recommended, fastest, most reliable) or a manual source installation using a Python virtual environment.

Method 1 – Docker (Recommended)

# Update package lists
sudo apt update

# Install Docker if not already installed
sudo apt install docker.io -y

# Start and enable the Docker service
sudo systemctl start docker
sudo systemctl enable docker

# Pull the official MobSF image
sudo docker pull opensecurity/mobile-security-framework-mobsf:latest

# Run MobSF, exposing port 8000
sudo docker run -it --rm -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest

Method 2 – Manual Installation from Source

# Install build dependencies
sudo apt install python3-dev python3-venv python3-pip build-essential \
  libffi-dev libssl-dev libxml2-dev libxslt1-dev libjpeg62-turbo-dev \
  zlib1g-dev wkhtmltopdf git -y

# Clone the MobSF repository
git clone https://github.com/MobSF/Mobile-Security-Framework-MobSF.git
cd Mobile-Security-Framework-MobSF

# Run the setup script (Linux/Kali)
./setup.sh

# Start the MobSF server
./run.sh

After either method completes, open a browser and navigate to http://127.0.0.1:8000. The default login credentials in older versions were mobsf/mobsf; current versions generate a random username/password on first run and print it to the console/log — always check the terminal output for the actual credentials.

Syntax

MobSF itself is not a traditional single-binary CLI tool; it is operated primarily through its web UI or its REST API. The general syntax patterns used throughout this section are:

# Running the server
./run.sh [IP:PORT]

# Interacting with the REST API using curl
curl -X POST --url <MobSF_URL>/api/v1/<endpoint> \
  -H "Authorization:<api_key>" \
  [-F 'file=@<path_to_apk>'] \
  [-d "<key>=<value>&<key2>=<value2>"]

All Command-Line Options / API Endpoints

run.sh script options:

OptionDescription
./run.shStarts MobSF on default 127.0.0.1:8000
./run.sh 0.0.0.0:8000Binds MobSF to all interfaces on port 8000
./run.sh 127.0.0.1:8080Runs MobSF on a custom port

Core REST API endpoints (used with curl -H "Authorization:<api_key>"):

EndpointMethodPurpose
/api/v1/uploadPOSTUpload an APK/IPA/APPX/ZIP file for analysis
/api/v1/scanPOSTTrigger a static scan on an uploaded file’s hash
/api/v1/scan_logsPOSTRetrieve live scan logs for a hash
/api/v1/report_jsonPOSTRetrieve the full static analysis report in JSON
/api/v1/download_pdfPOSTDownload the report as a PDF
/api/v1/pdfPOSTAlternate PDF report generation endpoint
/api/v1/scorecardPOSTRetrieve a simplified security scorecard
/api/v1/delete_scanPOSTDelete a scan and its associated report/data
/api/v1/recent_scansGETList recently scanned applications
/api/v1/view_sourcePOSTRetrieve source code of a specific file in the report
/api/v1/searchGETSearch scans by app name, package, or hash
/api/v1/compareGETCompare two scan reports (diff)
/api/v1/android/dynamic_analyzerPOSTStart Android dynamic analysis on a connected device
/api/v1/dynamic/report_jsonPOSTRetrieve dynamic analysis report in JSON
/api/v1/frida/instrumentPOSTInstrument the app with Frida during dynamic analysis
/api/v1/frida/api_monitorPOSTEnable Frida-based API monitoring
/api/v1/scan_binaryPOSTPerform binary-level scan (e.g., .so, .dylib)

The full, always up-to-date API reference is available from any running instance at <MobSF_URL>/api_docs, and the API key is displayed on that same page and in the server console logs.

Basic Usage (Expected Output in Bash)

Starting MobSF via Docker:

$ sudo docker run -it --rm -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest
[INFO] Creating MobSF Home Directory: /home/mobsf/.MobSF
[INFO] Downloading static analyzer dependencies...
[INFO] Applying migrations...
Operations to perform:
  Apply all migrations: StaticAnalyzer, admin, auth, contenttypes, sessions
Running migrations:
  Applying StaticAnalyzer.0001_initial... OK
[INFO] MobSF version: 4.3.2
[INFO] REST API Key: a190b3306dcd961cd7ecc6514369b22f50dddc858c68c4e4b0d620b442832ef4
Django version 4.2, using settings 'MobSF.settings'
Starting development server at http://0.0.0.0:8000/
Quit the server with CONTROL-C.

Uploading a file with curl:

$ curl -F 'file=@/home/kali/apks/goatdroid.apk' http://127.0.0.1:8000/api/v1/upload \
  -H "Authorization:a190b3306dcd961cd7ecc6514369b22f50dddc858c68c4e4b0d620b442832ef4"
{"file_name": "goatdroid.apk", "hash": "82ab8b2193b3cfb1c737e3a786be363a", "scan_type": "apk"}

Practical Examples with Output

Example 1 — Upload an APK for analysis:

$ curl -F 'file=@insecurebankv2.apk' http://127.0.0.1:8000/api/v1/upload \
  -H "Authorization:$MOBSF_API_KEY"
{"file_name": "insecurebankv2.apk", "hash": "3a1f9e2b8c4d6f0a1b2c3d4e5f60718293", "scan_type": "apk"}

Example 2 — Trigger the static scan using the returned hash:

$ curl -X POST --url http://127.0.0.1:8000/api/v1/scan \
  --data "hash=3a1f9e2b8c4d6f0a1b2c3d4e5f60718293" \
  -H "Authorization:$MOBSF_API_KEY"
{"analyzer": "static_analyzer", "status": "success", "hash": "3a1f9e2b8c4d6f0a1b2c3d4e5f60718293"}

Example 3 — Check scan logs while analysis runs:

$ curl -X POST --url http://127.0.0.1:8000/api/v1/scan_logs \
  --data "hash=3a1f9e2b8c4d6f0a1b2c3d4e5f60718293" \
  -H "Authorization:$MOBSF_API_KEY"
{"logs": [
  {"timestamp": "2026-07-19 10:12:01", "status": "Generating Hashes", "exception": null},
  {"timestamp": "2026-07-19 10:12:02", "status": "Extracting APK", "exception": null},
  {"timestamp": "2026-07-19 10:12:04", "status": "Parsing AndroidManifest.xml", "exception": null},
  {"timestamp": "2026-07-19 10:12:09", "status": "Fetching Permissions", "exception": null},
  {"timestamp": "2026-07-19 10:12:22", "status": "Performing Static Analysis of Source Code", "exception": null}
]}

Example 4 — Retrieve a simplified scorecard:

$ curl -X POST --url http://127.0.0.1:8000/api/v1/scorecard \
  --data "hash=3a1f9e2b8c4d6f0a1b2c3d4e5f60718293" \
  -H "Authorization:$MOBSF_API_KEY"
{
  "version": "v1",
  "title": "Mobile Security Framework (MobSF)",
  "file_name": "insecurebankv2.apk",
  "app_name": "InsecureBankv2",
  "app_type": "apk",
  "security_score": 32,
  "high": 8,
  "warning": 12,
  "info": 6,
  "secure": 3,
  "hotspot": 2
}

Example 5 — Download the full JSON report:

$ curl -X POST --url http://127.0.0.1:8000/api/v1/report_json \
  --data "hash=3a1f9e2b8c4d6f0a1b2c3d4e5f60718293" \
  -H "Authorization:$MOBSF_API_KEY" -o insecurebankv2_report.json

$ ls -lh insecurebankv2_report.json
-rw-r--r-- 1 kali kali 512K Jul 19 10:15 insecurebankv2_report.json

Example 6 — Download the report as PDF:

$ curl -X POST --url http://127.0.0.1:8000/api/v1/download_pdf \
  --data "hash=3a1f9e2b8c4d6f0a1b2c3d4e5f60718293&scan_type=apk" \
  -H "Authorization:$MOBSF_API_KEY" -o insecurebankv2_report.pdf

$ file insecurebankv2_report.pdf
insecurebankv2_report.pdf: PDF document, version 1.4

Example 7 — List recent scans:

$ curl -X GET --url http://127.0.0.1:8000/api/v1/recent_scans \
  -H "Authorization:$MOBSF_API_KEY"
{"content": [
  {"MD5": "3a1f9e2b8c4d6f0a1b2c3d4e5f60718293", "APP_NAME": "InsecureBankv2", "PACKAGE_NAME": "com.android.insecurebankv2", "VERSION_NAME": "1.0", "FILE_NAME": "insecurebankv2.apk", "SCAN_TYPE": "apk", "TIMESTAMP": "2026-07-19 10:12:01"}
], "count": 1}

Example 8 — Search for a specific scan:

$ curl -X GET --url "http://127.0.0.1:8000/api/v1/search?query=insecurebankv2" \
  -H "Authorization:$MOBSF_API_KEY"
{"3a1f9e2b8c4d6f0a1b2c3d4e5f60718293": {"MD5": "3a1f9e2b8c4d6f0a1b2c3d4e5f60718293", "APP_NAME": "InsecureBankv2", "PACKAGE_NAME": "com.android.insecurebankv2"}}

Example 9 — Trigger dynamic analysis on a connected Android device/emulator:

$ curl -X POST --url http://127.0.0.1:8000/api/v1/android/dynamic_analyzer \
  --data "hash=3a1f9e2b8c4d6f0a1b2c3d4e5f60718293" \
  -H "Authorization:$MOBSF_API_KEY"
{"status": "ok", "message": "Dynamic Analysis started successfully"}

Example 10 — Delete a scan and free storage:

$ curl -X POST --url http://127.0.0.1:8000/api/v1/delete_scan \
  --data "hash=3a1f9e2b8c4d6f0a1b2c3d4e5f60718293" \
  -H "Authorization:$MOBSF_API_KEY"
{"deleted": "yes"}

Example 11 — Compare two scans (regression testing between app versions):

$ curl -X GET --url "http://127.0.0.1:8000/api/v1/compare?hash1=3a1f9e2b&hash2=7c2e8f11" \
  -H "Authorization:$MOBSF_API_KEY"
{"compare": {"added_permissions": ["android.permission.CAMERA"], "removed_permissions": [], "score_diff": -5}}

Example 12 — Using the mobsf-cli community wrapper for full CI automation:

$ mobsf-cli ci insecurebankv2.apk -p ./reports -c 5.5 -u 60 -t 5
Uploading insecurebankv2.apk...
Scanning...
Validating scan scores...
Error: Security score [32] is too low. Minimum required: [60].

Common Use Cases

Automation with Bash

The following script automates the full MobSF workflow: upload, scan, poll until complete, and download both JSON and PDF reports.

#!/bin/bash
# mobsf_automate.sh - Automated MobSF scan workflow

MOBSF_URL="http://127.0.0.1:8000"
API_KEY="a190b3306dcd961cd7ecc6514369b22f50dddc858c68c4e4b0d620b442832ef4"
APK_FILE="$1"

if [ -z "$APK_FILE" ]; then
    echo "Usage: $0 <path_to_apk>"
    exit 1
fi

echo "[*] Uploading $APK_FILE..."
UPLOAD_RESPONSE=$(curl -s -F "file=@${APK_FILE}" "${MOBSF_URL}/api/v1/upload" \
  -H "Authorization:${API_KEY}")

HASH=$(echo "$UPLOAD_RESPONSE" | grep -oP '"hash":\s*"\K[^"]+')

if [ -z "$HASH" ]; then
    echo "[-] Upload failed: $UPLOAD_RESPONSE"
    exit 1
fi

echo "[+] Uploaded. Hash: $HASH"
echo "[*] Starting scan..."

curl -s -X POST --url "${MOBSF_URL}/api/v1/scan" \
  --data "hash=${HASH}" \
  -H "Authorization:${API_KEY}" > /dev/null

echo "[+] Scan complete."
echo "[*] Downloading JSON report..."
curl -s -X POST --url "${MOBSF_URL}/api/v1/report_json" \
  --data "hash=${HASH}" -H "Authorization:${API_KEY}" \
  -o "${HASH}_report.json"

echo "[*] Downloading PDF report..."
curl -s -X POST --url "${MOBSF_URL}/api/v1/download_pdf" \
  --data "hash=${HASH}&scan_type=apk" \
  -H "Authorization:${API_KEY}" -o "${HASH}_report.pdf"

echo "[+] Done. Reports saved as ${HASH}_report.json and ${HASH}_report.pdf"

Sample run:

$ chmod +x mobsf_automate.sh
$ ./mobsf_automate.sh insecurebankv2.apk
[*] Uploading insecurebankv2.apk...
[+] Uploaded. Hash: 3a1f9e2b8c4d6f0a1b2c3d4e5f60718293
[*] Starting scan...
[+] Scan complete.
[*] Downloading JSON report...
[*] Downloading PDF report...
[+] Done. Reports saved as 3a1f9e2b8c4d6f0a1b2c3d4e5f60718293_report.json and 3a1f9e2b8c4d6f0a1b2c3d4e5f60718293_report.pdf

Tips and Best Practices

Troubleshooting

ProblemCauseSolution
401 Unauthorized on API callsWrong or missing API keyCopy the correct key from <MobSF_URL>/api_docs or the server startup logs
Web UI unreachable at 127.0.0.1:8000Container/service not bound correctlyRe-run with -p 8000:8000 (Docker) or check ./run.sh 0.0.0.0:8000 for LAN access
wkhtmltopdf errors when generating PDF reportsMissing or wrong-architecture binaryInstall wkhtmltopdf manually and ensure it matches your OS architecture
Static analysis stuck at “Extracting APK”Corrupted or non-standard APK (e.g., split APKs)Use bundletool to merge split APKs/XAPKs into a single APK before upload
Dynamic analyzer fails to connect to deviceADB not detecting the emulator/deviceRun adb devices to confirm connectivity before triggering /api/v1/android/dynamic_analyzer
pip install -r requirements.txt fails during manual installMissing system build dependenciesInstall all packages listed in the manual installation step, especially libxml2-dev, libxslt1-dev, and libssl-dev
Migrations not applied / database errorsFirst run pending migrationsRun python manage.py migrate manually inside the activated virtual environment

References

Exit mobile version