Skip to main content

MobSF

MobSF (Mobile Security Framework) is an all-in-one mobile application security testing tool.

This article walks you through how to integrate a local MobSF installation with Corellium virtual devices. We demonstrate how to run static and dynamic analysis on a Corellium virtual device using both the MobSF web interface and the MobSF REST API.

MobSF Analysis Features

MobSF supports:

  • Static analysis of iOS apps
  • Static analysis of Android apps
  • Dynamic analysis of Android apps on devices running Android 7 to Android 10

Please note: Since MobSF does not support dynamic analysis of iOS apps, this guide will focus on running Android firmware on Corellium.

Set Up MobSF

  1. Ensure that your environment meets the requirements for MobSF, including cmake.

  2. Clone the repository and run the setup script.

    git clone https://github.com/MobSF/Mobile-Security-Framework-MobSF.git
    cd Mobile-Security-Framework-MobSF/
    ./setup.sh
  3. Create a new Corellium Android 10 virtual device. (MobSF supports up to Android 10 for dynamic analysis.)

  4. Wait for your device to boot and connect to the Corellium VPN. Make note of the IP and port numbers in the adb connect command. Connect to VPN and find the adb connect command

  5. Manually set ANALYZER_IDENTIFIER in the MobSF config file. The IP address and port should match the adb connect command from the previous step.

    sed -i -e "s/ANALYZER_IDENTIFIER = ''/ANALYZER_IDENTIFIER = '<device_services_ip>:5001'/g" ~/.MobSF/config.py
  6. Start MobSF with ./run.sh and wait for the web interface to load.

Run MobSF

We will run our tests on an example app Uncrackable Level 3, which is part of the OWASP Foundation's Mobile Application Security CrackMes project.

Static Analysis using the Web Interface

  1. Navigate to http://127.0.0.1:8000/.
  2. Click Upload & Analyze to begin the static analysis. Start the static analysis
  3. The results will load automatically when finished, or you can open the Static Report by clicking RECENT on the top-left. Be sure to check the Security Analysis section, especially any high-severity issues. Static analysis results
  4. Click MobSF Scorecard to view a high-level summary, including the Risk Rating grade. Static analysis Security Scorecard
  5. Optionally, save the results with PDF Report. Static analysis PDF

Dynamic Analysis Using the Web Interface

  1. Starting from the previous section, click Start Dynamic Analysis towards the bottom-left. Start the dynamic analysis

  2. You will be taken to the Dynamic Analysis page. Scroll to the top and click Show Screen. Dynamic analysis, show screen

  3. Click on Logcat Stream to view the live logs of your Corellium device. Dynamic analysis, logcat stream

  4. Open the TLS/SSL Security Tester. Dynamic analysis, TLS tester

  5. Click Run TLS/SSL Tests and wait for the results. Dynamic analysis, TLS results

  6. Continue to run integrated Frida scripts as appropriate, including:

    • Live API Monitor
    • Root Detection Bypass
    • SSL Pinning Bypass
    • Fingerprint Bypass
    • Enumerate Loaded Classes and Methods
    • Capture Strings and String Comparisons
  7. When you are finished, click Generate Report to view your test data summary, including screenshots, Frida logs, dympsys logs, URLs, trackers, and much more. Generate the dynamic analysis report

Static and Dynamic Analysis Using the REST API

In addition to using the MobSF web interface, you can also run static and dynamic analysis on Corellium devices with the REST API.

How to Execute the Script

  1. Save the script at the end of this article to your local environment. In our example, we saved the script to ~/mobsf_example.py.
  2. Navigate to the MobSF web interface (http://127.0.0.1:8000/).
  3. Click the REST API link at the top of the MobSF web interface and make note of your key. REST API key
  4. Set the APIKEY on Line 12 of your script.
  5. Set the FILE on Line 13 of your script to match your .apk. In our example, we use UnCrackable-Level3.apk.
  6. Run the script.
    python3 ~/mobsf_example.py

Example Script for the MobSF REST API

"""
MOBSF REST API Python Requests
"""

import json
import requests
from datetime import datetime
from requests_toolbelt import MultipartEncoder
import uuid

SERVER = "http://127.0.0.1:8000" # change me as necessary
FILE = 'your_app.apk' # change name as necessary and make sure this file path resolves
APIKEY = '' # your MobSF API key

def upload():
"""Upload File"""
print("Uploading file")
multipart_data = MultipartEncoder(fields={'file': (FILE, open(FILE, 'rb'), 'application/octet-stream')})
headers = {'Content-Type': multipart_data.content_type, 'Authorization': APIKEY}
response = requests.post(SERVER + '/api/v1/upload', data=multipart_data, headers=headers)
print(response.text)
return response.text

def scan(data):
"""Scan the file"""
print("Scanning file")
post_dict = json.loads(data)
headers = {'Authorization': APIKEY}
response = requests.post(SERVER + '/api/v1/scan', data=post_dict, headers=headers)
#print(response.text)

def startDynamic(data):
"""Starts Dynamic Analysis"""
print(f"Starting Dynamic Analysis")
headers = {'Authorization': APIKEY}
data = {"hash": json.loads(data)["hash"]}
response = requests.post(SERVER + '/api/v1/dynamic/start_analysis', data=data, headers=headers, stream=True)
#print(response.text)

def startTLSTest(data):
"""Starts TLS Test"""
print(f"Starting TLS Test")
headers = {'Authorization': APIKEY}
data = {"hash": json.loads(data)["hash"]}
response = requests.post(SERVER + '/api/v1/android/tls_tests', data=data, headers=headers, stream=True)
print(response.text)

def stopDynamic(data):
"""Stops Dynamic Analysis"""
print(f"Stopping Dynamic Analysis")
headers = {'Authorization': APIKEY}
data = {"hash": json.loads(data)["hash"]}
response = requests.post(SERVER + '/api/v1/dynamic/stop_analysis', data=data, headers=headers, stream=True)
print(response.text)

def pdf(data):
"""Generate PDF Report"""
print("Generate PDF report")
headers = {'Authorization': APIKEY}
data = {"hash": json.loads(data)["hash"]}
response = requests.post(SERVER + '/api/v1/download_pdf', data=data, headers=headers, stream=True)
report_name = "report-" + FILE + '-'+ str(uuid.uuid4())
with open(f"{report_name}.pdf", 'wb') as flip:
for chunk in response.iter_content(chunk_size=1024):
if chunk:
flip.write(chunk)
print(f"Report saved as {report_name}.pdf")

def json_resp(data):
"""Generate JSON Report"""
print("Generate JSON report")
headers = {'Authorization': APIKEY}
data = {"hash": json.loads(data)["hash"]}
response = requests.post(SERVER + '/api/v1/report_json', data=data, headers=headers)
print(response.text)


def delete(data):
"""Delete Scan Result"""
print("Deleting Scan")
headers = {'Authorization': APIKEY}
data = {"hash": json.loads(data)["hash"]}
response = requests.post(SERVER + '/api/v1/delete_scan', data=data, headers=headers)
print(response.text)

def main():
RESP = upload()
scan(RESP)
startDynamic(RESP)
startTLSTest(RESP)
stopDynamic(RESP)
json_resp(RESP)
pdf(RESP)
#delete(RESP)

if __name__ == '__main__':
try:
print('Starting the script at ' + datetime.now().strftime("%H:%M:%S"))
main()
except Exception as e:
print('Exception while running main().\n%s\n' % e)