Skip to content

A mitmproxy-based toolkit for capturing and mocking Android/iOS network traffic, with automation scripts for cert installation and dynamic proxy control.

Notifications You must be signed in to change notification settings

TomTruyen/mitm-proxy-configuration-scripts

Repository files navigation

πŸ•΅οΈ mitmproxy Emulator & Simulator Integration

This repository contains helper scripts and a mitmproxy addon to easily intercept HTTP(S) traffic from Android emulators and iOS simulators using mitmproxy. It also provides control endpoints to start/stop recording and dynamically map local responses to specific request URLs.


πŸ“¦ Requirements

  • mitmproxy (v9+ recommended)
  • Android Emulator with root access
  • iOS Simulator (via Xcode)
  • macOS or Linux

πŸ”§ Installation

macOS

brew install mitmproxy

Linux (Debian/Ubuntu)

sudo apt update
sudo apt install mitmproxy

Verify installation:

mitmdump --version

πŸ“± Android Emulator Setup

⚠️ Requirements:

  • Emulator must be rooted (use x86 or ARM images that support root).
  • Emulator must be started using -writable-system flag to be able to perform an adb remount
  • Android SDK + ADB installed and configured in your $PATH.

πŸ› οΈ Setup Steps:

  1. Launch emulator with writable system

You should find an emulator that can be rooted using adb root. In most cases these are the emulators WITHOUT Google Play Services.

Launch the emulator with a writable-system partition

# Find name of AVD
emulator -list-avds

emulator -avd <name of avd> -writable-system
  1. Run the script:
chmod +x android-certificate-install.sh
./android-certificate-install.sh

This script will:

  • Ensure the mitmproxy CA certificate exists as ~/.mitmproxy/mitmproxy-ca-cert.cer
  • Push the certificate to the emulator’s system certificate store (using the correct method for Android version)
  • Configure proxy settings to forward traffic to mitmproxy on host (10.0.2.2:8080)
  • Reboot the emulator to apply changes

🍏 iOS Simulator Setup

⚠️ Requirements:

  • xcode-select must point to an installed Xcode
  • You may need to manually trust the certificate in: Settings > General > About > Certificate Trust Settings

If simctl fails:

sudo xcode-select -s /Applications/Xcode.app

πŸ› οΈ Setup Steps:

chmod +x ios-certificate-install.sh
./ios-certificate-install.sh

This will:

  • Boot or select a running iOS simulator
  • Install mitmproxy CA certificate (mitmproxy-ca-cert.pem copied as mitmproxy-ca-cert.crt) into the simulator keychain
  • Set system proxy on the Ethernet interface (used by the simulator)
  • Exit with an error if automatic install fails (no manual fallback)

(Optional) macOS System Trust:

If you want your entire macOS system to trust mitmproxy (for capturing CLI tools or other apps):

sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain mitmproxy-ca-cert.crt

🧩 mitmproxy Addon – Session Controller

The file proxy-session-controller.py is a mitmproxy addon that:

  • Records flows while a session is active
  • Allows you to start/stop recording via HTTP API
  • Lets you map specific URLs to local mock response files

πŸš€ Usage

Start mitmproxy with the addon:

mitmdump -p 8080 -s proxy-session-controller.py

This starts mitmproxy with:

  • Listening port: 8080
  • Control API: http://localhost:9999

Running mitmproxy in background with the addon:

screen -dm mitmdump -p 8080 -s proxy-session-controller.py

About screen:

The screen command is a terminal multiplexer that lets you run multiple sessions within a single terminal window. By starting mitmdump in a detached screen session, you can keep it running in the background while continuing to use your terminal for other tasks.

This approach is especially useful in CI/CD environments, where you don't want a pipeline step to hang because mitmdump is occupying the terminal interactively.

You can re-attach to the running session at any time using:

screen -r

This allows you to check logs or interact with the process as needed. To verify if mitmdump is running, you can use:

pgrep mitmdump

This will return the process ID if it is running.


🚫 About IGNORED_ENDPOINTS

When using mitmproxy with emulators and simulators, a lot of background network traffic is generated by the operating system and system apps (such as Google or Apple services). Most of this traffic is not relevant for app testing or debugging and can clutter your logs.

The IGNORED_ENDPOINTS list in proxy-session-controller.py contains hostnames for common Android and iOS system services that are automatically filtered out. Requests to these endpoints are not recorded or included in your output files.

Examples of ignored endpoints:

  • Android: gstatic.com, googleapis.com, clients4.google.com, play.googleapis.com, etc.
  • iOS: apple.com, icloud.com, itunes.apple.com, push.apple.com, etc.

Why is this useful?

  • Reduces noise in your captured network logs.
  • Makes it easier to focus on your app’s actual API calls.
  • Prevents large, irrelevant log files from being generated.

If you want to capture all traffic, you can remove or modify the IGNORED_ENDPOINTS list in the script.


πŸ› οΈ Control API Endpoints

These endpoints allow dynamic control of recording and local response mapping.

▢️ Start Recording

# Default recording, outputs to flows.json
curl -X POST http://localhost:9999/start_recording

# Optional name for recording, outputs to "name".json
curl -X POST http://localhost:9999/start_recording \
  -H "Content-Type: application/json" \
  -d '{"name": "output_file_name"}'

⏹️ Stop Recording and Save

curl -X POST http://localhost:9999/stop_recording

This saves all recorded flows to the file specified when starting the recording (e.g., output_file_name.json), or to flows.json if no name was provided.

πŸ” Enable Local Mapping for a URL

curl -X POST http://localhost:9999/map_local/enable \
  -H "Content-Type: application/json" \
  -d '{"url": "https://api.example.com/data", "file_path": "/absolute/path/to/response.json"}'

Any requests matching the URL will return the contents of response.json.

🚫 Disable Mapping for a URL

curl -X POST http://localhost:9999/map_local/disable \
  -H "Content-Type: application/json" \
  -d '{"url": "https://api.example.com/data"}'

πŸ”„ Clear All Mappings

curl -X POST http://localhost:9999/map_local/disable

πŸ“Ž Notes & Edge Cases

  • For Android: Emulator must be rooted to modify /system/etc/security/cacerts
  • For iOS:
    • simctl keychain may not work on all Xcode versions. If it fails, the certificate will be opened manually for trust.
    • You may need to manually trust the cert in the iOS Simulator settings
  • For macOS:
    • You can manually install the CA cert into the system keychain to capture macOS traffic too
  • The local mapping only works if the URL matches exactly, including protocol and query params.

πŸ“‚ Output Example: flows.json

Each captured flow includes the method, URL, headers, and parsed JSON request/response body if possible.

[
  {
    "request": {
      "method": "GET",
      "url": "https://api.example.com/data",
      "headers": { ... },
      "body": {}
    },
    "response": {
      "status_code": 200,
      "headers": { ... },
      "body": { "result": "ok" }
    }
  }
]

πŸ“š Use Cases

βœ… Automated Network Testing for Android & iOS

You can integrate mitmproxy recording into your mobile test lifecycle to verify network behavior during test execution.


πŸ” Example Flow:

  1. Start mitmproxy with the addon (before your test suite):
mitmdump -p 8080 -s proxy-session-controller.py
  1. Start recording flows (before your test begins):
curl http://localhost:9999/start_recording
  1. Run your UI/E2E test that performs network requests from the Android emulator or iOS simulator.

  2. Stop recording after the test is finished:

curl http://localhost:9999/stop_recording
  1. Validate the output in flows.json using a custom validation script.

πŸ§ͺ Example: Test Validation Script (Python)

import json

with open("flows.json") as f:
    flows = json.load(f)

expected_url = "https://api.example.com/data"
matched = any(flow["request"]["url"] == expected_url for flow in flows)

assert matched, f"Expected request to {expected_url} not found!"
print("[βœ“] Network request verified.")

πŸ’‘ Use With Your Test Framework

In your test framework (e.g., XCTest for iOS, Espresso or UIAutomator for Android), you can:

  • Trigger /start_recording in the test setup phase
  • Run the UI interaction
  • Trigger /stop_recording in the test teardown
  • Run a validation script after the test completes

This allows you to assert that expected network calls were made, validate request payloads, and check response data without needing to modify your app code.


🧼 Cleanup

To reset Android emulator proxy:

adb shell settings put global http_proxy :0

To reset macOS proxy:

networksetup -listallnetworkservices | tail +2 | while read -r interface; do
  networksetup -setwebproxystate "$interface" off
  networksetup -setsecurewebproxystate "$interface" off
done

πŸ™Œ Contributions

Feel free to extend this tool with more proxy automation, better cert handling, or a simple UI for the control endpoints.

About

A mitmproxy-based toolkit for capturing and mocking Android/iOS network traffic, with automation scripts for cert installation and dynamic proxy control.

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published