Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4294c4d777 | ||
|
|
219d1ab30c | ||
|
|
4e200fd0bd |
@@ -1,77 +0,0 @@
|
||||
version: '{build}'
|
||||
build: off # Not a C# project
|
||||
|
||||
environment:
|
||||
CI_DEPS: codecov>=2.0.5
|
||||
CI_COMMANDS: codecov
|
||||
matrix:
|
||||
- PYTHON: "C:\\Python35"
|
||||
TOXENV: "py35"
|
||||
# TODO: ENABLE WHEN AVAILABLE
|
||||
# - PYTHON: "C:\\Python36"
|
||||
# TOXENV: "py36"
|
||||
|
||||
SNAPSHOT_HOST:
|
||||
secure: NeTo57s2rJhCd/mjKHetXVxCFd3uhr8txnjnAXD1tUI=
|
||||
SNAPSHOT_PORT:
|
||||
secure: TiJPtg60/edYTH8RnoBErg==
|
||||
SNAPSHOT_USER:
|
||||
secure: 6yBwmO5gv4vAwoFYII8qjQ==
|
||||
SNAPSHOT_PASS:
|
||||
secure: LPjrtFrWxYhOVGXzfPRV1GjtZE/wHoKq9m/PI6hSalfysUK5p2DxTG9uHlb4Q9qV
|
||||
RTOOL_KEY:
|
||||
secure: 0a+UUNbA+JjquyAbda4fd0JmiwL06AdG6torRPdCvbPDbKHnaW/BHHp1nRPytOKM
|
||||
|
||||
install:
|
||||
- "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
|
||||
- "python -m pip install --disable-pip-version-check -U pip"
|
||||
- "pip install -U tox"
|
||||
|
||||
test_script:
|
||||
- ps: "tox -- --cov mitmproxy --cov pathod -v"
|
||||
- ps: |
|
||||
$Env:VERSION = $(python mitmproxy/version.py)
|
||||
$Env:SKIP_MITMPROXY = "python -c `"print('skip mitmproxy')`""
|
||||
tox -e wheel
|
||||
tox -e rtool -- bdist
|
||||
|
||||
- ps: |
|
||||
if(
|
||||
($Env:TOXENV -match "py35") -and !$Env:APPVEYOR_PULL_REQUEST_NUMBER -and
|
||||
(($Env:APPVEYOR_REPO_BRANCH -In ("master", "pyinstaller")) -or ($Env:APPVEYOR_REPO_TAG -match "true"))
|
||||
) {
|
||||
tox -e rtool -- decrypt release\installbuilder\license.xml.enc release\installbuilder\license.xml
|
||||
if (!(Test-Path "C:\projects\mitmproxy\release\installbuilder-installer.exe")) {
|
||||
"Download InstallBuilder..."
|
||||
(New-Object System.Net.WebClient).DownloadFile(
|
||||
"https://installbuilder.bitrock.com/installbuilder-enterprise-16.11.1-windows-installer.exe",
|
||||
"C:\projects\mitmproxy\release\installbuilder-installer.exe"
|
||||
)
|
||||
}
|
||||
Start-Process "C:\projects\mitmproxy\release\installbuilder-installer.exe" "--mode unattended --unattendedmodeui none" -Wait
|
||||
& 'C:\Program Files (x86)\BitRock InstallBuilder Enterprise 16.11.1\bin\builder-cli.exe' `
|
||||
build `
|
||||
.\release\installbuilder\mitmproxy.xml `
|
||||
windows `
|
||||
--license .\release\installbuilder\license.xml `
|
||||
--setvars project.version=$Env:VERSION `
|
||||
--verbose
|
||||
}
|
||||
|
||||
deploy_script:
|
||||
# we build binaries on every run, but we only upload them for master snapshots or tags.
|
||||
ps: |
|
||||
if(
|
||||
($Env:TOXENV -match "py35") -and
|
||||
(($Env:APPVEYOR_REPO_BRANCH -In ("master", "pyinstaller")) -or ($Env:APPVEYOR_REPO_TAG -match "true"))
|
||||
) {
|
||||
tox -e rtool -- upload-snapshot --bdist --wheel --installer
|
||||
}
|
||||
|
||||
cache:
|
||||
- C:\projects\mitmproxy\release\installbuilder-installer.exe -> .appveyor.yml
|
||||
- C:\Users\appveyor\AppData\Local\pip\cache
|
||||
|
||||
notifications:
|
||||
- provider: Slack
|
||||
incoming_webhook: https://hooks.slack.com/services/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
|
||||
@@ -1 +0,0 @@
|
||||
comment: off
|
||||
6
.coveragerc
Normal file
@@ -0,0 +1,6 @@
|
||||
[rum]
|
||||
branch = True
|
||||
|
||||
[report]
|
||||
omit = *contrib*, *tnetstring*, *platform*, *console*
|
||||
include = *libmproxy*
|
||||
6
.env
@@ -1,6 +0,0 @@
|
||||
DIR="$( dirname "${BASH_SOURCE[0]}" )"
|
||||
ACTIVATE_DIR="$(if [ -f "$DIR/venv/bin/activate" ]; then echo 'bin'; else echo 'Scripts'; fi;)"
|
||||
if [ -z "$VIRTUAL_ENV" ] && [ -f "$DIR/venv/$ACTIVATE_DIR/activate" ]; then
|
||||
echo "Activating mitmproxy virtualenv..."
|
||||
source "$DIR/venv/$ACTIVATE_DIR/activate"
|
||||
fi
|
||||
2
.gitattributes
vendored
@@ -1,2 +0,0 @@
|
||||
mitmproxy/tools/web/static/**/* -diff
|
||||
web/src/js/filt/filt.js -diff
|
||||
28
.gitignore
vendored
@@ -1,21 +1,17 @@
|
||||
.DS_Store
|
||||
MANIFEST
|
||||
**/tmp
|
||||
/venv*
|
||||
/build
|
||||
/dist
|
||||
/tmp
|
||||
/doc
|
||||
/venv
|
||||
/libmproxy/gui
|
||||
/release/build
|
||||
*.py[cdo]
|
||||
*.swp
|
||||
*.swo
|
||||
*.egg-info/
|
||||
.coverage*
|
||||
mitmproxyc
|
||||
mitmdumpc
|
||||
.coverage
|
||||
.idea
|
||||
.cache/
|
||||
.tox*/
|
||||
build/
|
||||
|
||||
# UI
|
||||
|
||||
node_modules
|
||||
bower_components
|
||||
*.map
|
||||
sslkeylogfile.log
|
||||
.tox/
|
||||
netlib
|
||||
libpathod
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
ignore-paths:
|
||||
- docs
|
||||
- examples
|
||||
- mitmproxy/contrib
|
||||
- web
|
||||
max-line-length: 140
|
||||
pylint:
|
||||
options:
|
||||
dummy-variables-rgx: _$|.+_$|dummy_.+
|
||||
disable:
|
||||
- missing-docstring
|
||||
- protected-access
|
||||
- too-few-public-methods
|
||||
- too-many-arguments
|
||||
- too-many-instance-attributes
|
||||
- too-many-locals
|
||||
- too-many-public-methods
|
||||
- too-many-return-statements
|
||||
- too-many-statements
|
||||
- unpacking-non-sequence
|
||||
109
.travis.yml
@@ -1,94 +1,21 @@
|
||||
sudo: false
|
||||
language: python
|
||||
|
||||
env:
|
||||
global:
|
||||
- CI_DEPS=codecov>=2.0.5
|
||||
- CI_COMMANDS=codecov
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
include:
|
||||
- python: 3.5
|
||||
env: TOXENV=lint
|
||||
- os: osx
|
||||
osx_image: xcode7.3
|
||||
language: generic
|
||||
env: TOXENV=py35 BDIST=1
|
||||
- python: 3.5
|
||||
env: TOXENV=py35 OPENSSL_OLD
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libssl-dev
|
||||
- python: 3.5
|
||||
env: TOXENV=py35 BDIST=1 OPENSSL_ALPN
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
# Debian sid currently holds OpenSSL 1.1.0
|
||||
# change this with future releases!
|
||||
- debian-sid
|
||||
packages:
|
||||
- libssl-dev
|
||||
- python: 3.6
|
||||
env: TOXENV=py36 OPENSSL_ALPN
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
# Debian sid currently holds OpenSSL 1.1.0
|
||||
# change this with future releases!
|
||||
- debian-sid
|
||||
packages:
|
||||
- libssl-dev
|
||||
- python: 3.5
|
||||
env: TOXENV=docs
|
||||
git:
|
||||
depth: 10000
|
||||
allow_failures:
|
||||
- python: pypy
|
||||
|
||||
install:
|
||||
- |
|
||||
if [[ $TRAVIS_OS_NAME == "osx" ]]
|
||||
then
|
||||
brew update || brew update
|
||||
brew outdated pyenv || brew upgrade pyenv
|
||||
eval "$(pyenv init -)"
|
||||
env PYTHON_CONFIGURE_OPTS="--enable-framework" pyenv install --skip-existing 3.5.2
|
||||
pyenv global 3.5.2
|
||||
pyenv shell 3.5.2
|
||||
pip install -U pip setuptools wheel virtualenv
|
||||
fi
|
||||
- pip install tox
|
||||
|
||||
script:
|
||||
- tox -- --cov mitmproxy --cov pathod -v
|
||||
- |
|
||||
if [[ $BDIST == "1" ]]
|
||||
then
|
||||
git fetch --unshallow --tags
|
||||
tox -e rtool -- bdist
|
||||
fi
|
||||
|
||||
after_success:
|
||||
# we build binaries on every run, but we only upload them for master snapshots or tags.
|
||||
- |
|
||||
if [[ $BDIST == "1" && $TRAVIS_PULL_REQUEST == "false" && ($TRAVIS_BRANCH == "pyinstaller" || $TRAVIS_BRANCH == "master" || -n $TRAVIS_TAG) ]]
|
||||
then
|
||||
tox -e rtool -- upload-snapshot --bdist
|
||||
fi
|
||||
|
||||
python:
|
||||
- "2.7"
|
||||
# command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors
|
||||
install:
|
||||
- "pip install --upgrade git+https://github.com/mitmproxy/netlib.git"
|
||||
- "pip install --upgrade git+https://github.com/mitmproxy/pathod.git"
|
||||
- "pip install -r requirements.txt --use-mirrors"
|
||||
- "pip install -r test/requirements.txt --use-mirrors"
|
||||
# command to run tests, e.g. python setup.py test
|
||||
script:
|
||||
- "nosetests --with-cov --cov-report term-missing"
|
||||
after_success:
|
||||
- coveralls
|
||||
notifications:
|
||||
slack:
|
||||
-rooms:
|
||||
mitmproxy:YaDGC9Gt9TEM7o8zkC2OLNsu
|
||||
on_success: change
|
||||
on_failure: change
|
||||
on_start: never
|
||||
irc:
|
||||
channels:
|
||||
- "irc.oftc.net#mitmproxy"
|
||||
on_success: change
|
||||
on_failure: always
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.pyenv
|
||||
- $HOME/.cache/pip
|
||||
# - $HOME/build/mitmproxy/mitmproxy/.tox
|
||||
|
||||
456
CHANGELOG
@@ -1,348 +1,10 @@
|
||||
26 December 2016: mitmproxy 1.0
|
||||
26 Februrary 2014: mitmproxy 0.10.1:
|
||||
|
||||
* All mitmproxy tools are now Python 3 only! We plan to support Python 3.5 and higher.
|
||||
|
||||
* Web-Based User Interface: Mitmproxy now offically has a web-based user interface
|
||||
called mitmweb. We consider it stable for all features currently exposed
|
||||
in the UI, but it still misses a lot of mitmproxy’s options.
|
||||
|
||||
* Windows Compatibility: With mitmweb, mitmproxy is now useable on Windows.
|
||||
We are also introducing an installer (kindly sponsored by BitRock) that
|
||||
simplifies setup.
|
||||
|
||||
* Configuration: The config file format is now a single YAML file. In most cases,
|
||||
converting to the new format should be trivial - please see the docs for
|
||||
more information.
|
||||
|
||||
* Console: Significant UI improvements - including sorting of flows by
|
||||
size, type and url, status bar improvements, much faster indentation for
|
||||
HTTP views, and more.
|
||||
|
||||
* HTTP/2: Significant improvements, but is temporarily disabled by default
|
||||
due to wide-spread protocol implementation errors on some large website
|
||||
|
||||
* WebSocket: The protocol implementation is now mature, and is enabled by
|
||||
default. Complete UI support is coming in the next release. Hooks for
|
||||
message interception and manipulation are available.
|
||||
|
||||
* A myriad of other small improvements throughout the project.
|
||||
|
||||
|
||||
16 October 2016: mitmproxy 0.18
|
||||
|
||||
* Python 3 Compatibility for mitmproxy and pathod (Shadab Zafar, GSoC 2016)
|
||||
|
||||
* Major improvements to mitmweb (Clemens Brunner & Jason Hao, GSoC 2016)
|
||||
|
||||
* Internal Core Refactor: Separation of most features into isolated Addons
|
||||
|
||||
* Initial Support for WebSockets
|
||||
|
||||
* Improved HTTP/2 Support
|
||||
|
||||
* Reverse Proxy Mode now automatically adjusts host headers and TLS Server Name Indication
|
||||
|
||||
* Improved HAR export
|
||||
|
||||
* Improved export functionality for curl, python code, raw http etc.
|
||||
|
||||
* Flow URLs are now truncated in the console for better visibility
|
||||
|
||||
* New filters for TCP, HTTP and marked flows.
|
||||
|
||||
* Mitmproxy now handles comma-separated Cookie headers
|
||||
|
||||
* Merge mitmproxy and pathod documentation
|
||||
|
||||
* Mitmdump now sanitizes its console output to not include control characters
|
||||
|
||||
* Improved message body handling for HTTP messages:
|
||||
.raw_content provides the message body as seen on the wire
|
||||
.content provides the decompressed body (e.g. un-gzipped)
|
||||
.text provides the body decompressed and decoded body
|
||||
|
||||
* New HTTP Message getters/setters for cookies and form contents.
|
||||
|
||||
* Add ability to view only marked flows in mitmproxy
|
||||
|
||||
* Improved Script Reloader (Always use polling, watch for whole directory)
|
||||
|
||||
* Use tox for testing
|
||||
|
||||
* Unicode support for tnetstrings
|
||||
|
||||
* Add dumpfile converters for mitmproxy versions 0.11 and 0.12
|
||||
|
||||
* Numerous bugfixes
|
||||
|
||||
|
||||
9 April 2016: mitmproxy 0.17
|
||||
|
||||
* Simplify repository and release structure. mitmproxy now comes as a single package, including netlib and pathod.
|
||||
|
||||
* Rename the Python package from libmproxy to mitmproxy.
|
||||
|
||||
* New option to add server certs to client chain (CVE-2016-2402, John Kozyrakis)
|
||||
|
||||
* Enable HTTP/2 by default (Thomas Kriechbaumer)
|
||||
|
||||
* Improved HAR extractor (Shadab Zafar)
|
||||
|
||||
* Add icon for OSX and Windows binaries
|
||||
|
||||
* Add content view for query parameters (Will Coster)
|
||||
|
||||
* Initial work on Python 3 compatibility
|
||||
|
||||
* locust.io export (Zohar Lorberbaum)
|
||||
|
||||
* Fix XSS vulnerability in HTTP errors (Will Coster)
|
||||
|
||||
* Numerous bugfixes and minor improvements
|
||||
|
||||
|
||||
15 February 2016: mitmproxy 0.16
|
||||
|
||||
* Completely revised HTTP2 implementation based on hyper-h2 (Thomas Kriechbaumer)
|
||||
|
||||
* Export flows as cURL command, Python code or raw HTTP (Shadab Zafar)
|
||||
|
||||
* Fixed compatibility with the Android Emulator (Will Coster)
|
||||
|
||||
* Script Reloader: Inline scripts are reloaded automatically if modified (Matthew Shao)
|
||||
|
||||
* Inline script hooks for TCP mode (Michael J. Bazzinotti)
|
||||
|
||||
* Add default ciphers to support iOS9 App Transport Security (Jorge Villacorta)
|
||||
|
||||
* Basic Authentication for mitmweb (Guillem Anguera)
|
||||
|
||||
* Exempt connections from interception based on TLS Server Name Indication (David Weinstein)
|
||||
|
||||
* Provide Python Wheels for faster installation
|
||||
|
||||
* Numerous bugfixes and minor improvements
|
||||
|
||||
|
||||
4 December 2015: mitmproxy 0.15
|
||||
|
||||
* Support for loading and converting older dumpfile formats (0.13 and up)
|
||||
|
||||
* Content views for inline script (@chrisczub)
|
||||
|
||||
* Better handling of empty header values (Benjamin Lee/@bltb)
|
||||
|
||||
* Fix a gnarly memory leak in mitmdump
|
||||
|
||||
* A number of bugfixes and small improvements
|
||||
|
||||
|
||||
6 November 2015: mitmproxy 0.14
|
||||
|
||||
* Statistics: 399 commits, 13 contributors, 79 closed issues, 37 closed
|
||||
PRs, 103 days
|
||||
|
||||
* Docs: Greatly updated docs now hosted on ReadTheDocs!
|
||||
http://docs.mitmproxy.org
|
||||
|
||||
* Docs: Fixed Typos, updated URLs etc. (Nick Badger, Ben Lerner, Choongwoo
|
||||
Han, onlywade, Jurriaan Bremer)
|
||||
|
||||
* mitmdump: Colorized TTY output
|
||||
|
||||
* mitmdump: Use mitmproxy's content views for human-readable output (Chris
|
||||
Czub)
|
||||
|
||||
* mitmproxy and mitmdump: Support for displaying UTF8 contents
|
||||
|
||||
* mitmproxy: add command line switch to disable mouse interaction (Timothy
|
||||
Elliott)
|
||||
|
||||
* mitmproxy: bug fixes (Choongwoo Han, sethp-jive, FreeArtMan)
|
||||
|
||||
* mitmweb: bug fixes (Colin Bendell)
|
||||
|
||||
* libmproxy: Add ability to fall back to TCP passthrough for non-HTTP
|
||||
connections.
|
||||
|
||||
* libmproxy: Avoid double-connect in case of TLS Server Name Indication.
|
||||
This yields a massive speedup for TLS handshakes.
|
||||
|
||||
* libmproxy: Prevent unneccessary upstream connections (macmantrl)
|
||||
|
||||
* Inline Scripts: New API for HTTP Headers:
|
||||
http://docs.mitmproxy.org/en/latest/dev/models.html#netlib.http.Headers
|
||||
|
||||
* Inline Scripts: Properly handle exceptions in `done` hook
|
||||
|
||||
* Inline Scripts: Allow relative imports, provide `__file__`
|
||||
|
||||
* Examples: Add probabilistic TLS passthrough as an inline script
|
||||
|
||||
* netlib: Refactored HTTP protocol handling code
|
||||
|
||||
* netlib: ALPN support
|
||||
|
||||
* netlib: fixed a bug in the optional certificate verification.
|
||||
|
||||
* netlib: Initial Python 3.5 support (this is the first prerequisite for
|
||||
3.x support in mitmproxy)
|
||||
|
||||
|
||||
24 July 2015: mitmproxy 0.13
|
||||
|
||||
* Upstream certificate validation. See the --verify-upstream-cert,
|
||||
--upstream-trusted-cadir and --upstream-trusted-ca parameters. Thanks to
|
||||
Kyle Morton (github.com/kyle-m) for his work on this.
|
||||
|
||||
* Add HTTP transparent proxy mode. This uses the host headers from HTTP
|
||||
traffic (rather than SNI and IP address information from the OS) to
|
||||
implement perform transparent proxying. Thanks to github.com/ijiro123 for
|
||||
this feature.
|
||||
|
||||
* Add ~src and ~dst REGEX filters, allowing matching on source and
|
||||
destination addresses in the form of <IP>:<Port>
|
||||
|
||||
* mitmproxy console: change g/G keyboard shortcuts to match less. Thanks to
|
||||
Jose Luis Honorato (github.com/jlhonora).
|
||||
|
||||
* mitmproxy console: Flow marking and unmarking. Marked flows are not
|
||||
deleted when the flow list is cleared. Thanks to Jake Drahos
|
||||
(github.com/drahosj).
|
||||
|
||||
* mitmproxy console: add marking of flows
|
||||
|
||||
* Remove the certforward feature. It was added to allow exploitation of
|
||||
#gotofail, which is no longer a common vulnerability. Permitting this
|
||||
hugely increased the complexity of packaging and distributing mitmproxy.
|
||||
|
||||
|
||||
|
||||
|
||||
3 June 2015: mitmproxy 0.12.1
|
||||
|
||||
* mitmproxy console: mouse interaction - scroll in the flow list, click on
|
||||
flow to view, click to switch between tabs.
|
||||
|
||||
* Update our crypto defaults: SHA256, 2048 bit RSA, 4096 bit DH parameters.
|
||||
|
||||
* BUGFIX: crash under some circumstances when copying to clipboard.
|
||||
|
||||
* BUGFIX: occasional crash when deleting flows.
|
||||
|
||||
|
||||
18 May 2015: mitmproxy 0.12
|
||||
|
||||
* mitmproxy console: Significant revamp of the UI. The major changes are
|
||||
listed below, and in addition almost every aspect of the UI has
|
||||
been tweaked, and performance has improved significantly.
|
||||
|
||||
* mitmproxy console: A new options screen has been created ("o" shortcut),
|
||||
and many options that were previously manipulated directly via a
|
||||
keybinding have been moved there.
|
||||
|
||||
* mitmproxy console: Big improvement in palettes. This includes improvements
|
||||
to all colour schemes. Palettes now set the terminal background colour by
|
||||
default, and a new --palette-transparent option has been added to disable
|
||||
this.
|
||||
|
||||
* mitmproxy console: g/G shortcuts throughout mitmproxy console to jump
|
||||
to the beginning/end of the current view.
|
||||
|
||||
* mitmproxy console: switch palettes on the fly from the options screen.
|
||||
|
||||
* mitmproxy console: A cookie editor has been added for mitmproxy console
|
||||
at long last.
|
||||
|
||||
* mitmproxy console: Various components of requests and responses can be
|
||||
copied to the clipboard from mitmproxy - thanks to @marceloglezer.
|
||||
|
||||
* Support for creating new requests from scratch in mitmproxy console (@marceloglezer).
|
||||
|
||||
* SSLKEYLOGFILE environment variable to specify a logging location for TLS
|
||||
master keys. This can be used with tools like Wireshark to allow TLS
|
||||
decoding.
|
||||
|
||||
* Server facing SSL cipher suite specification (thanks to Jim Shaver).
|
||||
|
||||
* Official support for transparent proxying on FreeBSD - thanks to Mike C
|
||||
(http://github.com/mike-pt).
|
||||
|
||||
* Many other small bugfixes and improvemenets throughout the project.
|
||||
|
||||
|
||||
29 Dec 2014: mitmproxy 0.11.2:
|
||||
|
||||
* Configuration files - mitmproxy.conf, mitmdump.conf, common.conf in the
|
||||
.mitmproxy directory.
|
||||
* Better handling of servers that reject connections that are not SNI.
|
||||
* Many other small bugfixes and improvements.
|
||||
|
||||
|
||||
15 November 2014: mitmproxy 0.11.1:
|
||||
|
||||
* Bug fixes: connection leaks some crashes
|
||||
|
||||
|
||||
7 November 2014: mitmproxy 0.11:
|
||||
|
||||
* Performance improvements for mitmproxy console
|
||||
|
||||
* SOCKS5 proxy mode allows mitmproxy to act as a SOCKS5 proxy server
|
||||
|
||||
* Data streaming for response bodies exceeding a threshold
|
||||
(bradpeabody@gmail.com)
|
||||
|
||||
* Ignore hosts or IP addresses, forwarding both HTTP and HTTPS traffic
|
||||
untouched
|
||||
|
||||
* Finer-grained control of traffic replay, including options to ignore
|
||||
contents or parameters when matching flows (marcelo.glezer@gmail.com)
|
||||
|
||||
* Pass arguments to inline scripts
|
||||
|
||||
* Configurable size limit on HTTP request and response bodies
|
||||
|
||||
* Per-domain specification of interception certificates and keys (see
|
||||
--cert option)
|
||||
|
||||
* Certificate forwarding, relaying upstream SSL certificates verbatim (see
|
||||
--cert-forward)
|
||||
|
||||
* Search and highlighting for HTTP request and response bodies in
|
||||
mitmproxy console (pedro@worcel.com)
|
||||
|
||||
* Transparent proxy support on Windows
|
||||
|
||||
* Improved error messages and logging
|
||||
|
||||
* Support for FreeBSD in transparent mode, using pf (zbrdge@gmail.com)
|
||||
|
||||
* Content view mode for WBXML (davidshaw835@air-watch.com)
|
||||
|
||||
* Better documentation, with a new section on proxy modes
|
||||
|
||||
* Generic TCP proxy mode
|
||||
|
||||
* Countless bugfixes and other small improvements
|
||||
|
||||
* pathod: Hugely improved SSL support, including dynamic generation of certificates
|
||||
using the mitproxy cacert
|
||||
|
||||
7 November 2014: pathod 0.11:
|
||||
|
||||
* Hugely improved SSL support, including dynamic generation of certificates
|
||||
using the mitproxy cacert
|
||||
|
||||
* pathoc -S dumps information on the remote SSL certificate chain
|
||||
|
||||
* Big improvements to fuzzing, including random spec selection and memoization to avoid repeating randomly generated patterns
|
||||
|
||||
* Reflected patterns, allowing you to embed a pathod server response specification in a pathoc request, resolving both on client side. This makes fuzzing proxies and other intermediate systems much better.
|
||||
* Fix compatibility with pyOpenSSL 0.14
|
||||
|
||||
|
||||
28 January 2014: mitmproxy 0.10:
|
||||
|
||||
|
||||
* Support for multiple scripts and multiple script arguments
|
||||
|
||||
* Easy certificate install through the in-proxy web app, which is now
|
||||
@@ -362,7 +24,7 @@
|
||||
25 August 2013: mitmproxy 0.9.2:
|
||||
|
||||
* Improvements to the mitmproxywrapper.py helper script for OSX.
|
||||
|
||||
|
||||
* Don't take minor version into account when checking for serialized file
|
||||
compatibility.
|
||||
|
||||
@@ -376,41 +38,38 @@
|
||||
valid IDNA-encoded names.
|
||||
|
||||
* Display transfer rates for responses in the flow list.
|
||||
|
||||
|
||||
* Many other small bugfixes and improvements.
|
||||
|
||||
|
||||
|
||||
25 August 2013: pathod 0.9.2:
|
||||
|
||||
* Adapt to interface changes in netlib
|
||||
|
||||
|
||||
16 June 2013: mitmproxy 0.9.1:
|
||||
|
||||
* Use "correct" case for Content-Type headers added by mitmproxy.
|
||||
|
||||
* Make UTF environment detection more robust.
|
||||
|
||||
* Make UTF environment detection more robust.
|
||||
|
||||
* Improved MIME-type detection for viewers.
|
||||
|
||||
|
||||
* Always read files in binary mode (Windows compatibility fix).
|
||||
|
||||
|
||||
* Some developer documentation.
|
||||
|
||||
|
||||
|
||||
15 May 2013: mitmproxy 0.9:
|
||||
|
||||
* Upstream certs mode is now the default.
|
||||
|
||||
* Add a WSGI container that lets you host in-proxy web applications.
|
||||
|
||||
|
||||
* Full transparent proxy support for Linux and OSX.
|
||||
|
||||
|
||||
* Introduce netlib, a common codebase for mitmproxy and pathod
|
||||
(http://github.com/cortesi/netlib).
|
||||
|
||||
* Full support for SNI.
|
||||
|
||||
|
||||
* Color palettes for mitmproxy, tailored for light and dark terminal
|
||||
backgrounds.
|
||||
|
||||
@@ -421,12 +80,12 @@
|
||||
match asset flows (js, images, css).
|
||||
|
||||
* Follow mode in mitmproxy ("F" shortcut) to "tail" flows as they arrive.
|
||||
|
||||
|
||||
* --dummy-certs option to specify and preserve the dummy certificate
|
||||
directory.
|
||||
|
||||
* Server replay from the current captured buffer.
|
||||
|
||||
|
||||
* Huge improvements in content views. We now have viewers for AMF, HTML,
|
||||
JSON, Javascript, images, XML, URL-encoded forms, as well as hexadecimal
|
||||
and raw views.
|
||||
@@ -435,93 +94,12 @@
|
||||
on flows, based on a matching pattern.
|
||||
|
||||
* A graphical editor for path components in mitmproxy.
|
||||
|
||||
|
||||
* A small set of standard user-agent strings, which can be used easily in
|
||||
the header editor.
|
||||
|
||||
* Proxy authentication to limit access to mitmproxy
|
||||
|
||||
* pathod: Proxy mode. You can now configure clients to use pathod as an
|
||||
HTTP/S proxy.
|
||||
|
||||
* pathoc: Proxy support, including using CONNECT to tunnel directly to
|
||||
targets.
|
||||
|
||||
* pathoc: client certificate support.
|
||||
|
||||
* pathod: API improvements, bugfixes.
|
||||
|
||||
|
||||
15 May 2013: pathod 0.9 (version synced with mitmproxy):
|
||||
|
||||
* Pathod proxy mode. You can now configure clients to use pathod as an
|
||||
HTTP/S proxy.
|
||||
|
||||
* Pathoc proxy support, including using CONNECT to tunnel directly to
|
||||
targets.
|
||||
|
||||
* Pathoc client certificate support.
|
||||
|
||||
* API improvements, bugfixes.
|
||||
|
||||
|
||||
16 November 2012: pathod 0.3:
|
||||
|
||||
A release focusing on shoring up our fuzzing capabilities, especially with
|
||||
pathoc.
|
||||
|
||||
* pathoc -q and -r options, output full request and response text.
|
||||
|
||||
* pathod -q and -r options, add full request and response text to pathod's
|
||||
log buffer.
|
||||
|
||||
* pathoc and pathod -x option, makes -q and -r options log in hex dump
|
||||
format.
|
||||
|
||||
* pathoc -C option, specify response codes to ignore.
|
||||
|
||||
* pathoc -T option, instructs pathoc to ignore timeouts.
|
||||
|
||||
* pathoc -o option, a one-shot mode that exits after the first non-ignored
|
||||
response.
|
||||
|
||||
* pathoc and pathod -e option, which explains the resulting message by
|
||||
expanding random and generated portions, and logging a reproducible
|
||||
specification.
|
||||
|
||||
* Streamline the specification langauge. HTTP response message is now
|
||||
specified using the "r" mnemonic.
|
||||
|
||||
* Add a "u" mnemonic for specifying User-Agent strings. Add a set of
|
||||
standard user-agent strings accessible through shortcuts.
|
||||
|
||||
* Major internal refactoring and cleanup.
|
||||
|
||||
* Many bugfixes.
|
||||
|
||||
|
||||
22 August 2012: pathod 0.2:
|
||||
|
||||
* Add pathoc, a pathological HTTP client.
|
||||
|
||||
* Add libpathod.test, a truss for using pathod in unit tests.
|
||||
|
||||
* Add an injection operator to the specification language.
|
||||
|
||||
* Allow Python escape sequences in value literals.
|
||||
|
||||
* Allow execution of requests and responses from file, using the new + operator.
|
||||
|
||||
* Add daemonization to Pathod, and make it more robust for public-facing use.
|
||||
|
||||
* Let pathod pick an arbitrary open port if -p 0 is specified.
|
||||
|
||||
* Move from Tornado to netlib, the network library written for mitmproxy.
|
||||
|
||||
* Move the web application to Flask.
|
||||
|
||||
* Massively expand the documentation.
|
||||
|
||||
|
||||
5 April 2012: mitmproxy 0.8:
|
||||
|
||||
|
||||
194
CONTRIBUTORS
@@ -1,189 +1,51 @@
|
||||
2407 Aldo Cortesi
|
||||
1873 Maximilian Hils
|
||||
556 Thomas Kriechbaumer
|
||||
258 Shadab Zafar
|
||||
97 Jason
|
||||
83 Marcelo Glezer
|
||||
68 Clemens
|
||||
28 Jim Shaver
|
||||
854 Aldo Cortesi
|
||||
64 Maximilian Hils
|
||||
18 Henrik Nordstrom
|
||||
16 Matthew Shao
|
||||
14 Pedro Worcel
|
||||
14 David Weinstein
|
||||
13 Thomas Roth
|
||||
11 Jake Drahos
|
||||
11 Stephen Altamirano
|
||||
11 arjun23496
|
||||
11 Justus Wingert
|
||||
10 András Veres-Szentkirályi
|
||||
10 Zohar Lorberbaum
|
||||
10 smill
|
||||
10 Chris Czub
|
||||
10 Sandor Nemes
|
||||
10 Doug Freed
|
||||
9 ikoz
|
||||
9 Legend Tang
|
||||
9 Rouli
|
||||
9 Kyle Morton
|
||||
8 Jason A. Novak
|
||||
8 Chandler Abraham
|
||||
7 Matthias Urlichs
|
||||
7 Brad Peabody
|
||||
7 dufferzafar
|
||||
8 Rouli
|
||||
7 Alexis Hildebrandt
|
||||
6 Felix Yan
|
||||
5 Will Coster
|
||||
5 Sam Cleveland
|
||||
5 iroiro123
|
||||
5 elitest
|
||||
6 Pedro Worcel
|
||||
5 Tomaz Muraus
|
||||
5 Choongwoo Han
|
||||
4 Schamper
|
||||
4 Youhei Sakurai
|
||||
4 Bryan Bishop
|
||||
5 Matthias Urlichs
|
||||
4 root
|
||||
4 Valtteri Virtanen
|
||||
4 Clemens Brunner
|
||||
4 Bryan Bishop
|
||||
4 Marc Liyanage
|
||||
4 Wade 524
|
||||
4 chhsiao90
|
||||
4 yonder
|
||||
4 Michael J. Bazzinotti
|
||||
3 Ryan Welton
|
||||
3 Ryan Laughlin
|
||||
4 Valtteri Virtanen
|
||||
3 Kyle Manna
|
||||
3 Eli Shvartsman
|
||||
3 Vincent Haupert
|
||||
3 Manish Kumar
|
||||
3 Zack B
|
||||
3 MatthewShao
|
||||
3 redfast00
|
||||
3 requires.io
|
||||
3 Guillem Anguera
|
||||
3 smill@cuckoo.sh
|
||||
3 Chris Neasbitt
|
||||
3 Benjamin Lee
|
||||
2 Steven Van Acker
|
||||
2 Slobodan Mišković
|
||||
2 Jim Lloyd
|
||||
2 isra17
|
||||
2 israel
|
||||
2 Sean Coates
|
||||
2 Sachin Kelkar
|
||||
2 jpkrause
|
||||
2 Bennett Blodinger
|
||||
2 lilydjwg
|
||||
2 Michael Frister
|
||||
2 Israel Nir
|
||||
2 Cory Benfield
|
||||
2 phackt
|
||||
2 Anant
|
||||
2 Jaime Soriano Pastor
|
||||
2 Paul
|
||||
2 Colin Bendell
|
||||
2 依云
|
||||
2 Heikki Hannikainen
|
||||
2 Rob Wills
|
||||
2 Niko Kommenda
|
||||
2 Naveen Pai
|
||||
2 strohu
|
||||
2 alts
|
||||
2 Yoginski
|
||||
2 Heikki Hannikainen
|
||||
2 Jim Lloyd
|
||||
2 Michael Frister
|
||||
2 Rob Wills
|
||||
2 Jaime Soriano Pastor
|
||||
2 israel
|
||||
2 Mark E. Haase
|
||||
2 Wade Catron
|
||||
2 Terry Long
|
||||
2 Krzysztof Bielicki
|
||||
2 Nick Badger
|
||||
1 Nicolas Esteves
|
||||
1 Andrew Orr
|
||||
1 Andrey Plotnikov
|
||||
1 Andy Smith
|
||||
1 Angelo Agatino Nicolosi
|
||||
1 Anthony Zhang
|
||||
1 BSalita
|
||||
1 Ben Lerner
|
||||
1 Bradley Baetz
|
||||
1 Brady Law
|
||||
1 Brett Randall
|
||||
1 Chris Hamant
|
||||
1 Christian Frichot
|
||||
1 Dan Wilbraham
|
||||
1 David Dworken
|
||||
1 David Shaw
|
||||
1 Doug Lethin
|
||||
1 Drake Caraker
|
||||
1 Edgar Boda-Majer
|
||||
1 Eric Entzel
|
||||
1 Felix Wolfsteller
|
||||
1 FreeArtMan
|
||||
1 Gabriel Kirkpatrick
|
||||
1 Henrik Nordström
|
||||
1 Israel Blancas
|
||||
1 Ivaylo Popov
|
||||
1 JC
|
||||
1 Jakub Nawalaniec
|
||||
1 Jakub Wilk
|
||||
1 James Billingham
|
||||
1 Jason Pepas
|
||||
1 Jean Regisser
|
||||
1 Jonathan Jones
|
||||
1 Jorge Villacorta
|
||||
1 Kit Randel
|
||||
1 Kostya Esmukov
|
||||
1 Linmiao Xu
|
||||
1 Lucas Cimon
|
||||
1 M. Utku Altinkaya
|
||||
1 Mathieu Mitchell
|
||||
1 Michael Bisbjerg
|
||||
1 Mike C
|
||||
1 Mike Fotinakis
|
||||
1 Mikhail Korobov
|
||||
1 Morton Fox
|
||||
1 Nick HS
|
||||
1 Nick Raptis
|
||||
1 Aditya
|
||||
1 Oleksandr Sheremet
|
||||
1 Parth Ganatra
|
||||
1 Pritam Baral
|
||||
1 Quentin Pradet
|
||||
1 Paul
|
||||
1 Rich Somerfield
|
||||
1 Rory McCann
|
||||
1 Felix Wolfsteller
|
||||
1 Rune Halvorsen
|
||||
1 Ryo Onodera
|
||||
1 Sahil Chelaramani
|
||||
1 Sahn Lam
|
||||
1 Sanchit Sokhey
|
||||
1 Seppo Yli-Olli
|
||||
1 Sergey Chipiga
|
||||
1 Stefan Wärting
|
||||
1 Steve Phillips
|
||||
1 Steven Noble
|
||||
1 Suyash
|
||||
1 Tai Dickerson
|
||||
1 Tarashish Mishra
|
||||
1 TearsDontFalls
|
||||
1 Thiago Arrais
|
||||
1 Tim Becker
|
||||
1 Timothy Elliott
|
||||
1 Tyler St. Onge
|
||||
1 Eric Entzel
|
||||
1 Dan Wilbraham
|
||||
1 Ulrich Petri
|
||||
1 Vyacheslav Bakhmutov
|
||||
1 Wes Turner
|
||||
1 Andy Smith
|
||||
1 Yuangxuan Wang
|
||||
1 capt8bit
|
||||
1 cle1000
|
||||
1 davidpshaw
|
||||
1 deployable
|
||||
1 gecko655
|
||||
1 jlhonora
|
||||
1 joebowbeer
|
||||
1 kronick
|
||||
1 meeee
|
||||
1 michaeljau
|
||||
1 peralta
|
||||
1 James Billingham
|
||||
1 Jakub Nawalaniec
|
||||
1 JC
|
||||
1 Kit Randel
|
||||
1 phil plante
|
||||
1 sentient07
|
||||
1 sethp-jive
|
||||
1 starenka
|
||||
1 vulnminer
|
||||
1 vzvu3k6k
|
||||
1 Mathieu Mitchell
|
||||
1 Ivaylo Popov
|
||||
1 Henrik Nordström
|
||||
1 Michael Bisbjerg
|
||||
1 Nicolas Esteves
|
||||
1 Oleksandr Sheremet
|
||||
|
||||
14
MANIFEST.in
@@ -1,3 +1,11 @@
|
||||
graft mitmproxy
|
||||
graft pathod
|
||||
recursive-exclude * *.pyc *.pyo *.swo *.swp *.map
|
||||
include LICENSE
|
||||
include CHANGELOG
|
||||
include CONTRIBUTORS
|
||||
include README.txt
|
||||
include setup.py
|
||||
exclude README.mkd
|
||||
recursive-include examples *
|
||||
recursive-include doc *
|
||||
recursive-include test *
|
||||
recursive-include libmproxy/resources *
|
||||
recursive-exclude test *.swo *.swp *.pyc
|
||||
|
||||
61
README.mkd
Normal file
@@ -0,0 +1,61 @@
|
||||
[](https://travis-ci.org/mitmproxy/mitmproxy) [](https://coveralls.io/r/mitmproxy/mitmproxy)
|
||||
|
||||
__mitmproxy__ is an interactive, SSL-capable man-in-the-middle proxy for HTTP
|
||||
with a console interface.
|
||||
|
||||
__mitmdump__ is the command-line version of mitmproxy. Think tcpdump for HTTP.
|
||||
|
||||
__libmproxy__ is the library that mitmproxy and mitmdump are built on.
|
||||
|
||||
Documentation, tutorials and distribution packages can be found on the
|
||||
mitmproxy.org website:
|
||||
|
||||
[mitmproxy.org](http://mitmproxy.org).
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- Intercept HTTP requests and responses and modify them on the fly.
|
||||
- Save complete HTTP conversations for later replay and analysis.
|
||||
- Replay the client-side of an HTTP conversations.
|
||||
- Replay HTTP responses of a previously recorded server.
|
||||
- Reverse proxy mode to forward traffic to a specified server.
|
||||
- Transparent proxy mode on OSX and Linux.
|
||||
- Make scripted changes to HTTP traffic using Python.
|
||||
- SSL certificates for interception are generated on the fly.
|
||||
- And much, much more.
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
* [Python](http://www.python.org) 2.7.x.
|
||||
* [netlib](http://pypi.python.org/pypi/netlib), version matching mitmproxy.
|
||||
* Third-party packages listed in [setup.py](https://github.com/mitmproxy/mitmproxy/blob/master/setup.py)
|
||||
|
||||
Optional packages for extended content decoding:
|
||||
|
||||
* [PyAMF](http://www.pyamf.org/) version 0.6.1 or newer.
|
||||
* [protobuf](https://code.google.com/p/protobuf/) version 2.5.0 or newer.
|
||||
* [cssutils](http://cthedot.de/cssutils/) version 1.0 or newer.
|
||||
|
||||
__mitmproxy__ is tested and developed on OSX, Linux and OpenBSD. Windows is not
|
||||
officially supported at the moment.
|
||||
|
||||
|
||||
Hacking
|
||||
-------
|
||||
|
||||
The following components are needed if you plan to hack on mitmproxy:
|
||||
|
||||
* The test suite uses the [nose](http://readthedocs.org/docs/nose/en/latest/) unit testing
|
||||
framework and requires [pathod](http://pathod.org) and [flask](http://flask.pocoo.org/).
|
||||
* Rendering the documentation requires [countershape](http://github.com/cortesi/countershape).
|
||||
|
||||
For convenience, all dependencies save countershape can be installed from pypi
|
||||
to a virtualenv with 'pip install -r requirements.txt'.
|
||||
|
||||
Please ensure that all patches are accompanied by matching changes in the test
|
||||
suite. The project maintains 100% test coverage.
|
||||
|
||||
193
README.rst
@@ -1,193 +0,0 @@
|
||||
mitmproxy
|
||||
^^^^^^^^^
|
||||
|
||||
|travis| |appveyor| |coverage| |latest_release| |python_versions|
|
||||
|
||||
This repository contains the **mitmproxy** and **pathod** projects.
|
||||
|
||||
``mitmproxy`` is an interactive, SSL-capable intercepting proxy with a console
|
||||
interface.
|
||||
|
||||
``mitmdump`` is the command-line version of mitmproxy. Think tcpdump for HTTP.
|
||||
|
||||
``pathoc`` and ``pathod`` are perverse HTTP client and server applications
|
||||
designed to let you craft almost any conceivable HTTP request, including ones
|
||||
that creatively violate the standards.
|
||||
|
||||
|
||||
Documentation & Help
|
||||
--------------------
|
||||
|
||||
|
||||
General information, tutorials, and precompiled binaries can be found on the mitmproxy
|
||||
and pathod websites.
|
||||
|
||||
|mitmproxy_site|
|
||||
|
||||
The latest documentation for mitmproxy is also available on ReadTheDocs.
|
||||
|
||||
|mitmproxy_docs|
|
||||
|
||||
|
||||
Join our discussion forum on Discourse to ask questions, help
|
||||
each other solve problems, and come up with new ideas for the project.
|
||||
|
||||
|mitmproxy_discourse|
|
||||
|
||||
|
||||
Join our developer chat on Slack if you would like to hack on mitmproxy itself.
|
||||
|
||||
|slack|
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
The installation instructions are `here <http://docs.mitmproxy.org/en/stable/install.html>`__.
|
||||
If you want to contribute changes, keep on reading.
|
||||
|
||||
|
||||
Hacking
|
||||
-------
|
||||
|
||||
To get started hacking on mitmproxy, make sure you have Python_ 3.5.x or above with
|
||||
virtualenv_ installed (you can find installation instructions for virtualenv
|
||||
`here <http://virtualenv.readthedocs.org/en/latest/>`__). Then do the following:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
git clone https://github.com/mitmproxy/mitmproxy.git
|
||||
cd mitmproxy
|
||||
./dev.sh # powershell .\dev.ps1 on Windows
|
||||
|
||||
|
||||
The *dev* script will create a virtualenv environment in a directory called
|
||||
"venv", and install all mandatory and optional dependencies into it. The
|
||||
primary mitmproxy components - mitmproxy and pathod - are installed as
|
||||
"editable", so any changes to the source in the repository will be reflected
|
||||
live in the virtualenv.
|
||||
|
||||
To confirm that you're up and running, activate the virtualenv, and run the
|
||||
mitmproxy test suite:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
. venv/bin/activate # venv\Scripts\activate on Windows
|
||||
py.test
|
||||
|
||||
Note that the main executables for the project - ``mitmdump``, ``mitmproxy``,
|
||||
``mitmweb``, ``pathod``, and ``pathoc`` - are all created within the
|
||||
virtualenv. After activating the virtualenv, they will be on your $PATH, and
|
||||
you can run them like any other command:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
mitmdump --version
|
||||
|
||||
For convenience, the project includes an autoenv_ file (`.env`_) that
|
||||
auto-activates the virtualenv when you cd into the mitmproxy directory.
|
||||
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
If you've followed the procedure above, you already have all the development
|
||||
requirements installed, and you can simply run the test suite:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
py.test
|
||||
|
||||
Please ensure that all patches are accompanied by matching changes in the test
|
||||
suite. The project tries to maintain 100% test coverage.
|
||||
|
||||
You can also use `tox` to run the full suite of tests, including a quick test
|
||||
to check documentation and code linting.
|
||||
|
||||
The following tox environments are relevant for local testing:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
tox -e py35 # runs all tests with Python 3.5
|
||||
tox -e docs # runs a does-it-compile check on the documentation
|
||||
tox -e lint # runs the linter for coding style checks
|
||||
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
The mitmproxy documentation is build using Sphinx_, which is installed
|
||||
automatically if you set up a development environment as described above. After
|
||||
installation, you can render the documentation like this:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
cd docs
|
||||
make clean
|
||||
make html
|
||||
make livehtml
|
||||
|
||||
The last command invokes `sphinx-autobuild`_, which watches the Sphinx directory and rebuilds
|
||||
the documentation when a change is detected.
|
||||
|
||||
Style
|
||||
-----
|
||||
|
||||
Keeping to a consistent code style throughout the project makes it easier to
|
||||
contribute and collaborate. Please stick to the guidelines in
|
||||
`PEP8`_ and the `Google Style Guide`_ unless there's a very
|
||||
good reason not to.
|
||||
|
||||
This is automatically enforced on every PR. If we detect a linting error, the
|
||||
PR checks will fail and block merging. You can run our lint checks yourself
|
||||
with the following command:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
tox -e lint
|
||||
|
||||
|
||||
.. |mitmproxy_site| image:: https://shields.mitmproxy.org/api/https%3A%2F%2F-mitmproxy.org-blue.svg
|
||||
:target: https://mitmproxy.org/
|
||||
:alt: mitmproxy.org
|
||||
|
||||
.. |mitmproxy_docs| image:: https://readthedocs.org/projects/mitmproxy/badge/
|
||||
:target: http://docs.mitmproxy.org/en/latest/
|
||||
:alt: mitmproxy documentation
|
||||
|
||||
.. |mitmproxy_discourse| image:: https://shields.mitmproxy.org/api/https%3A%2F%2F-discourse.mitmproxy.org-orange.svg
|
||||
:target: https://discourse.mitmproxy.org
|
||||
:alt: Discourse: mitmproxy
|
||||
|
||||
.. |slack| image:: http://slack.mitmproxy.org/badge.svg
|
||||
:target: http://slack.mitmproxy.org/
|
||||
:alt: Slack Developer Chat
|
||||
|
||||
.. |travis| image:: https://shields.mitmproxy.org/travis/mitmproxy/mitmproxy/master.svg?label=Travis%20build
|
||||
:target: https://travis-ci.org/mitmproxy/mitmproxy
|
||||
:alt: Travis Build Status
|
||||
|
||||
.. |appveyor| image:: https://shields.mitmproxy.org/appveyor/ci/mhils/mitmproxy/master.svg?label=Appveyor%20build
|
||||
:target: https://ci.appveyor.com/project/mhils/mitmproxy
|
||||
:alt: Appveyor Build Status
|
||||
|
||||
.. |coverage| image:: https://codecov.io/gh/mitmproxy/mitmproxy/branch/master/graph/badge.svg
|
||||
:target: https://codecov.io/gh/mitmproxy/mitmproxy
|
||||
:alt: Coverage Status
|
||||
|
||||
.. |latest_release| image:: https://shields.mitmproxy.org/pypi/v/mitmproxy.svg
|
||||
:target: https://pypi.python.org/pypi/mitmproxy
|
||||
:alt: Latest Version
|
||||
|
||||
.. |python_versions| image:: https://shields.mitmproxy.org/pypi/pyversions/mitmproxy.svg
|
||||
:target: https://pypi.python.org/pypi/mitmproxy
|
||||
:alt: Supported Python versions
|
||||
|
||||
.. _Python: https://www.python.org/
|
||||
.. _virtualenv: http://virtualenv.readthedocs.org/en/latest/
|
||||
.. _autoenv: https://github.com/kennethreitz/autoenv
|
||||
.. _.env: https://github.com/mitmproxy/mitmproxy/blob/master/.env
|
||||
.. _Sphinx: http://sphinx-doc.org/
|
||||
.. _sphinx-autobuild: https://pypi.python.org/pypi/sphinx-autobuild
|
||||
.. _PEP8: https://www.python.org/dev/peps/pep-0008
|
||||
.. _Google Style Guide: https://google.github.io/styleguide/pyguide.html
|
||||
11
README.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
**mitmproxy** is an interactive, SSL-capable man-in-the-middle proxy for HTTP
|
||||
with a console interface.
|
||||
|
||||
**mitmdump** is the command-line version of mitmproxy. Think tcpdump for HTTP.
|
||||
|
||||
**libmproxy** is the library that mitmproxy and mitmdump are built on.
|
||||
|
||||
Complete documentation and a set of practical tutorials is included in the
|
||||
distribution package, and is also available at mitmproxy.org_.
|
||||
|
||||
.. _mitmproxy.org: http://mitmproxy.org
|
||||
21
dev.ps1
@@ -1,21 +0,0 @@
|
||||
$ErrorActionPreference = "Stop"
|
||||
$VENV = ".\venv"
|
||||
|
||||
$pyver = python --version
|
||||
if($pyver -notmatch "3\.[5-9]") {
|
||||
Write-Warning "Unexpected Python version, expected Python 3.5 or above: $pyver"
|
||||
}
|
||||
|
||||
python -m venv $VENV --copies
|
||||
& $VENV\Scripts\activate.ps1
|
||||
|
||||
python -m pip install --disable-pip-version-check -U pip
|
||||
cmd /c "pip install -r requirements.txt 2>&1"
|
||||
|
||||
echo @"
|
||||
|
||||
* Created virtualenv environment in $VENV.
|
||||
* Installed all dependencies into the virtualenv.
|
||||
* Activated virtualenv environment.
|
||||
|
||||
"@
|
||||
17
dev.sh
@@ -1,17 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
set -x
|
||||
|
||||
PYVERSION=${1:-3.5}
|
||||
VENV="venv$PYVERSION"
|
||||
|
||||
echo "Creating dev environment in $VENV using Python $PYVERSION"
|
||||
|
||||
python$PYVERSION -m venv "$VENV"
|
||||
. "$VENV/bin/activate"
|
||||
pip$PYVERSION install -U pip setuptools
|
||||
pip$PYVERSION install -r requirements.txt
|
||||
|
||||
echo ""
|
||||
echo "* Virtualenv created in $VENV and all dependencies installed."
|
||||
echo "* You can now activate the $(python --version) virtualenv with this command: \`. $VENV/bin/activate\`"
|
||||
9
doc-src/01-bootstrap.min.css
vendored
Normal file
20
doc-src/02-docstyle.css
Normal file
@@ -0,0 +1,20 @@
|
||||
body {
|
||||
padding-top: 60px;
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
|
||||
.tablenum {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.nowrap {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
h1 {
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
margin: 0px 0 22px;
|
||||
}
|
||||
36
doc-src/_layout.html
Normal file
@@ -0,0 +1,36 @@
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
<a class="brand" href="@!urlTo(idxpath)!@">mitmproxy $!VERSION!$ docs</a>
|
||||
</div><!--/.nav-collapse -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="span3">
|
||||
<div class="well sidebar-nav">
|
||||
$!navbar!$
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="span9">
|
||||
<div class="page-header">
|
||||
<h1>@!this.title!@</h1>
|
||||
</div>
|
||||
$!body!$
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<footer>
|
||||
<p>@!copyright!@</p>
|
||||
</footer>
|
||||
</div>
|
||||
50
doc-src/_nav.html
Normal file
@@ -0,0 +1,50 @@
|
||||
<ul class="nav nav-list">
|
||||
$!nav(idxpath, this, state)!$
|
||||
$!nav("install.html", this, state)!$
|
||||
$!nav("howmitmproxy.html", this, state)!$
|
||||
|
||||
<li class="nav-header">Tools</li>
|
||||
$!nav("mitmproxy.html", this, state)!$
|
||||
$!nav("mitmdump.html", this, state)!$
|
||||
|
||||
<li class="nav-header">Features</li>
|
||||
$!nav("anticache.html", this, state)!$
|
||||
$!nav("clientreplay.html", this, state)!$
|
||||
$!nav("filters.html", this, state)!$
|
||||
$!nav("forwardproxy.html", this, state)!$
|
||||
$!nav("proxyauth.html", this, state)!$
|
||||
$!nav("replacements.html", this, state)!$
|
||||
$!nav("serverreplay.html", this, state)!$
|
||||
$!nav("setheaders.html", this, state)!$
|
||||
$!nav("sticky.html", this, state)!$
|
||||
$!nav("reverseproxy.html", this, state)!$
|
||||
$!nav("upstreamcerts.html", this, state)!$
|
||||
|
||||
<li class="nav-header">Installing Certificates</li>
|
||||
$!nav("ssl.html", this, state)!$
|
||||
$!nav("certinstall/webapp.html", this, state)!$
|
||||
$!nav("certinstall/android.html", this, state)!$
|
||||
$!nav("certinstall/firefox.html", this, state)!$
|
||||
$!nav("certinstall/ios.html", this, state)!$
|
||||
$!nav("certinstall/ios-simulator.html", this, state)!$
|
||||
$!nav("certinstall/java.html", this, state)!$
|
||||
$!nav("certinstall/osx.html", this, state)!$
|
||||
$!nav("certinstall/windows7.html", this, state)!$
|
||||
|
||||
<li class="nav-header">Transparent Proxying</li>
|
||||
$!nav("transparent.html", this, state)!$
|
||||
$!nav("transparent/linux.html", this, state)!$
|
||||
$!nav("transparent/osx.html", this, state)!$
|
||||
|
||||
<li class="nav-header">Scripting mitmproxy</li>
|
||||
$!nav("scripting/inlinescripts.html", this, state)!$
|
||||
$!nav("scripting/libmproxy.html", this, state)!$
|
||||
|
||||
<li class="nav-header">Tutorials</li>
|
||||
$!nav("tutorials/30second.html", this, state)!$
|
||||
$!nav("tutorials/gamecenter.html", this, state)!$
|
||||
$!nav("tutorials/transparent-dhcp.html", this, state)!$
|
||||
|
||||
<li class="nav-header">Hacking</li>
|
||||
$!nav("dev/testing.html", this, state)!$
|
||||
</ul>
|
||||
42
doc-src/_websitelayout.html
Normal file
@@ -0,0 +1,42 @@
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
<a class="brand" href="@!urlTo(idxpath)!@">mitmproxy</a>
|
||||
<div class="nav">
|
||||
<ul class="nav">
|
||||
<li $!'class="active"' if this.match("/index.html", True) else ""!$> <a href="@!top!@/index.html">home</a> </li>
|
||||
<li $!'class="active"' if this.under("/doc") else ""!$><a href="@!top!@/doc/index.html">docs</a></li>
|
||||
<li $!'class="active"' if this.under("/about.html") else ""!$><a href="@!top!@/about.html">about</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
|
||||
<div class="span3">
|
||||
<div class="well sidebar-nav">
|
||||
$!navbar!$
|
||||
</div>
|
||||
</div>
|
||||
<div class="span9">
|
||||
<div class="page-header">
|
||||
<h1>@!this.title!@</h1>
|
||||
</div>
|
||||
$!body!$
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<footer>
|
||||
<p>@!copyright!@</p>
|
||||
</footer>
|
||||
</div>
|
||||
BIN
doc-src/certinstall/android-settingssecurityinstallca.png
Normal file
|
After Width: | Height: | Size: 56 KiB |
BIN
doc-src/certinstall/android-settingssecuritymenu.png
Normal file
|
After Width: | Height: | Size: 74 KiB |
BIN
doc-src/certinstall/android-settingssecurityuserinstalledca.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
BIN
doc-src/certinstall/android-shellwgetmitmproxyca.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
53
doc-src/certinstall/android.html
Normal file
@@ -0,0 +1,53 @@
|
||||
The proxy situation on Android is [an
|
||||
embarrasment](http://code.google.com/p/android/issues/detail?id=1273). It's
|
||||
scarcely credible, but Android didn't have a global proxy setting at all until
|
||||
quite recently, and it's still not supported on many common Android versions.
|
||||
In the meantime the app ecosystem has grown used to life without this basic
|
||||
necessity, and many apps merrily ignore it even if it's there. This situation
|
||||
is improving, but in many circumstances using [transparent
|
||||
mode](@!urlTo("transparent.html")!@) is mandatory for testing Android apps.
|
||||
|
||||
We used both an Asus Transformer Prime TF201 (Android 4.0.3) and a Nexus 4
|
||||
(Android 4.4.4) in the examples below - your device may differ, but the broad
|
||||
process should be similar. On **emulated devices**, there are some [additional
|
||||
quirks](https://github.com/mitmproxy/mitmproxy/issues/204#issuecomment-32837093)
|
||||
to consider.
|
||||
|
||||
|
||||
## Getting the certificate onto the device
|
||||
|
||||
The easiest way to get the certificate to the device is to use [the web
|
||||
app](@!urlTo("webapp.html")!@). In the rare cases where the web app doesn't
|
||||
work, you will need to get the __mitmproxy-ca-cert.cer__ file into the
|
||||
__/sdcard__ folder on the device (/sdcard/Download on older devices). This can
|
||||
be accomplished in a number of ways:
|
||||
|
||||
- If you have the Android Developer Tools installed, you can use [__adb
|
||||
push__](http://developer.android.com/tools/help/adb.html).
|
||||
- Using a file transfer program like wget (installed on the Android device) to
|
||||
copy the file over.
|
||||
- Transfer the file using external media like an SD Card.
|
||||
|
||||
Once we have the certificate on the local disk, we need to import it into the
|
||||
list of trusted CAs. Go to Settings -> Security -> Credential Storage,
|
||||
and select "Install from storage":
|
||||
|
||||
<img src="android-settingssecuritymenu.png"/>
|
||||
|
||||
The certificate in /sdcard is automatically located and offered for
|
||||
installation. Installing the cert will delete the download file from the local
|
||||
disk.
|
||||
|
||||
|
||||
## Installing the certificate
|
||||
|
||||
You should now see something like this (you may have to explicitly name the
|
||||
certificate):
|
||||
|
||||
<img src="android-settingssecurityinstallca.png"/>
|
||||
|
||||
Click OK, and you should then see the certificate listed in the Trusted
|
||||
Credentials store:
|
||||
|
||||
<img src="android-settingssecurityuserinstalledca.png"/>
|
||||
|
||||
31
doc-src/certinstall/firefox.html
Normal file
@@ -0,0 +1,31 @@
|
||||
## Get the certificate to the browser
|
||||
|
||||
The easiest way to get the certificate to the browser is to use [the web
|
||||
app](@!urlTo("webapp.html")!@). If this fails, do the following:
|
||||
|
||||
|
||||
<ol class="tlist">
|
||||
<li> If needed, copy the ~/.mitmproxy/mitmproxy-ca-cert.pem file to the target. </li>
|
||||
|
||||
<li>Open preferences, click on "Advanced", then select"Encryption":
|
||||
<img src="@!urlTo('firefox3.jpg')!@"/>
|
||||
</li>
|
||||
|
||||
<li> Click "View Certificates", "Import", and select the certificate file:
|
||||
<img src="@!urlTo('firefox3-import.jpg')!@"/>
|
||||
</li>
|
||||
|
||||
</ol>
|
||||
|
||||
|
||||
## Installing the certificate
|
||||
|
||||
<ol class="tlist">
|
||||
<li>Tick "Trust this CS to identify web sites", and click "Ok":
|
||||
<img src="@!urlTo('firefox3-trust.jpg')!@"/>
|
||||
</li>
|
||||
|
||||
<li> You should now see the mitmproxy certificate listed in the Authorities
|
||||
tab.</li>
|
||||
</ol>
|
||||
|
||||
12
doc-src/certinstall/index.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from countershape import Page
|
||||
|
||||
pages = [
|
||||
Page("webapp.html", "Using the Web App"),
|
||||
Page("firefox.html", "Firefox"),
|
||||
Page("osx.html", "OSX"),
|
||||
Page("windows7.html", "Windows 7"),
|
||||
Page("ios.html", "IOS"),
|
||||
Page("ios-simulator.html", "IOS Simulator"),
|
||||
Page("android.html", "Android"),
|
||||
Page("java.html", "Java"),
|
||||
]
|
||||
23
doc-src/certinstall/ios-simulator.html
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
How to install the __mitmproxy__ certificate authority in the IOS simulator:
|
||||
|
||||
<ol class="tlist">
|
||||
|
||||
<li> First, check out the <a
|
||||
href="https://github.com/ADVTOOLS/ADVTrustStore">ADVTrustStore</a> tool
|
||||
from github.</li>
|
||||
|
||||
<li> Now, run the following command:
|
||||
|
||||
<pre class="terminal">./iosCertTrustManager.py -a ~/.mitmproxy/mitmproxy-ca-cert.pem</pre>
|
||||
|
||||
</li>
|
||||
|
||||
</ol>
|
||||
|
||||
|
||||
Note that although the IOS simulator has its own certificate store, it shares
|
||||
the proxy settings of the host operating system. You will therefore to have
|
||||
configure your OSX host's proxy settings to use the mitmproxy instance you want
|
||||
to test with.
|
||||
|
||||
27
doc-src/certinstall/ios.html
Normal file
@@ -0,0 +1,27 @@
|
||||
|
||||
## Getting the certificate onto the device
|
||||
|
||||
The easiest way to get the certificate to the device is to use [the web
|
||||
app](@!urlTo("webapp.html")!@). In the rare cases where the web app doesn't
|
||||
work, you will need to get the __mitmproxy-ca-cert.pem__ file to the device to
|
||||
install it. The easiest way to accomplish this is to set up the Mail app on the
|
||||
device, and to email it over as an attachment. Open the email, tap on the
|
||||
attachment, then proceed with the install.
|
||||
|
||||
|
||||
## Installing the certificate
|
||||
|
||||
<ol class="tlist">
|
||||
<li>You will be prompted to install a profile. Click "Install":
|
||||
|
||||
<img src="@!urlTo('ios-profile.png')!@"/></li>
|
||||
|
||||
<li>Accept the warning by clicking "Install" again:
|
||||
|
||||
<img src="@!urlTo('ios-warning.png')!@"/></li>
|
||||
|
||||
<li>The certificate should now be trusted:
|
||||
|
||||
<img src="@!urlTo('ios-installed.png')!@"/></li>
|
||||
|
||||
</ol>
|
||||
13
doc-src/certinstall/java.html
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
You can add the mitmproxy certificates to the Java trust store using
|
||||
[keytool](http://docs.oracle.com/javase/6/docs/technotes/tools/solaris/keytool.html).
|
||||
On OSX, the required command looks like this:
|
||||
|
||||
<pre class="terminal">
|
||||
sudo keytool -importcert -alias mitmproxy -storepass "password" \
|
||||
-keystore /System/Library/Java/Support/CoreDeploy.bundle/Contents/Home/lib/security/cacerts \
|
||||
-trustcacerts -file ~/.mitmproxy/mitmproxy-ca-cert.pem
|
||||
</pre>
|
||||
|
||||
Note that your store password will (hopefully) be different from the one above.
|
||||
|
||||
16
doc-src/certinstall/osx.html
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
How to install the __mitmproxy__ certificate authority in OSX:
|
||||
|
||||
<ol class="tlist">
|
||||
|
||||
<li>Open Finder, and double-click on the mitmproxy-ca-cert.pem file.</li>
|
||||
|
||||
<li>You will be prompted to add the certificate. Click "Always Trust":
|
||||
|
||||
<img src="@!urlTo('osx-addcert-alwaystrust.png')!@"/>
|
||||
</li>
|
||||
|
||||
<li> You may be prompted for your password. You should now see the
|
||||
mitmproxy cert listed under "Certificates".</li>
|
||||
</ol>
|
||||
|
||||
10
doc-src/certinstall/webapp.html
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
By far the easiest way to install the mitmproxy certs is to use the built-in
|
||||
web app. To do this, start mitmproxy and configure your target device with the
|
||||
correct proxy settings. Now start a browser on the device, and visit the magic
|
||||
domain **mitm.it**. You should see something like this:
|
||||
|
||||
<img src="@!urlTo("webapp.png")!@"></img>
|
||||
|
||||
Just click on the relevant icon, and then follow the setup instructions
|
||||
for the platform you're on.
|
||||
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
35
doc-src/certinstall/windows7.html
Normal file
@@ -0,0 +1,35 @@
|
||||
|
||||
How to install the __mitmproxy__ certificate authority in Windows 7:
|
||||
|
||||
<ol class="tlist">
|
||||
|
||||
<li> The easiest way to get the certificate to the device is to use <a
|
||||
href="@!urlTo("webapp.html")!@">the web app</a>. If this fails for some
|
||||
reason, simply copy the ~/.mitmproxy/mitmproxy-ca-cert.p12 file to the
|
||||
target system and double-click it. </li>
|
||||
|
||||
<li>
|
||||
You should see a certificate import wizard:
|
||||
|
||||
<img src="@!urlTo('win7-wizard.png')!@"/>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
Click "Next" until you're prompted for the certificate store:
|
||||
|
||||
<img src="@!urlTo('win7-certstore.png')!@"/>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<p>Select "Place all certificates in the following store", and select "Trusted Root Certification Authorities":</p>
|
||||
|
||||
<img src="@!urlTo('win7-certstore-trustedroot.png')!@"/>
|
||||
|
||||
</li>
|
||||
|
||||
<li> Click "Next" and "Finish". </li>
|
||||
|
||||
</ol>
|
||||
|
||||
@@ -18,22 +18,22 @@ __prompt__, and __content\_types__ and a function named __\_\_call\_\___.
|
||||
Adding a new content viewer to parse a data type is as simple as writing a new
|
||||
View class. Your new content viewer View class should have the same properties
|
||||
as the other View classes: __name__, __prompt__, and __content\_types__ and a
|
||||
__\_\_call\_\___ function to parse the content of the request/response.
|
||||
__\_\_call\_\___ function to parse the content of the request/response.
|
||||
|
||||
* The __name__ property should be a string describing the contents and new content viewer;
|
||||
* The __name__ property should be a string describing the contents and new content viewer;
|
||||
* The __prompt__ property should be a two item tuple:
|
||||
|
||||
- __1__: A string that will be used to display the new content viewer's type; and
|
||||
- __2__: A one character string that will be the hotkey used to select the new content viewer from the Flow View screen;
|
||||
- __2__: A one character string that will be the hotkey used to select the new content viewer from the Flow View screen;
|
||||
|
||||
* The __content\_types__ property should be a list of strings of HTTP Content\-Types that the new content viewer can parse.
|
||||
* The __content\_types__ property should be a list of strings of HTTP Content\-Types that the new content viewer can parse.
|
||||
* Note that mitmproxy will use the content\_types to try and heuristically show a friendly view of content and that you can override the built-in views by populating content\_types with values for content\_types that are already parsed -- e.g. "image/png".
|
||||
|
||||
After defining the __name__, __prompt__, and __content\_types__ properties of
|
||||
the class, you should write the __\_\_call\_\___ function, which will parse the
|
||||
request/response data and provide a friendly view of the data. The
|
||||
__\_\_call\_\___ function should take the following arguments: __self__,
|
||||
__hdrs__, __content__, __limit__; __hdrs__ is a MultiDict object containing
|
||||
__hdrs__, __content__, __limit__; __hdrs__ is a ODictCaseless object containing
|
||||
the headers of the request/response; __content__ is the content of the
|
||||
request/response, and __limit__ is an integer representing the amount of data
|
||||
to display in the view window.
|
||||
@@ -46,7 +46,7 @@ Alternatively, you can display content as a series of key-value pairs; to do
|
||||
so, prepare a list of lists, where each list item is a two item list -- a key
|
||||
that describes the data, and then the data itself; after preparing the list of
|
||||
lists, use the __common.format\_keyvals__ function on it to prepare it as text
|
||||
for display.
|
||||
for display.
|
||||
|
||||
If the new content viewer fails or throws an exception, mitmproxy will default
|
||||
to a __raw__ view.
|
||||
6
doc-src/dev/index.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from countershape import Page
|
||||
|
||||
pages = [
|
||||
Page("testing.html", "Testing"),
|
||||
# Page("addingviews.html", "Writing Content Views"),
|
||||
]
|
||||
43
doc-src/dev/testing.html
Normal file
@@ -0,0 +1,43 @@
|
||||
|
||||
All the mitmproxy projects strive to maintain 100% code coverage. In general,
|
||||
patches and pull requests will be declined unless they're accompanied by a
|
||||
suitable extension to the test suite.
|
||||
|
||||
Our tests are written for the [nose](https://nose.readthedocs.org/en/latest/).
|
||||
At the point where you send your pull request, a command like this:
|
||||
|
||||
<pre class="terminal">
|
||||
> nosetests --with-cov --cov-report term-missing ./test
|
||||
</pre>
|
||||
|
||||
Should give output something like this:
|
||||
|
||||
<pre class="terminal">
|
||||
> ---------- coverage: platform darwin, python 2.7.2-final-0 --
|
||||
> Name Stmts Miss Cover Missing
|
||||
> ----------------------------------------------------
|
||||
> libmproxy/__init__ 0 0 100%
|
||||
> libmproxy/app 4 0 100%
|
||||
> libmproxy/cmdline 100 0 100%
|
||||
> libmproxy/controller 69 0 100%
|
||||
> libmproxy/dump 150 0 100%
|
||||
> libmproxy/encoding 39 0 100%
|
||||
> libmproxy/filt 201 0 100%
|
||||
> libmproxy/flow 891 0 100%
|
||||
> libmproxy/proxy 427 0 100%
|
||||
> libmproxy/script 27 0 100%
|
||||
> libmproxy/utils 133 0 100%
|
||||
> libmproxy/version 4 0 100%
|
||||
> ----------------------------------------------------
|
||||
> TOTAL 2045 0 100%
|
||||
> ----------------------------------------------------
|
||||
> Ran 251 tests in 11.864s
|
||||
</pre>
|
||||
|
||||
|
||||
There are exceptions to the coverage requirement - for instance, much of the
|
||||
console interface code can't sensibly be unit tested. These portions are
|
||||
excluded from coverage analysis either in the **.coveragerc** file, or using
|
||||
**#pragma no-cover** directives. To keep our coverage analysis relevant, we use
|
||||
these measures as sparingly as possible.
|
||||
|
||||
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 77 KiB |
18
doc-src/features/anticache.html
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
When the __anticache__ option is passed to mitmproxy, it removes headers
|
||||
(__if-none-match__ and __if-modified-since__) that might elicit a
|
||||
304-not-modified response from the server. This is useful when you want to make
|
||||
sure you capture an HTTP exchange in its totality. It's also often used during
|
||||
[client replay](@!urlTo("clientreplay.html")!@), when you want to make sure the
|
||||
server responds with complete data.
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th width="20%">command-line</th> <td>--anticache</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>mitmproxy shortcut</th> <td><b>o</b> then <b>a</b></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -1,7 +1,3 @@
|
||||
.. _clientreplay:
|
||||
|
||||
Client-side replay
|
||||
==================
|
||||
|
||||
Client-side replay does what it says on the tin: you provide a previously saved
|
||||
HTTP conversation, and mitmproxy replays the client requests one by one. Note
|
||||
@@ -10,9 +6,17 @@ before starting the next request. This might differ from the recorded
|
||||
conversation, where requests may have been made concurrently.
|
||||
|
||||
You may want to use client-side replay in conjunction with the
|
||||
:ref:`anticache` option, to make sure the server responds with complete data.
|
||||
[anticache](@!urlTo("anticache.html")!@) option, to make sure the server
|
||||
responds with complete data.
|
||||
|
||||
================== ===========
|
||||
command-line ``-c path``
|
||||
mitmproxy shortcut :kbd:`R` then :kbd:`c`
|
||||
================== ===========
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th width="20%">command-line</th> <td>-c path</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>mitmproxy shortcut</th> <td><b>c</b></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -1,38 +1,36 @@
|
||||
.. _filters:
|
||||
|
||||
Filter expressions
|
||||
==================
|
||||
|
||||
Many commands in :program:`mitmproxy` and :program:`mitmdump` take a filter expression.
|
||||
Many commands in __mitmproxy__ and __mitmdump__ take a filter expression.
|
||||
Filter expressions consist of the following operators:
|
||||
|
||||
.. documentedlist::
|
||||
:header: "Expression" "Description"
|
||||
:listobject: mitmproxy.flowfilter.help
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<!--(for i in filt_help)-->
|
||||
<tr>
|
||||
<td class="filt_cmd">@!i[0]!@</td>
|
||||
<td class="filt_help">@!i[1]!@</td>
|
||||
</tr>
|
||||
<!--(end)-->
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
- Regexes are Python-style
|
||||
- Regexes can be specified as quoted strings
|
||||
- Header matching (~h, ~hq, ~hs) is against a string of the form "name: value".
|
||||
- Strings with no operators are matched against the request URL.
|
||||
- The default binary operator is &.
|
||||
- The default binary operator is &.
|
||||
|
||||
Examples
|
||||
--------
|
||||
========
|
||||
|
||||
URL containing "google.com":
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
google\.com
|
||||
|
||||
Requests whose body contains the string "test":
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
~q ~b test
|
||||
|
||||
Anything but requests with a text/html content type:
|
||||
|
||||
.. code-block:: none
|
||||
!(~q & ~t \"text/html\")
|
||||
|
||||
!(~q & ~t "text/html")
|
||||
16
doc-src/features/forwardproxy.html
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
In this mode, mitmproxy accepts proxy requests and unconditionally forwards all
|
||||
requests to a specified upstream server. This is in contrast to <a
|
||||
href="@!urlTo("reverseproxy.html")!@">reverse proxy mode</a>, in which
|
||||
mitmproxy forwards ordinary HTTP requests to an upstream server.
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th width="20%">command-line</th> <td>-F http[s]://hostname[:port]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>mitmproxy shortcut</th> <td><b>F</b></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
15
doc-src/features/index.py
Normal file
@@ -0,0 +1,15 @@
|
||||
from countershape import Page
|
||||
|
||||
pages = [
|
||||
Page("anticache.html", "Anticache"),
|
||||
Page("clientreplay.html", "Client-side replay"),
|
||||
Page("filters.html", "Filter expressions"),
|
||||
Page("forwardproxy.html", "Forward proxy mode"),
|
||||
Page("setheaders.html", "Set Headers"),
|
||||
Page("serverreplay.html", "Server-side replay"),
|
||||
Page("sticky.html", "Sticky cookies and auth"),
|
||||
Page("proxyauth.html", "Proxy Authentication"),
|
||||
Page("replacements.html", "Replacements"),
|
||||
Page("reverseproxy.html", "Reverse proxy mode"),
|
||||
Page("upstreamcerts.html", "Upstream Certs"),
|
||||
]
|
||||
26
doc-src/features/proxyauth.html
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
Asks the user for authentication before they are permitted to use the proxy.
|
||||
Authentication headers are stripped from the flows, so they are not passed to
|
||||
upstream servers. For now, only HTTP Basic authentication is supported. The
|
||||
proxy auth options are ignored if the proxy is in transparent or reverse proxy
|
||||
mode.
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th width="20%">command-line</th>
|
||||
<td>
|
||||
<ul>
|
||||
<li>--nonanonymous</li>
|
||||
|
||||
<li>--singleuser USER</li>
|
||||
|
||||
<li>--htpasswd PATH</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
.. _replacements:
|
||||
|
||||
Replacements
|
||||
============
|
||||
|
||||
Mitmproxy lets you specify an arbitrary number of patterns that define text
|
||||
replacements within flows. Each pattern has 3 components: a filter that defines
|
||||
which flows a replacement applies to, a regular expression that defines what
|
||||
@@ -14,59 +9,66 @@ replace hook is triggered on server response, the replacement is only run on
|
||||
the Response object leaving the Request intact. You control whether the hook
|
||||
triggers on the request, response or both using the filter pattern. If you need
|
||||
finer-grained control than this, it's simple to create a script using the
|
||||
replacement API on Flow components.
|
||||
replacement API on Flow components.
|
||||
|
||||
Replacement hooks are extremely handy in interactive testing of applications.
|
||||
For instance you can use a replace hook to replace the text "XSS" with a
|
||||
complicated XSS exploit, and then "inject" the exploit simply by interacting
|
||||
with the application through the browser. When used with tools like Firebug and
|
||||
mitmproxy's own interception abilities, replacement hooks can be an amazingly
|
||||
flexible and powerful feature.
|
||||
flexible and powerful feature.
|
||||
|
||||
|
||||
On the command-line
|
||||
-------------------
|
||||
## On the command-line
|
||||
|
||||
The replacement hook command-line options use a compact syntax to make it easy
|
||||
to specify all three components at once. The general form is as follows:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
/patt/regex/replacement
|
||||
|
||||
Here, **patt** is a mitmproxy filter expression, **regex** is a valid Python
|
||||
regular expression, and **replacement** is a string literal. The first
|
||||
character in the expression (``/`` in this case) defines what the separation
|
||||
Here, __patt__ is a mitmproxy filter expression, __regex__ is a valid Python
|
||||
regular expression, and __replacement__ is a string literal. The first
|
||||
character in the expression (__/__ in this case) defines what the separation
|
||||
character is. Here's an example of a valid expression that replaces "foo" with
|
||||
"bar" in all requests:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
:~q:foo:bar
|
||||
|
||||
In practice, it's pretty common for the replacement literal to be long and
|
||||
complex. For instance, it might be an XSS exploit that weighs in at hundreds or
|
||||
thousands of characters. To cope with this, there's a variation of the
|
||||
replacement hook specifier that lets you load the replacement text from a file.
|
||||
So, you might start **mitmdump** as follows:
|
||||
So, you might start __mitmdump__ as follows:
|
||||
|
||||
>>> mitmdump --replace-from-file :~q:foo:~/xss-exploit
|
||||
<pre class="terminal">
|
||||
mitmdump --replace-from-file :~q:foo:~/xss-exploit
|
||||
</pre>
|
||||
|
||||
This will load the replacement text from the file ``~/xss-exploit``.
|
||||
This will load the replacement text from the file __~/xss-exploit__.
|
||||
|
||||
Both the ``--replace`` and ``--replace-from-file`` flags can be passed multiple
|
||||
Both the _--replace_ and _--replace-from-file_ flags can be passed multiple
|
||||
times.
|
||||
|
||||
|
||||
Interactively
|
||||
-------------
|
||||
## Interactively
|
||||
|
||||
The :kbd:`R` shortcut key in the mitmproxy options menu (:kbd:`o`) lets you add and edit
|
||||
replacement hooks using a built-in editor. The context-sensitive help (:kbd:`?`) has
|
||||
complete usage information.
|
||||
The _R_ shortcut key in mitmproxy lets you add and edit replacement hooks using
|
||||
a built-in editor. The context-sensitive help (_h_) has complete usage
|
||||
information.
|
||||
|
||||
================== =======================
|
||||
command-line ``--replace``,
|
||||
``--replace-from-file``
|
||||
mitmproxy shortcut :kbd:`o` then :kbd:`R`
|
||||
================== =======================
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th width="20%">command-line</th>
|
||||
<td>
|
||||
<ul>
|
||||
<li>--replace</li>
|
||||
<li>--replace-from-file</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>mitmproxy shortcut</th> <td><b>R</b></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
19
doc-src/features/reverseproxy.html
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
In reverse proxy mode, mitmproxy accepts standard HTTP requests and forwards
|
||||
them to the specified upstream server. This is in contrast to <a
|
||||
href="@!urlTo("forwardproxy.html")!@">forward proxy mode</a>, in which
|
||||
mitmproxy forwards HTTP proxy requests to an upstream server.
|
||||
|
||||
Note that the displayed URL for flows in this mode will use the value of the
|
||||
__Host__ header field from the request, not the reverse proxy server.
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th width="20%">command-line</th> <td>-P http[s]://hostname[:port]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>mitmproxy shortcut</th> <td><b>P</b></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -1,7 +1,6 @@
|
||||
.. _serverreplay:
|
||||
|
||||
Server-side replay
|
||||
==================
|
||||
- command-line: _-S path_
|
||||
- mitmproxy shortcut: _S_
|
||||
|
||||
Server-side replay lets us replay server responses from a saved HTTP
|
||||
conversation.
|
||||
@@ -9,12 +8,12 @@ conversation.
|
||||
Matching requests with responses
|
||||
--------------------------------
|
||||
|
||||
By default, :program:`mitmproxy` excludes request headers when matching incoming
|
||||
By default, __mitmproxy__ excludes request headers when matching incoming
|
||||
requests with responses from the replay file. This works in most circumstances,
|
||||
and makes it possible to replay server responses in situations where request
|
||||
headers would naturally vary, e.g. using a different user agent.
|
||||
The ``--rheader headername`` command-line option allows you to override
|
||||
this behaviour by specifying individual headers that should be included in matching.
|
||||
headers would naturally vary, e.g. using a different user agent. The _--rheader
|
||||
headername_ command-line option allows you to override this behaviour by
|
||||
specifying individual headers that should be included in matching.
|
||||
|
||||
|
||||
Response refreshing
|
||||
@@ -23,17 +22,14 @@ Response refreshing
|
||||
Simply replaying server responses without modification will often result in
|
||||
unexpected behaviour. For example cookie timeouts that were in the future at
|
||||
the time a conversation was recorded might be in the past at the time it is
|
||||
replayed. By default, :program:`mitmproxy` refreshes server responses before sending
|
||||
them to the client. The **date**, **expires** and **last-modified** headers are
|
||||
replayed. By default, __mitmproxy__ refreshes server responses before sending
|
||||
them to the client. The __date__, __expires__ and __last-modified__ headers are
|
||||
all updated to have the same relative time offset as they had at the time of
|
||||
recording. So, if they were in the past at the time of recording, they will be
|
||||
in the past at the time of replay, and vice versa. Cookie expiry times are
|
||||
updated in a similar way.
|
||||
|
||||
You can turn off response refreshing using the ``--norefresh`` argument, or using
|
||||
the :kbd:`o` options shortcut within :program:`mitmproxy`.
|
||||
You can turn off response refreshing using the _--norefresh_ argument, or using
|
||||
the _o_ options shortcut within __mitmproxy__.
|
||||
|
||||
|
||||
================== ===========
|
||||
command-line ``-S path``
|
||||
mitmproxy shortcut :kbd:`R` then :kbd:`s`
|
||||
================== ===========
|
||||
18
doc-src/features/setheaders.html
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
This feature lets you specify a set of headers to be added to requests or
|
||||
responses, based on a filter pattern. You can specify these either on the
|
||||
command-line, or through an interactive editor in mitmproxy.
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th width="20%">command-line</th>
|
||||
<td>
|
||||
--setheader PATTERN
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>mitmproxy shortcut</th> <td><b>H</b></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
60
doc-src/features/sticky.html
Normal file
@@ -0,0 +1,60 @@
|
||||
|
||||
## Sticky cookies
|
||||
|
||||
When the sticky cookie option is set, __mitmproxy__ will add the cookie most
|
||||
recently set by the server to any cookie-less request. Consider a service that
|
||||
sets a cookie to track the session after authentication. Using sticky cookies,
|
||||
you can fire up mitmproxy, and authenticate to a service as you usually would
|
||||
using a browser. After authentication, you can request authenticated resources
|
||||
through mitmproxy as if they were unauthenticated, because mitmproxy will
|
||||
automatically add the session tracking cookie to requests. Among other things,
|
||||
this lets you script interactions with authenticated resources (using tools
|
||||
like wget or curl) without having to worry about authentication.
|
||||
|
||||
Sticky cookies are especially powerful when used in conjunction with [client
|
||||
replay](@!urlTo("clientreplay.html")!@) - you can record the authentication
|
||||
process once, and simply replay it on startup every time you need to interact
|
||||
with the secured resources.
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th width="20%">command-line</th>
|
||||
<td>
|
||||
<ul>
|
||||
<li>-t FILTER</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>mitmproxy shortcut</th> <td><b>t</b></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
## Sticky auth
|
||||
|
||||
The sticky auth option is analogous to the sticky cookie option, in that HTTP
|
||||
__Authorization__ headers are simply replayed to the server once they have been
|
||||
seen. This is enough to allow you to access a server resource using HTTP Basic
|
||||
authentication through the proxy. Note that __mitmproxy__ doesn't (yet) support
|
||||
replay of HTTP Digest authentication.
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th width="20%">command-line</th>
|
||||
<td>
|
||||
<ul>
|
||||
<li>-u FILTER</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>mitmproxy shortcut</th> <td><b>u</b></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
@@ -1,23 +1,21 @@
|
||||
.. _upstreamcerts:
|
||||
|
||||
Upstream Certificates
|
||||
=====================
|
||||
|
||||
When mitmproxy receives a connection destined for an SSL-protected service, it
|
||||
freezes the connection before reading its request data, and makes a connection
|
||||
to the upstream server to "sniff" the contents of its SSL certificate. The
|
||||
information gained - the **Common Name** and **Subject Alternative Names** - is
|
||||
information gained - the __Common Name__ and __Subject Alternative Names__ - is
|
||||
then used to generate the interception certificate, which is sent to the client
|
||||
so the connection can continue.
|
||||
|
||||
This rather intricate little dance lets us seamlessly generate correct
|
||||
certificates even if the client has specified only an IP address rather than the
|
||||
certificates even if the client has specifed only an IP address rather than the
|
||||
hostname. It also means that we don't need to sniff additional data to generate
|
||||
certs in transparent mode.
|
||||
|
||||
Upstream cert sniffing is on by default, and can optionally be turned off.
|
||||
|
||||
================== ======================
|
||||
command-line ``--no-upstream-cert``
|
||||
mitmproxy shortcut :kbd:`o` then :kbd:`U`
|
||||
================== ======================
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th width="20%">command-line</th> <td>--no-upstream-cert</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
360
doc-src/howmitmproxy.html
Normal file
@@ -0,0 +1,360 @@
|
||||
|
||||
|
||||
Mitmproxy is an enormously flexible tool. Knowing exactly how the proxying
|
||||
process works will help you deploy it creatively, and take into account its
|
||||
fundamental assumptions and how to work around them. This document explains
|
||||
mitmproxy's proxy mechanism in detail, starting with the simplest unencrypted
|
||||
explicit proxying, and working up to the most complicated interaction -
|
||||
transparent proxying of SSL-protected traffic[^ssl] in the presence of
|
||||
[SNI](http://en.wikipedia.org/wiki/Server_Name_Indication).
|
||||
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Explicit HTTP</h1>
|
||||
</div>
|
||||
|
||||
Configuring the client to use mitmproxy as an explicit proxy is the simplest
|
||||
and most reliable way to intercept traffic. The proxy protocol is codified in
|
||||
the [HTTP RFC](http://www.ietf.org/rfc/rfc2068.txt), so the behaviour of both
|
||||
the client and the server is well defined, and usually reliable. In the
|
||||
simplest possible interaction with mitmproxy, a client connects directly to the
|
||||
proxy, and makes a request that looks like this:
|
||||
|
||||
<pre>GET http://example.com/index.html HTTP/1.1</pre>
|
||||
|
||||
This is a proxy GET request - an extended form of the vanilla HTTP GET request
|
||||
that includes a schema and host specification, and it includes all the
|
||||
information mitmproxy needs to proceed.
|
||||
|
||||
<img src="explicit.png"/>
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
|
||||
<td><b>1</b></td>
|
||||
|
||||
<td>The client connects to the proxy and makes a request.</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td><b>2</b></td>
|
||||
|
||||
<td>Mitmproxy connects to the upstream server and simply forwards
|
||||
the request on.</td>
|
||||
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Explicit HTTPS</h1>
|
||||
</div>
|
||||
|
||||
The process for an explicitly proxied HTTPS connection is quite different. The
|
||||
client connects to the proxy and makes a request that looks like this:
|
||||
|
||||
<pre>CONNECT example.com:443 HTTP/1.1</pre>
|
||||
|
||||
A conventional proxy can neither view nor manipulate an SSL-encrypted data
|
||||
stream, so a CONNECT request simply asks the proxy to open a pipe between the
|
||||
client and server. The proxy here is just a facilitator - it blindly forwards
|
||||
data in both directions without knowing anything about the contents. The
|
||||
negotiation of the SSL connection happens over this pipe, and the subsequent
|
||||
flow of requests and responses are completely opaque to the proxy.
|
||||
|
||||
## The MITM in mitmproxy
|
||||
|
||||
This is where mitmproxy's fundamental trick comes into play. The MITM in its
|
||||
name stands for Man-In-The-Middle - a reference to the process we use to
|
||||
intercept and interfere with these theoretically opaque data streams. The basic
|
||||
idea is to pretend to be the server to the client, and pretend to be the client
|
||||
to the server, while we sit in the middle decoding traffic from both sides. The
|
||||
tricky part is that the [Certificate
|
||||
Authority](http://en.wikipedia.org/wiki/Certificate_authority) system is
|
||||
designed to prevent exactly this attack, by allowing a trusted third-party to
|
||||
cryptographically sign a server's SSL certificates to verify that they are
|
||||
legit. If this signature doesn't match or is from a non-trusted party, a secure
|
||||
client will simply drop the connection and refuse to proceed. Despite the many
|
||||
shortcomings of the CA system as it exists today, this is usually fatal to
|
||||
attempts to MITM an SSL connection for analysis. Our answer to this conundrum
|
||||
is to become a trusted Certificate Authority ourselves. Mitmproxy includes a
|
||||
full CA implementation that generates interception certificates on the fly. To
|
||||
get the client to trust these certificates, we [register mitmproxy as a trusted
|
||||
CA with the device manually](@!urlTo("ssl.html")!@).
|
||||
|
||||
## Complication 1: What's the remote hostname?
|
||||
|
||||
To proceed with this plan, we need to know the domain name to use in the
|
||||
interception certificate - the client will verify that the certificate is for
|
||||
the domain it's connecting to, and abort if this is not the case. At first
|
||||
blush, it seems that the CONNECT request above gives us all we need - in this
|
||||
example, both of these values are "example.com". But what if the client had
|
||||
initiated the connection as follows:
|
||||
|
||||
<pre>CONNECT 10.1.1.1:443 HTTP/1.1</pre>
|
||||
|
||||
Using the IP address is perfectly legitimate because it gives us enough
|
||||
information to initiate the pipe, even though it doesn't reveal the remote
|
||||
hostname.
|
||||
|
||||
Mitmproxy has a cunning mechanism that smooths this over - [upstream
|
||||
certificate sniffing](@!urlTo("features/upstreamcerts.html")!@). As soon as we
|
||||
see the CONNECT request, we pause the client part of the conversation, and
|
||||
initiate a simultaneous connection to the server. We complete the SSL handshake
|
||||
with the server, and inspect the certificates it used. Now, we use the Common
|
||||
Name in the upstream SSL certificates to generate the dummy certificate for the
|
||||
client. Voila, we have the correct hostname to present to the client, even if
|
||||
it was never specified.
|
||||
|
||||
|
||||
## Complication 2: Subject Alternative Name
|
||||
|
||||
Enter the next complication. Sometimes, the certificate Common Name is not, in
|
||||
fact, the hostname that the client is connecting to. This is because of the
|
||||
optional [Subject Alternative
|
||||
Name](http://en.wikipedia.org/wiki/SubjectAltName) field in the SSL certificate
|
||||
that allows an arbitrary number of alternative domains to be specified. If the
|
||||
expected domain matches any of these, the client will proceed, even though the
|
||||
domain doesn't match the certificate Common Name. The answer here is simple:
|
||||
when extract the CN from the upstream cert, we also extract the SANs, and add
|
||||
them to the generated dummy certificate.
|
||||
|
||||
|
||||
## Complication 3: Server Name Indication
|
||||
|
||||
One of the big limitations of vanilla SSL is that each certificate requires its
|
||||
own IP address. This means that you couldn't do virtual hosting where multiple
|
||||
domains with independent certificates share the same IP address. In a world
|
||||
with a rapidly shrinking IPv4 address pool this is a problem, and we have a
|
||||
solution in the form of the [Server Name
|
||||
Indication](http://en.wikipedia.org/wiki/Server_Name_Indication) extension to
|
||||
the SSL and TLS protocols. This lets the client specify the remote server name
|
||||
at the start of the SSL handshake, which then lets the server select the right
|
||||
certificate to complete the process.
|
||||
|
||||
SNI breaks our upstream certificate sniffing process, because when we connect
|
||||
without using SNI, we get served a default certificate that may have nothing to
|
||||
do with the certificate expected by the client. The solution is another tricky
|
||||
complication to the client connection process. After the client connects, we
|
||||
allow the SSL handshake to continue until just _after_ the SNI value has been
|
||||
passed to us. Now we can pause the conversation, and initiate an upstream
|
||||
connection using the correct SNI value, which then serves us the correct
|
||||
upstream certificate, from which we can extract the expected CN and SANs.
|
||||
|
||||
There's another wrinkle here. Due to a limitation of the SSL library mitmproxy
|
||||
uses, we can't detect that a connection _hasn't_ sent an SNI request until it's
|
||||
too late for upstream certificate sniffing. In practice, we therefore make a
|
||||
vanilla SSL connection upstream to sniff non-SNI certificates, and then discard
|
||||
the connection if the client sends an SNI notification. If you're watching your
|
||||
traffic with a packet sniffer, you'll see two connections to the server when an
|
||||
SNI request is made, the first of which is immediately closed after the SSL
|
||||
handshake. Luckily, this is almost never an issue in practice.
|
||||
|
||||
## Putting it all together
|
||||
|
||||
Lets put all of this together into the complete explicitly proxied HTTPS flow.
|
||||
|
||||
<img src="explicit_https.png"/>
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><b>1</b></td>
|
||||
<td>The client makes a connection to mitmproxy, and issues an HTTP
|
||||
CONNECT request.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>2</b></td>
|
||||
|
||||
<td>Mitmproxy responds with a 200 Connection Established, as if it
|
||||
has set up the CONNECT pipe.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>3</b></td>
|
||||
|
||||
<td>The client believes it's talking to the remote server, and
|
||||
initiates the SSL connection. It uses SNI to indicate the hostname
|
||||
it is connecting to.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><b>4</b></td>
|
||||
|
||||
<td>Mitmproxy connects to the server, and establishes an SSL
|
||||
connection using the SNI hostname indicated by the client.</td>
|
||||
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>5</b></td>
|
||||
|
||||
<td>The server responds with the matching SSL certificate, which
|
||||
contains the CN and SAN values needed to generate the interception
|
||||
certificate.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>6</b></td>
|
||||
|
||||
<td>Mitmproxy generates the interception cert, and continues the
|
||||
client SSL handshake paused in step 3.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>7</b></td>
|
||||
|
||||
<td>The client sends the request over the established SSL
|
||||
connection.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>7</b></td>
|
||||
|
||||
<td>Mitmproxy passes the request on to the server over the SSL
|
||||
connection initiated in step 4.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Transparent HTTP</h1>
|
||||
</div>
|
||||
|
||||
When a transparent proxy is used, the HTTP/S connection is redirected into a
|
||||
proxy at the network layer, without any client configuration being required.
|
||||
This makes transparent proxying ideal for those situations where you can't
|
||||
change client behaviour - proxy-oblivious Android applications being a common
|
||||
example.
|
||||
|
||||
To achieve this, we need to introduce two extra components. The first is a
|
||||
redirection mechanism that transparently reroutes a TCP connection destined for
|
||||
a server on the Internet to a listening proxy server. This usually takes the
|
||||
form of a firewall on the same host as the proxy server -
|
||||
[iptables](http://www.netfilter.org/) on Linux or
|
||||
[pf](http://en.wikipedia.org/wiki/PF_\(firewall\)) on OSX. Once the client has
|
||||
initiated the connection, it makes a vanilla HTTP request, which might look
|
||||
something like this:
|
||||
|
||||
<pre>GET /index.html HTTP/1.1</pre>
|
||||
|
||||
Note that this request differs from the explicit proxy variation, in that it
|
||||
omits the scheme and hostname. How, then, do we know which upstream host to
|
||||
forward the request to? The routing mechanism that has performed the
|
||||
redirection keeps track of the original destination for us. Each routing
|
||||
mechanism has a different way of exposing this data, so this introduces the
|
||||
second component required for working transparent proxying: a host module that
|
||||
knows how to retrieve the original destination address from the router. In
|
||||
mitmproxy, this takes the form of a built-in set of
|
||||
[modules](https://github.com/mitmproxy/mitmproxy/tree/master/libmproxy/platform)
|
||||
that know how to talk to each platform's redirection mechanism. Once we have
|
||||
this information, the process is fairly straight-forward.
|
||||
|
||||
<img src="transparent.png"/>
|
||||
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><b>1</b></td>
|
||||
<td>The client makes a connection to the server.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>2</b></td>
|
||||
|
||||
<td>The router redirects the connection to mitmproxy, which is
|
||||
typically listening on a local port of the same host. Mitmproxy
|
||||
then consults the routing mechanism to establish what the original
|
||||
destination was.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>3</b></td>
|
||||
|
||||
<td>Now, we simply read the client's request...</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><b>4</b></td>
|
||||
|
||||
<td>... and forward it upstream.</td>
|
||||
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Transparent HTTPS</h1>
|
||||
</div>
|
||||
|
||||
The first step is to determine whether we should treat an incoming connection
|
||||
as HTTPS. The mechanism for doing this is simple - we use the routing mechanism
|
||||
to find out what the original destination port is. By default, we treat all
|
||||
traffic destined for ports 443 and 8443 as SSL.
|
||||
|
||||
From here, the process is a merger of the methods we've described for
|
||||
transparently proxying HTTP, and explicitly proxying HTTPS. We use the routing
|
||||
mechanism to establish the upstream server address, and then proceed as for
|
||||
explicit HTTPS connections to establish the CN and SANs, and cope with SNI.
|
||||
|
||||
<img src="transparent_https.png"/>
|
||||
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><b>1</b></td>
|
||||
<td>The client makes a connection to the server.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>2</b></td>
|
||||
|
||||
<td>The router redirects the connection to mitmproxy, which is
|
||||
typically listening on a local port of the same host. Mitmproxy
|
||||
then consults the routing mechanism to establish what the original
|
||||
destination was.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>3</b></td>
|
||||
|
||||
<td>The client believes it's talking to the remote server, and
|
||||
initiates the SSL connection. It uses SNI to indicate the hostname
|
||||
it is connecting to.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><b>4</b></td>
|
||||
|
||||
<td>Mitmproxy connects to the server, and establishes an SSL
|
||||
connection using the SNI hostname indicated by the client.</td>
|
||||
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>5</b></td>
|
||||
|
||||
<td>The server responds with the matching SSL certificate, which
|
||||
contains the CN and SAN values needed to generate the interception
|
||||
certificate.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>6</b></td>
|
||||
|
||||
<td>Mitmproxy generates the interception cert, and continues the
|
||||
client SSL handshake paused in step 3.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>7</b></td>
|
||||
|
||||
<td>The client sends the request over the established SSL
|
||||
connection.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>7</b></td>
|
||||
|
||||
<td>Mitmproxy passes the request on to the server over the SSL
|
||||
connection initiated in step 4.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
[^ssl]: I use "SSL" to refer to both SSL and TLS in the generic sense, unless otherwise specified.
|
||||
4
doc-src/index.html
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
@!index_contents!@
|
||||
|
||||
|
||||
89
doc-src/index.py
Normal file
@@ -0,0 +1,89 @@
|
||||
import os, sys, datetime
|
||||
import countershape
|
||||
from countershape import Page, Directory, PythonModule, markup, model
|
||||
import countershape.template
|
||||
sys.path.insert(0, "..")
|
||||
from libmproxy import filt, version
|
||||
|
||||
MITMPROXY_SRC = os.environ.get("MITMPROXY_SRC", os.path.abspath(".."))
|
||||
ns.VERSION = version.VERSION
|
||||
|
||||
if ns.options.website:
|
||||
ns.idxpath = "doc/index.html"
|
||||
this.layout = countershape.Layout("_websitelayout.html")
|
||||
else:
|
||||
ns.idxpath = "index.html"
|
||||
this.layout = countershape.Layout("_layout.html")
|
||||
|
||||
ns.title = countershape.template.Template(None, "<h1>@!this.title!@</h1>")
|
||||
this.titlePrefix = "%s - " % version.NAMEVERSION
|
||||
this.markup = markup.Markdown(extras=["footnotes"])
|
||||
|
||||
ns.docMaintainer = "Aldo Cortesi"
|
||||
ns.docMaintainerEmail = "aldo@corte.si"
|
||||
ns.copyright = u"\u00a9 mitmproxy project, %s" % datetime.date.today().year
|
||||
|
||||
def mpath(p):
|
||||
p = os.path.join(MITMPROXY_SRC, p)
|
||||
return os.path.expanduser(p)
|
||||
|
||||
with open(mpath("README.mkd")) as f:
|
||||
readme = f.read()
|
||||
ns.index_contents = readme.split("\n", 1)[1] #remove first line (contains build status)
|
||||
|
||||
def example(s):
|
||||
d = file(mpath(s)).read().rstrip()
|
||||
extemp = """<div class="example">%s<div class="example_legend">(%s)</div></div>"""
|
||||
return extemp%(countershape.template.Syntax("py")(d), s)
|
||||
ns.example = example
|
||||
|
||||
|
||||
filt_help = []
|
||||
for i in filt.filt_unary:
|
||||
filt_help.append(
|
||||
("~%s"%i.code, i.help)
|
||||
)
|
||||
for i in filt.filt_rex:
|
||||
filt_help.append(
|
||||
("~%s regex"%i.code, i.help)
|
||||
)
|
||||
for i in filt.filt_int:
|
||||
filt_help.append(
|
||||
("~%s int"%i.code, i.help)
|
||||
)
|
||||
filt_help.sort()
|
||||
filt_help.extend(
|
||||
[
|
||||
("!", "unary not"),
|
||||
("&", "and"),
|
||||
("|", "or"),
|
||||
("(...)", "grouping"),
|
||||
]
|
||||
)
|
||||
ns.filt_help = filt_help
|
||||
|
||||
|
||||
def nav(page, current, state):
|
||||
if current.match(page, False):
|
||||
pre = '<li class="active">'
|
||||
else:
|
||||
pre = "<li>"
|
||||
p = state.application.getPage(page)
|
||||
return pre + '<a href="%s">%s</a></li>'%(model.UrlTo(page), p.title)
|
||||
ns.nav = nav
|
||||
ns.navbar = countershape.template.File(None, "_nav.html")
|
||||
|
||||
pages = [
|
||||
Page("index.html", "Introduction"),
|
||||
Page("install.html", "Installation"),
|
||||
Page("mitmproxy.html", "mitmproxy"),
|
||||
Page("mitmdump.html", "mitmdump"),
|
||||
Page("howmitmproxy.html", "How mitmproxy works"),
|
||||
|
||||
Page("ssl.html", "Overview"),
|
||||
Directory("certinstall"),
|
||||
Directory("scripting"),
|
||||
Directory("tutorials"),
|
||||
Page("transparent.html", "Overview"),
|
||||
Directory("transparent"),
|
||||
]
|
||||
52
doc-src/install.html
Normal file
@@ -0,0 +1,52 @@
|
||||
|
||||
The preferred way to install mitmproxy - whether you're installing the latest
|
||||
release or from source - is to use [pip](http://www.pip-installer.org/). If you
|
||||
don't already have pip on your system, you can find installation instructions
|
||||
[here](http://www.pip-installer.org/en/latest/installing.html).
|
||||
|
||||
|
||||
## Installing the latest release
|
||||
|
||||
A single command will download and install the latest release of mitmproxy,
|
||||
along with all its dependencies:
|
||||
|
||||
<pre class="terminal">
|
||||
pip install mitmproxy
|
||||
</pre>
|
||||
|
||||
|
||||
## Installing from source
|
||||
|
||||
When installing from source, the easiest method is still to use pip. In this
|
||||
case run:
|
||||
|
||||
<pre class="terminal">
|
||||
pip install /path/to/source
|
||||
</pre>
|
||||
|
||||
Note that if you're installing current git master, you will also have to
|
||||
install the current git master of [netlib](http://github.com/mitmproxy/netlib) by
|
||||
hand.
|
||||
|
||||
## OSX
|
||||
|
||||
- If you're running a Python interpreter installed with homebrew (or similar),
|
||||
you may have to install some dependencies by hand.
|
||||
- Make sure that XCode is installed from the App Store, and that the
|
||||
command-line tools have been downloaded (XCode/Preferences/Downloads).
|
||||
- Now use __pip__ to do the installation, as above.
|
||||
|
||||
There are a few bits of customization you might want to do to make mitmproxy
|
||||
comfortable to use on OSX. The default color scheme is optimized for a dark
|
||||
background terminal, but you can select a palette for a light terminal
|
||||
background with the --palette option. You can use the OSX <b>open</b> program
|
||||
to create a simple and effective <b>~/.mailcap</b> file to view request and
|
||||
response bodies:
|
||||
|
||||
<pre class="terminal">
|
||||
application/*; /usr/bin/open -Wn %s
|
||||
audio/*; /usr/bin/open -Wn %s
|
||||
image/*; /usr/bin/open -Wn %s
|
||||
video/*; /usr/bin/open -Wn %s
|
||||
</pre>
|
||||
|
||||
68
doc-src/mitmdump.html
Normal file
@@ -0,0 +1,68 @@
|
||||
|
||||
__mitmdump__ is the command-line companion to mitmproxy. It provides
|
||||
tcpdump-like functionality to let you view, record, and programmatically
|
||||
transform HTTP traffic. See the _--help_ flag output for complete
|
||||
documentation.
|
||||
|
||||
|
||||
|
||||
# Examples
|
||||
|
||||
|
||||
## Saving traffic
|
||||
|
||||
<pre class="terminal">
|
||||
> mitmdump -w outfile
|
||||
</pre>
|
||||
|
||||
Start up mitmdump in proxy mode, and write all traffic to __outfile__.
|
||||
|
||||
|
||||
## Filtering saved traffic
|
||||
|
||||
<pre class="terminal">
|
||||
> mitmdump -nr infile -w outfile "~m post"
|
||||
</pre>
|
||||
|
||||
Start mitmdump without binding to the proxy port (_-n_), read all flows from
|
||||
infile, apply the specified filter expression (only match POSTs), and write to
|
||||
outfile.
|
||||
|
||||
|
||||
## Client replay
|
||||
|
||||
<pre class="terminal">
|
||||
> mitmdump -nc outfile
|
||||
</pre>
|
||||
|
||||
Start mitmdump without binding to the proxy port (_-n_), then replay all
|
||||
requests from outfile (_-c filename_). Flags combine in the obvious way, so
|
||||
you can replay requests from one file, and write the resulting flows to
|
||||
another:
|
||||
|
||||
<pre class="terminal">
|
||||
> mitmdump -nc srcfile -w dstfile
|
||||
</pre>
|
||||
|
||||
See the [Client-side Replay](@!urlTo("clientreplay.html")!@) section for more information.
|
||||
|
||||
|
||||
## Running a script
|
||||
|
||||
<pre class="terminal">
|
||||
> mitmdump -s examples/add_header.py
|
||||
</pre>
|
||||
|
||||
This runs the __add_header.py__ example script, which simply adds a new header
|
||||
to all responses.
|
||||
|
||||
|
||||
## Scripted data transformation
|
||||
|
||||
<pre class="terminal">
|
||||
> mitmdump -ns examples/add_header.py -r srcfile -w dstfile
|
||||
</pre>
|
||||
|
||||
This command loads flows from __srcfile__, transforms it according to the
|
||||
specified script, then writes it back to __dstfile__.
|
||||
|
||||
115
doc-src/mitmproxy.html
Normal file
@@ -0,0 +1,115 @@
|
||||
|
||||
__mitmproxy__ is a console tool that allows interactive examination and
|
||||
modification of HTTP traffic. It differs from mitmdump in that all flows are
|
||||
kept in memory, which means that it's intended for taking and manipulating
|
||||
small-ish samples. Use the _?_ shortcut key to view, context-sensitive
|
||||
documentation from any __mitmproxy__ screen.
|
||||
|
||||
## Flow list
|
||||
|
||||
The flow list shows an index of captured flows in chronological order.
|
||||
|
||||
<img src="@!urlTo('screenshots/mitmproxy.png')!@"/>
|
||||
|
||||
- __1__: A GET request, returning a 302 Redirect response.
|
||||
- __2__: A GET request, returning 16.75kb of text/html data.
|
||||
- __3__: A replayed request.
|
||||
- __4__: Intercepted flows are indicated with orange text. The user may edit
|
||||
these flows, and then accept them (using the _a_ key) to continue. In this
|
||||
case, the request has been intercepted on the way to the server.
|
||||
- __5__: A response intercepted from the server on the way to the client.
|
||||
- __6__: The event log can be toggled on and off using the _e_ shortcut key. This
|
||||
pane shows events and errors that may not result in a flow that shows up in the
|
||||
flow pane.
|
||||
- __7__: Flow count.
|
||||
- __8__: Various information on mitmproxy's state. In this case, we have an
|
||||
interception pattern set to ".*".
|
||||
- __9__: Bind address indicator - mitmproxy is listening on port 8080 of all
|
||||
interfaces.
|
||||
|
||||
|
||||
## Flow view
|
||||
|
||||
The __Flow View__ lets you inspect and manipulate a single flow:
|
||||
|
||||
<img src="@!urlTo('screenshots/mitmproxy-flowview.png')!@"/>
|
||||
|
||||
- __1__: Flow summary.
|
||||
- __2__: The Request/Response tabs, showing you which part of the flow you are
|
||||
currently viewing. In the example above, we're viewing the Response. Hit _tab_
|
||||
to switch between the Response and the Request.
|
||||
- __3__: Headers.
|
||||
- __4__: Body.
|
||||
- __5__: View Mode indicator. In this case, we're viewing the body in __hex__
|
||||
mode. The other available modes are __pretty__, which uses a number of
|
||||
heuristics to show you a friendly view of various content types, and __raw__,
|
||||
which shows you exactly what's there without any changes. You can change modes
|
||||
using the _m_ key.
|
||||
|
||||
|
||||
|
||||
## Grid Editor
|
||||
|
||||
Much of the data that we'd like to interact with in mitmproxy is structured.
|
||||
For instance, headers, queries and form data can all be thought of as a list of
|
||||
key/value pairs. Mitmproxy has a built-in editor that lays this type of data
|
||||
out in a grid for easy manipulation.
|
||||
|
||||
At the moment, the Grid Editor is used in four parts of mitmproxy:
|
||||
|
||||
- Editing request or response headers (_e_ for edit, then _h_ for headers in flow view)
|
||||
- Editing a query string (_e_ for edit, then _q_ for query in flow view)
|
||||
- Editing a URL-encoded form (_e_ for edit, then _f_ for form in flow view)
|
||||
- Editing replacement patterns (_R_ globally)
|
||||
|
||||
If there is is no data, an empty editor will be started to let you add some.
|
||||
Here is the editor showing the headers from a request:
|
||||
|
||||
<img src="@!urlTo('screenshots/mitmproxy-kveditor.png')!@"/>
|
||||
|
||||
To edit, navigate to the key or value you want to modify using the arrow or vi
|
||||
navigation keys, and press enter. The background color will change to show that
|
||||
you are in edit mode for the specified field:
|
||||
|
||||
<img src="@!urlTo('screenshots/mitmproxy-kveditor-editmode.png')!@"/>
|
||||
|
||||
Modify the field as desired, then press escape to exit edit mode when you're
|
||||
done. You can also add a row (_a_ key), delete a row (_d_ key), spawn an
|
||||
external editor on a field (_e_ key). Be sure to consult the context-sensitive
|
||||
help (_?_ key) for more.
|
||||
|
||||
|
||||
# Example: Interception
|
||||
|
||||
__mitmproxy__'s interception functionality lets you pause an HTTP request or
|
||||
response, inspect and modify it, and then accept it to send it on to the server
|
||||
or client.
|
||||
|
||||
|
||||
### 1: Set an interception pattern
|
||||
|
||||
<img src="@!urlTo('mitmproxy-intercept-filt.png')!@"/>
|
||||
|
||||
We press _i_ to set an interception pattern. In this case, the __~q__ filter
|
||||
pattern tells __mitmproxy__ to intercept all requests. For complete filter
|
||||
syntax, see the [Filter expressions](@!urlTo("filters.html")!@) section of this
|
||||
document, or the built-in help function in __mitmproxy__.
|
||||
|
||||
### 2: Intercepted connections are indicated with orange text:
|
||||
|
||||
<img src="@!urlTo('mitmproxy-intercept-mid.png')!@"/>
|
||||
|
||||
### 3: You can now view and modify the request:
|
||||
|
||||
<img src="@!urlTo('mitmproxy-intercept-options.png')!@"/>
|
||||
|
||||
In this case, we viewed the request by selecting it, pressed _e_ for "edit"
|
||||
and _m_ for "method" to change the HTTP request method.
|
||||
|
||||
### 4: Accept the intercept to continue:
|
||||
|
||||
<img src="@!urlTo('mitmproxy-intercept-result.png')!@"/>
|
||||
|
||||
Finally, we press _a_ to accept the modified request, which is then sent on to
|
||||
the server. In this case, we changed the request from an HTTP GET to
|
||||
OPTIONS, and Google's server has responded with a 405 "Method not allowed".
|
||||
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 308 KiB After Width: | Height: | Size: 308 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 149 KiB After Width: | Height: | Size: 149 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 65 KiB |
6
doc-src/scripting/index.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from countershape import Page
|
||||
|
||||
pages = [
|
||||
Page("inlinescripts.html", "Inline Scripts"),
|
||||
Page("libmproxy.html", "libmproxy"),
|
||||
]
|
||||
149
doc-src/scripting/inlinescripts.html
Normal file
@@ -0,0 +1,149 @@
|
||||
__mitmproxy__ has a powerful scripting API that allows you to modify flows
|
||||
on-the-fly or rewrite previously saved flows locally.
|
||||
|
||||
The mitmproxy scripting API is event driven - a script is simply a Python
|
||||
module that exposes a set of event methods. Here's a complete mitmproxy script
|
||||
that adds a new header to every HTTP response before it is returned to the
|
||||
client:
|
||||
|
||||
$!example("examples/add_header.py")!$
|
||||
|
||||
The first argument to each event method is an instance of ScriptContext that
|
||||
lets the script interact with the global mitmproxy state. The __response__
|
||||
event also gets an instance of Flow, which we can use to manipulate the
|
||||
response itself.
|
||||
|
||||
We can now run this script using mitmdump or mitmproxy as follows:
|
||||
|
||||
<pre class="terminal">
|
||||
> mitmdump -s add_header.py
|
||||
</pre>
|
||||
|
||||
The new header will be added to all responses passing through the proxy.
|
||||
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
### start(ScriptContext, argv)
|
||||
|
||||
Called once on startup, before any other events.
|
||||
|
||||
|
||||
### clientconnect(ScriptContext, ClientConnect)
|
||||
|
||||
Called when a client initiates a connection to the proxy. Note that
|
||||
a connection can correspond to multiple HTTP requests.
|
||||
|
||||
|
||||
### serverconnect(ScriptContext, ServerConnection)
|
||||
|
||||
Called when the proxy initiates a connection to the target server. Note that
|
||||
a connection can correspond to multiple HTTP requests.
|
||||
|
||||
### request(ScriptContext, Flow)
|
||||
|
||||
Called when a client request has been received. The __Flow__ object is
|
||||
guaranteed to have a non-None __request__ attribute.
|
||||
|
||||
|
||||
### response(ScriptContext, Flow)
|
||||
|
||||
Called when a server response has been received. The __Flow__ object is
|
||||
guaranteed to have non-None __request__ and __response__ attributes.
|
||||
|
||||
|
||||
### error(ScriptContext, Flow)
|
||||
|
||||
Called when a flow error has occurred, e.g. invalid server responses, or
|
||||
interrupted connections. This is distinct from a valid server HTTP error
|
||||
response, which is simply a response with an HTTP error code. The __Flow__
|
||||
object is guaranteed to have non-None __request__ and __error__ attributes.
|
||||
|
||||
|
||||
### clientdisconnect(ScriptContext, ClientDisconnect)
|
||||
|
||||
Called when a client disconnects from the proxy.
|
||||
|
||||
### done(ScriptContext)
|
||||
|
||||
Called once on script shutdown, after any other events.
|
||||
|
||||
|
||||
## API
|
||||
|
||||
The main classes you will deal with in writing mitmproxy scripts are:
|
||||
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>libmproxy.flow.ClientConnection</th>
|
||||
<td>Describes a client connection.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>libmproxy.flow.ClientDisconnection</th>
|
||||
<td>Describes a client disconnection.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>libmproxy.flow.Error</th>
|
||||
<td>A communications error.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>libmproxy.flow.Flow</th>
|
||||
<td>A collection of objects representing a single HTTP transaction.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>libmproxy.flow.Headers</th>
|
||||
<td>HTTP headers for a request or response.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>libmproxy.flow.ODict</th>
|
||||
|
||||
<td>A dictionary-like object for managing sets of key/value data. There
|
||||
is also a variant called CaselessODict that ignores key case for some
|
||||
calls (used mainly for headers).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>libmproxy.flow.Response</th>
|
||||
<td>An HTTP response.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>libmproxy.flow.Request</th>
|
||||
<td>An HTTP request.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>libmproxy.flow.ScriptContext</th>
|
||||
<td> A handle for interacting with mitmproxy's from within scripts. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>libmproxy.certutils.SSLCert</th>
|
||||
<td>Exposes information SSL certificates.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
The canonical API documentation is the code. You can view the API documentation
|
||||
using pydoc (which is installed with Python by default), like this:
|
||||
|
||||
<pre class="terminal">
|
||||
> pydoc libmproxy.flow.Request
|
||||
</pre>
|
||||
|
||||
|
||||
## Running scripts in parallel
|
||||
|
||||
We have a single flow primitive, so when a script is handling something, other requests block.
|
||||
While that's a very desirable behaviour under some circumstances, scripts can be run threaded by using the <code>libmproxy.script.concurrent</code> decorator.
|
||||
|
||||
$!example("examples/nonblocking.py")!$
|
||||
|
||||
## Running scripts on saved flows
|
||||
|
||||
Sometimes, we want to run a script on __Flow__ objects that are already
|
||||
complete. This happens when you start a script, and then load a saved set of
|
||||
flows from a file (see the "scripted data transformation" example on the
|
||||
[mitmdump](@!urlTo("mitmdump.html")!@) page). It also happens when you run a
|
||||
one-shot script on a single flow through the _|_ (pipe) shortcut in mitmproxy.
|
||||
|
||||
In this case, there are no client connections, and the events are run in the
|
||||
following order: __start__, __request__, __response__, __error__, __done__. If
|
||||
the flow doesn't have a __response__ or __error__ associated with it, the
|
||||
matching event will be skipped.
|
||||
12
doc-src/scripting/libmproxy.html
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
All of mitmproxy's basic functionality is exposed through the __libmproxy__
|
||||
library. The example below shows a simple implementation of the "sticky cookie"
|
||||
functionality included in the interactive mitmproxy program. Traffic is
|
||||
monitored for __cookie__ and __set-cookie__ headers, and requests are rewritten
|
||||
to include a previously seen cookie if they don't already have one. In effect,
|
||||
this lets you log in to a site using your browser, and then make subsequent
|
||||
requests using a tool like __curl__, which will then seem to be part of the
|
||||
authenticated session.
|
||||
|
||||
$!example("examples/stickycookies")!$
|
||||
|
||||
67
doc-src/ssl.html
Normal file
@@ -0,0 +1,67 @@
|
||||
|
||||
The first time __mitmproxy__ or __mitmdump__ is run, a set of certificate files
|
||||
for the mitmproxy Certificate Authority are created in the config directory
|
||||
(~/.mitmproxy by default). This CA is used for on-the-fly generation of dummy
|
||||
certificates for SSL interception. Since your browser won't trust the
|
||||
__mitmproxy__ CA out of the box (and rightly so), you will see an SSL cert
|
||||
warning every time you visit a new SSL domain through __mitmproxy__. When
|
||||
you're testing a single site through a browser, just accepting the bogus SSL
|
||||
cert manually is not too much trouble, but there are a many circumstances where
|
||||
you will want to configure your testing system or browser to trust the
|
||||
__mitmproxy__ CA as a signing root authority.
|
||||
|
||||
|
||||
CA and cert files
|
||||
-----------------
|
||||
|
||||
The files created by mitmproxy in the .mitmproxy directory are as follows:
|
||||
|
||||
<table class="table">
|
||||
<tr>
|
||||
<td class="nowrap">mitmproxy-ca.pem</td>
|
||||
<td>The private key and certificate in PEM format.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="nowrap">mitmproxy-ca-cert.pem</td>
|
||||
<td>The certificate in PEM format. Use this to distribute to most
|
||||
non-Windows platforms.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="nowrap">mitmproxy-ca-cert.p12</td>
|
||||
<td>The certificate in PKCS12 format. For use on Windows.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="nowrap">mitmproxy-ca-cert.cer</td>
|
||||
<td>Same file as .pem, but with an extension expected by some Android
|
||||
devices.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
Using a custom certificate
|
||||
--------------------------
|
||||
|
||||
You can use your own certificate by passing the __--cert__ option to mitmproxy.
|
||||
|
||||
The certificate file is expected to be in the PEM format. You can generate
|
||||
a certificate in this format using these instructions:
|
||||
|
||||
<pre class="terminal">
|
||||
> openssl genrsa -out cert.key 8192
|
||||
> openssl req -new -x509 -key cert.key -out cert.crt
|
||||
(Specify the mitm domain as Common Name, e.g. *.google.com)
|
||||
> cat cert.key cert.crt > cert.pem
|
||||
> mitmproxy --cert=cert.pem
|
||||
</pre>
|
||||
|
||||
|
||||
Installing the mitmproxy CA
|
||||
---------------------------
|
||||
|
||||
* [Firefox](@!urlTo("certinstall/firefox.html")!@)
|
||||
* [OSX](@!urlTo("certinstall/osx.html")!@)
|
||||
* [Windows 7](@!urlTo("certinstall/windows7.html")!@)
|
||||
* [iPhone/iPad](@!urlTo("certinstall/ios.html")!@)
|
||||
* [IOS Simulator](@!urlTo("certinstall/ios-simulator.html")!@)
|
||||
* [Android](@!urlTo("certinstall/android.html")!@)
|
||||
|
||||
120
doc-src/syntax.css
Normal file
@@ -0,0 +1,120 @@
|
||||
.highlight { background: #f8f8f8; }
|
||||
.highlight .c { color: #408080; font-style: italic } /* Comment */
|
||||
.highlight .err { border: 1px solid #FF0000 } /* Error */
|
||||
.highlight .k { color: #008000; font-weight: bold } /* Keyword */
|
||||
.highlight .o { color: #666666 } /* Operator */
|
||||
.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */
|
||||
.highlight .cp { color: #BC7A00 } /* Comment.Preproc */
|
||||
.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */
|
||||
.highlight .cs { color: #408080; font-style: italic } /* Comment.Special */
|
||||
.highlight .gd { color: #A00000 } /* Generic.Deleted */
|
||||
.highlight .ge { font-style: italic } /* Generic.Emph */
|
||||
.highlight .gr { color: #FF0000 } /* Generic.Error */
|
||||
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
|
||||
.highlight .gi { color: #00A000 } /* Generic.Inserted */
|
||||
.highlight .go { color: #808080 } /* Generic.Output */
|
||||
.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
|
||||
.highlight .gs { font-weight: bold } /* Generic.Strong */
|
||||
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
|
||||
.highlight .gt { color: #0040D0 } /* Generic.Traceback */
|
||||
.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
|
||||
.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
|
||||
.highlight .kp { color: #008000 } /* Keyword.Pseudo */
|
||||
.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
|
||||
.highlight .kt { color: #B00040 } /* Keyword.Type */
|
||||
.highlight .m { color: #666666 } /* Literal.Number */
|
||||
.highlight .s { color: #BA2121 } /* Literal.String */
|
||||
.highlight .na { color: #7D9029 } /* Name.Attribute */
|
||||
.highlight .nb { color: #008000 } /* Name.Builtin */
|
||||
.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */
|
||||
.highlight .no { color: #880000 } /* Name.Constant */
|
||||
.highlight .nd { color: #AA22FF } /* Name.Decorator */
|
||||
.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */
|
||||
.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
|
||||
.highlight .nf { color: #0000FF } /* Name.Function */
|
||||
.highlight .nl { color: #A0A000 } /* Name.Label */
|
||||
.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
|
||||
.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
|
||||
.highlight .nv { color: #19177C } /* Name.Variable */
|
||||
.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
|
||||
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
|
||||
.highlight .mf { color: #666666 } /* Literal.Number.Float */
|
||||
.highlight .mh { color: #666666 } /* Literal.Number.Hex */
|
||||
.highlight .mi { color: #666666 } /* Literal.Number.Integer */
|
||||
.highlight .mo { color: #666666 } /* Literal.Number.Oct */
|
||||
.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
|
||||
.highlight .sc { color: #BA2121 } /* Literal.String.Char */
|
||||
.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
|
||||
.highlight .s2 { color: #BA2121 } /* Literal.String.Double */
|
||||
.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
|
||||
.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
|
||||
.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
|
||||
.highlight .sx { color: #008000 } /* Literal.String.Other */
|
||||
.highlight .sr { color: #BB6688 } /* Literal.String.Regex */
|
||||
.highlight .s1 { color: #BA2121 } /* Literal.String.Single */
|
||||
.highlight .ss { color: #19177C } /* Literal.String.Symbol */
|
||||
.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
|
||||
.highlight .vc { color: #19177C } /* Name.Variable.Class */
|
||||
.highlight .vg { color: #19177C } /* Name.Variable.Global */
|
||||
.highlight .vi { color: #19177C } /* Name.Variable.Instance */
|
||||
.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
|
||||
.grokdoc { background: #f8f8f8; }
|
||||
.grokdoc .c { color: #408080; font-style: italic } /* Comment */
|
||||
.grokdoc .err { border: 1px solid #FF0000 } /* Error */
|
||||
.grokdoc .k { color: #008000; font-weight: bold } /* Keyword */
|
||||
.grokdoc .o { color: #666666 } /* Operator */
|
||||
.grokdoc .cm { color: #408080; font-style: italic } /* Comment.Multiline */
|
||||
.grokdoc .cp { color: #BC7A00 } /* Comment.Preproc */
|
||||
.grokdoc .c1 { color: #408080; font-style: italic } /* Comment.Single */
|
||||
.grokdoc .cs { color: #408080; font-style: italic } /* Comment.Special */
|
||||
.grokdoc .gd { color: #A00000 } /* Generic.Deleted */
|
||||
.grokdoc .ge { font-style: italic } /* Generic.Emph */
|
||||
.grokdoc .gr { color: #FF0000 } /* Generic.Error */
|
||||
.grokdoc .gh { color: #000080; font-weight: bold } /* Generic.Heading */
|
||||
.grokdoc .gi { color: #00A000 } /* Generic.Inserted */
|
||||
.grokdoc .go { color: #808080 } /* Generic.Output */
|
||||
.grokdoc .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
|
||||
.grokdoc .gs { font-weight: bold } /* Generic.Strong */
|
||||
.grokdoc .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
|
||||
.grokdoc .gt { color: #0040D0 } /* Generic.Traceback */
|
||||
.grokdoc .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
|
||||
.grokdoc .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
|
||||
.grokdoc .kp { color: #008000 } /* Keyword.Pseudo */
|
||||
.grokdoc .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
|
||||
.grokdoc .kt { color: #B00040 } /* Keyword.Type */
|
||||
.grokdoc .m { color: #666666 } /* Literal.Number */
|
||||
.grokdoc .s { color: #BA2121 } /* Literal.String */
|
||||
.grokdoc .na { color: #7D9029 } /* Name.Attribute */
|
||||
.grokdoc .nb { color: #008000 } /* Name.Builtin */
|
||||
.grokdoc .nc { color: #0000FF; font-weight: bold } /* Name.Class */
|
||||
.grokdoc .no { color: #880000 } /* Name.Constant */
|
||||
.grokdoc .nd { color: #AA22FF } /* Name.Decorator */
|
||||
.grokdoc .ni { color: #999999; font-weight: bold } /* Name.Entity */
|
||||
.grokdoc .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
|
||||
.grokdoc .nf { color: #0000FF } /* Name.Function */
|
||||
.grokdoc .nl { color: #A0A000 } /* Name.Label */
|
||||
.grokdoc .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
|
||||
.grokdoc .nt { color: #008000; font-weight: bold } /* Name.Tag */
|
||||
.grokdoc .nv { color: #19177C } /* Name.Variable */
|
||||
.grokdoc .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
|
||||
.grokdoc .w { color: #bbbbbb } /* Text.Whitespace */
|
||||
.grokdoc .mf { color: #666666 } /* Literal.Number.Float */
|
||||
.grokdoc .mh { color: #666666 } /* Literal.Number.Hex */
|
||||
.grokdoc .mi { color: #666666 } /* Literal.Number.Integer */
|
||||
.grokdoc .mo { color: #666666 } /* Literal.Number.Oct */
|
||||
.grokdoc .sb { color: #BA2121 } /* Literal.String.Backtick */
|
||||
.grokdoc .sc { color: #BA2121 } /* Literal.String.Char */
|
||||
.grokdoc .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
|
||||
.grokdoc .s2 { color: #BA2121 } /* Literal.String.Double */
|
||||
.grokdoc .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
|
||||
.grokdoc .sh { color: #BA2121 } /* Literal.String.Heredoc */
|
||||
.grokdoc .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
|
||||
.grokdoc .sx { color: #008000 } /* Literal.String.Other */
|
||||
.grokdoc .sr { color: #BB6688 } /* Literal.String.Regex */
|
||||
.grokdoc .s1 { color: #BA2121 } /* Literal.String.Single */
|
||||
.grokdoc .ss { color: #19177C } /* Literal.String.Symbol */
|
||||
.grokdoc .bp { color: #008000 } /* Name.Builtin.Pseudo */
|
||||
.grokdoc .vc { color: #19177C } /* Name.Variable.Class */
|
||||
.grokdoc .vg { color: #19177C } /* Name.Variable.Global */
|
||||
.grokdoc .vi { color: #19177C } /* Name.Variable.Instance */
|
||||
.grokdoc .il { color: #666666 } /* Literal.Number.Integer.Long */
|
||||
19
doc-src/transparent.html
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
When a transparent proxy is used, traffic is redirected into a proxy at the
|
||||
network layer, without any client configuration being required. This makes
|
||||
transparent proxying ideal for those situations where you can't change client
|
||||
behaviour - proxy-oblivious Android applications being a common example.
|
||||
|
||||
To set up transparent proxying, we need two new components. The first is a
|
||||
redirection mechanism that transparently reroutes a TCP connection destined for
|
||||
a server on the Internet to a listening proxy server. This usually takes the
|
||||
form of a firewall on the same host as the proxy server -
|
||||
[iptables](http://www.netfilter.org/) on Linux or
|
||||
[pf](http://en.wikipedia.org/wiki/PF_\(firewall\)) on OSX. When the proxy
|
||||
receives a redirected connection, it sees a vanilla HTTP request, without a
|
||||
host specification. This is where the second new component comes in - a host
|
||||
module that allows us to query the redirector for the original destination of
|
||||
the TCP connection.
|
||||
|
||||
At the moment, mitmproxy supports transparent proxying on OSX Lion and above,
|
||||
and all current flavors of Linux.
|
||||
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
6
doc-src/transparent/index.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from countershape import Page
|
||||
|
||||
pages = [
|
||||
Page("osx.html", "OSX"),
|
||||
Page("linux.html", "Linux"),
|
||||
]
|
||||
43
doc-src/transparent/linux.html
Normal file
@@ -0,0 +1,43 @@
|
||||
On Linux, mitmproxy integrates with the iptables redirection mechanism to
|
||||
achieve transparent mode.
|
||||
|
||||
<ol class="tlist">
|
||||
|
||||
<li> <a href="@!urlTo('ssl.html')!@">Install the mitmproxy
|
||||
certificates on the test device</a>. </li>
|
||||
|
||||
<li> Enable IP forwarding:
|
||||
|
||||
<pre class="terminal">sysctl -w net.ipv4.ip_forward=1</pre>
|
||||
|
||||
You may also want to consider enabling this permanently in
|
||||
<b>/etc/sysctl.conf</b>.
|
||||
|
||||
</li>
|
||||
|
||||
<li> Create an iptables ruleset that redirects the desired traffic to the
|
||||
mitmproxy port. Details will differ according to your setup, but the
|
||||
ruleset should look something like this:
|
||||
|
||||
<pre class="terminal">iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
|
||||
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 8080</pre>
|
||||
|
||||
</li>
|
||||
|
||||
<li> Fire up mitmproxy. You probably want a command like this:
|
||||
|
||||
<pre class="terminal">mitmproxy -T --host</pre>
|
||||
|
||||
The <b>-T</b> flag turns on transparent mode, and the <b>--host</b>
|
||||
argument tells mitmproxy to use the value of the Host header for URL
|
||||
display.
|
||||
|
||||
</li>
|
||||
|
||||
<li> Finally, configure your test device to use the host on which mitmproxy is
|
||||
running as the default gateway.</li>
|
||||
|
||||
</ol>
|
||||
|
||||
|
||||
For a detailed walkthrough, have a look at the <a href="@!urlTo('tutorials/transparent-dhcp.html')!@"><i>Transparently proxify virtual machines</i></a> tutorial.
|
||||
81
doc-src/transparent/osx.html
Normal file
@@ -0,0 +1,81 @@
|
||||
|
||||
|
||||
OSX Lion integrated the [pf](http://www.openbsd.org/faq/pf/) packet filter from
|
||||
the OpenBSD project, which mitmproxy uses to implement transparent mode on OSX.
|
||||
Note that this means we don't support transparent mode for earlier versions of
|
||||
OSX.
|
||||
|
||||
<ol class="tlist">
|
||||
|
||||
<li> <a href="@!urlTo('ssl.html')!@">Install the mitmproxy
|
||||
certificates on the test device</a>. </li>
|
||||
|
||||
<li> Enable IP forwarding:
|
||||
|
||||
<pre class="terminal">sudo sysctl -w net.inet.ip.forwarding=1</pre>
|
||||
</li>
|
||||
|
||||
<li> Place the following two lines in a file called, say, <b>pf.conf</b>:
|
||||
|
||||
<pre class="terminal">rdr on en2 inet proto tcp to any port 80 -> 127.0.0.1 port 8080
|
||||
rdr on en2 inet proto tcp to any port 443 -> 127.0.0.1 port 8080
|
||||
</pre>
|
||||
|
||||
These rules tell pf to redirect all traffic destined for port 80 or 443
|
||||
to the local mitmproxy instance running on port 8080. You should
|
||||
replace <b>en2</b> with the interface on which your test device will
|
||||
appear.
|
||||
|
||||
</li>
|
||||
|
||||
<li> Configure pf with the rules:
|
||||
|
||||
<pre class="terminal">sudo pfctl -f pf.conf</pre>
|
||||
|
||||
</li>
|
||||
|
||||
<li> And now enable it:
|
||||
|
||||
<pre class="terminal">sudo pfctl -e</pre>
|
||||
|
||||
</li>
|
||||
|
||||
<li> Configure sudoers to allow mitmproxy to access pfctl. Edit the file
|
||||
<b>/etc/sudoers</b> on your system as root. Add the following line to the end
|
||||
of the file:
|
||||
|
||||
<pre>ALL ALL=NOPASSWD: /sbin/pfctl -s state</pre>
|
||||
|
||||
Note that this allows any user on the system to run the command
|
||||
"/sbin/pfctl -s state" as root without a password. This only allows
|
||||
inspection of the state table, so should not be an undue security risk. If
|
||||
you're special feel free to tighten the restriction up to the user running
|
||||
mitmproxy.</li>
|
||||
|
||||
<li> Fire up mitmproxy. You probably want a command like this:
|
||||
|
||||
<pre class="terminal">mitmproxy -T --host</pre>
|
||||
|
||||
The <b>-T</b> flag turns on transparent mode, and the <b>--host</b>
|
||||
argument tells mitmproxy to use the value of the Host header for URL
|
||||
display.
|
||||
|
||||
</li>
|
||||
|
||||
<li> Finally, configure your test device to use the host on which mitmproxy is
|
||||
running as the default gateway.</li>
|
||||
|
||||
|
||||
</ol>
|
||||
|
||||
Note that the **rdr** rules in the pf.conf given above only apply to inbound
|
||||
traffic. This means that they will NOT redirect traffic coming from the box
|
||||
running pf itself. We can't distinguish between an outbound connection from a
|
||||
non-mitmproxy app, and an outbound connection from mitmproxy itself - if you
|
||||
want to intercept your OSX traffic, you should use an external host to run
|
||||
mitmproxy. None the less, pf is flexible to cater for a range of creative
|
||||
possibilities, like intercepting traffic emanating from VMs. See the
|
||||
**pf.conf** man page for more.
|
||||
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 78 KiB |
@@ -1,50 +1,48 @@
|
||||
.. _30second:
|
||||
|
||||
Client playback: a 30 second example
|
||||
====================================
|
||||
|
||||
My local cafe is serviced by a rickety and unreliable wireless network,
|
||||
generously sponsored with ratepayers' money by our city council. After
|
||||
connecting, you are redirected to an SSL-protected page that prompts you for a
|
||||
username and password. Once you've entered your details, you are free to enjoy
|
||||
the intermittent dropouts, treacle-like speeds and incorrectly configured
|
||||
transparent proxy.
|
||||
transparent proxy.
|
||||
|
||||
I tend to automate this kind of thing at the first opportunity, on the theory
|
||||
that time spent now will be more than made up in the long run. In this case, I
|
||||
might use Firebug_ to ferret out the form post
|
||||
might use [Firebug](http://getfirebug.com/) to ferret out the form post
|
||||
parameters and target URL, then fire up an editor to write a little script
|
||||
using Python's urllib_ to simulate a submission.
|
||||
That's a lot of futzing about. With mitmproxy we can do the job
|
||||
using Python's [urllib](http://docs.python.org/library/urllib.html) to simulate
|
||||
a submission. That's a lot of futzing about. With mitmproxy we can do the job
|
||||
in literally 30 seconds, without having to worry about any of the details.
|
||||
Here's how.
|
||||
|
||||
1. Run mitmdump to record our HTTP conversation to a file.
|
||||
----------------------------------------------------------
|
||||
## 1. Run mitmdump to record our HTTP conversation to a file.
|
||||
|
||||
>>> mitmdump -w wireless-login
|
||||
<pre class="terminal">
|
||||
> mitmdump -w wireless-login
|
||||
</pre>
|
||||
|
||||
2. Point your browser at the mitmdump instance.
|
||||
-----------------------------------------------
|
||||
## 2. Point your browser at the mitmdump instance.
|
||||
|
||||
I use a tiny Firefox addon called `Toggle Proxy`_ to switch quickly to and from mitmproxy.
|
||||
I'm assuming you've already :ref:`configured
|
||||
I use a tiny Firefox addon called [Toggle
|
||||
Proxy](https://addons.mozilla.org/en-us/firefox/addon/toggle-proxy-51740/) to
|
||||
switch quickly to and from mitmproxy. I'm assuming you've already [configured
|
||||
your browser with mitmproxy's SSL certificate
|
||||
authority <certinstall>`.
|
||||
authority](http://mitmproxy.org/doc/ssl.html).
|
||||
|
||||
## 3. Log in as usual.
|
||||
|
||||
3. Log in as usual.
|
||||
-------------------
|
||||
|
||||
And that's it! You now have a serialized version of the login process in the
|
||||
file wireless-login, and you can replay it at any time like this:
|
||||
|
||||
>>> mitmdump -c wireless-login
|
||||
<pre class="terminal">
|
||||
> mitmdump -c wireless-login
|
||||
</pre>
|
||||
|
||||
Embellishments
|
||||
--------------
|
||||
## Embellishments
|
||||
|
||||
We're really done at this point, but there are a couple of embellishments we
|
||||
could make if we wanted. I use wicd_ to
|
||||
could make if we wanted. I use [wicd](http://wicd.sourceforge.net/) to
|
||||
automatically join wireless networks I frequent, and it lets me specify a
|
||||
command to run after connecting. I used the client replay command above and
|
||||
voila! - totally hands-free wireless network startup.
|
||||
@@ -54,13 +52,10 @@ forth. These add only a few moments to the time it takes to replay, but they're
|
||||
not really needed and I somehow feel compelled to trim them anyway. So, we fire up
|
||||
the mitmproxy console tool on our serialized conversation, like so:
|
||||
|
||||
>>> mitmproxy -r wireless-login
|
||||
<pre class="terminal">
|
||||
> mitmproxy -r wireless-login
|
||||
</pre>
|
||||
|
||||
We can now go through and manually delete (using the :kbd:`d` keyboard shortcut)
|
||||
everything we want to trim. When we're done, we use :kbd:`w` to save the
|
||||
We can now go through and manually delete (using the __d__ keyboard shortcut)
|
||||
everything we want to trim. When we're done, we use __w__ to save the
|
||||
conversation back to the file.
|
||||
|
||||
.. _Firebug: https://getfirebug.com/
|
||||
.. _urllib: https://docs.python.org/library/urllib.html
|
||||
.. _Toggle Proxy: https://addons.mozilla.org/en-us/firefox/addon/toggle-proxy-51740/
|
||||
.. _wicd: https://launchpad.net/wicd
|
||||