Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4294c4d777 | ||
|
|
219d1ab30c | ||
|
|
4e200fd0bd |
@@ -1,31 +0,0 @@
|
||||
version: '{build}'
|
||||
build: off # Not a C# project
|
||||
environment:
|
||||
matrix:
|
||||
- PYTHON: "C:\\Python27"
|
||||
PATH: "%APPDATA%\\Python\\Scripts;C:\\Python27;C:\\Python27\\Scripts;%PATH%"
|
||||
SNAPSHOT_HOST:
|
||||
secure: NeTo57s2rJhCd/mjKHetXVxCFd3uhr8txnjnAXD1tUI=
|
||||
SNAPSHOT_PORT:
|
||||
secure: TiJPtg60/edYTH8RnoBErg==
|
||||
SNAPSHOT_USER:
|
||||
secure: 6yBwmO5gv4vAwoFYII8qjQ==
|
||||
SNAPSHOT_PASS:
|
||||
secure: LPjrtFrWxYhOVGXzfPRV1GjtZE/wHoKq9m/PI6hSalfysUK5p2DxTG9uHlb4Q9qV
|
||||
install:
|
||||
- "pip install --user -U virtualenv"
|
||||
- "dev.bat"
|
||||
- "python -c \"from OpenSSL import SSL; print(SSL.SSLeay_version(SSL.SSLEAY_VERSION))\""
|
||||
test_script:
|
||||
- "py.test --cov netlib --cov mitmproxy --cov pathod"
|
||||
cache:
|
||||
- C:\Users\appveyor\AppData\Local\pip\cache
|
||||
deploy_script:
|
||||
ps: |
|
||||
if(($Env:APPVEYOR_REPO_BRANCH -match "master") -or ($Env:APPVEYOR_REPO_TAG -match "true")) {
|
||||
python .\release\rtool.py bdist
|
||||
python .\release\rtool.py upload-snapshot --bdist
|
||||
}
|
||||
notifications:
|
||||
- provider: Slack
|
||||
incoming_webhook: https://hooks.slack.com/services/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
|
||||
6
.coveragerc
Normal file
@@ -0,0 +1,6 @@
|
||||
[rum]
|
||||
branch = True
|
||||
|
||||
[report]
|
||||
omit = *contrib*, *tnetstring*, *platform*, *console*
|
||||
include = *libmproxy*
|
||||
@@ -1 +0,0 @@
|
||||
.git
|
||||
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/web/static/**/* -diff
|
||||
web/src/js/filt/filt.js -diff
|
||||
21
.gitignore
vendored
@@ -1,18 +1,17 @@
|
||||
.DS_Store
|
||||
MANIFEST
|
||||
*/tmp
|
||||
/build
|
||||
/dist
|
||||
/tmp
|
||||
/doc
|
||||
/venv
|
||||
/libmproxy/gui
|
||||
/release/build
|
||||
*.py[cdo]
|
||||
*.swp
|
||||
*.swo
|
||||
*.egg-info/
|
||||
mitmproxyc
|
||||
mitmdumpc
|
||||
.coverage
|
||||
.idea
|
||||
.cache/
|
||||
build/
|
||||
|
||||
# UI
|
||||
|
||||
node_modules
|
||||
bower_components
|
||||
*.map
|
||||
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
|
||||
@@ -1,171 +0,0 @@
|
||||
// Bootswatch.less
|
||||
// Swatch: Journal
|
||||
// Version: 2.0.4
|
||||
// -----------------------------------------------------
|
||||
|
||||
// TYPOGRAPHY
|
||||
// -----------------------------------------------------
|
||||
|
||||
@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700');
|
||||
|
||||
h1, h2, h3, h4, h5, h6, .navbar .brand {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
// SCAFFOLDING
|
||||
// -----------------------------------------------------
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.nav a, .navbar .brand, .subnav a, a.btn, .dropdown-menu a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
// NAVBAR
|
||||
// -----------------------------------------------------
|
||||
|
||||
.navbar {
|
||||
|
||||
.navbar-inner {
|
||||
@shadow: 0 2px 4px rgba(0,0,0,.25), inset 0 -1px 0 rgba(0,0,0,.1);
|
||||
.box-shadow(@shadow);
|
||||
border-top: 1px solid #E5E5E5;
|
||||
.border-radius(0);
|
||||
}
|
||||
|
||||
.brand {
|
||||
text-shadow: none;
|
||||
|
||||
&:hover {
|
||||
background-color: #EEEEEE;
|
||||
}
|
||||
}
|
||||
|
||||
.navbar-text {
|
||||
line-height: 68px;
|
||||
}
|
||||
|
||||
.nav > li > a {
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
.border-radius(0);
|
||||
}
|
||||
|
||||
.nav li.dropdown.active > .dropdown-toggle,
|
||||
.nav li.dropdown.active > .dropdown-toggle:hover,
|
||||
.nav li.dropdown.open > .dropdown-toggle,
|
||||
.nav li.dropdown.active.open > .dropdown-toggle,
|
||||
.nav li.dropdown.active.open > .dropdown-toggle:hover {
|
||||
background-color: @grayLighter;
|
||||
color: @linkColor;
|
||||
}
|
||||
|
||||
.nav li.dropdown .dropdown-toggle .caret,
|
||||
.nav .open .caret,
|
||||
.nav .open .dropdown-toggle:hover .caret {
|
||||
border-top-color: @black;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.nav-collapse.in .nav li > a:hover {
|
||||
background-color: @grayLighter;
|
||||
}
|
||||
|
||||
.nav-collapse .nav li > a {
|
||||
color: @textColor;
|
||||
text-decoration: none;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.nav-collapse .navbar-form,
|
||||
.nav-collapse .navbar-search {
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
.navbar-search .search-query,
|
||||
.navbar-search .search-query:hover {
|
||||
border: 1px solid @grayLighter;
|
||||
color: @textColor;
|
||||
.placeholder(@gray);
|
||||
}
|
||||
}
|
||||
|
||||
div.subnav {
|
||||
background-color: @bodyBackground;
|
||||
background-image: none;
|
||||
@shadow: 0 1px 2px rgba(0,0,0,.25);
|
||||
.box-shadow(@shadow);
|
||||
.border-radius(0);
|
||||
|
||||
&.subnav-fixed {
|
||||
top: @navbarHeight;
|
||||
}
|
||||
|
||||
.nav > li > a:hover,
|
||||
.nav > .active > a,
|
||||
.nav > .active > a:hover {
|
||||
color: @textColor;
|
||||
text-decoration: none;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.nav > li:first-child > a,
|
||||
.nav > li:first-child > a:hover {
|
||||
.border-radius(0);
|
||||
}
|
||||
}
|
||||
|
||||
// BUTTONS
|
||||
// -----------------------------------------------------
|
||||
|
||||
.btn-primary {
|
||||
.buttonBackground(lighten(@linkColor, 5%), @linkColor);
|
||||
}
|
||||
|
||||
[class^="icon-"], [class*=" icon-"] {
|
||||
vertical-align: -2px;
|
||||
}
|
||||
|
||||
// MODALS
|
||||
// -----------------------------------------------------
|
||||
|
||||
.modal {
|
||||
.border-radius(0px);
|
||||
background: @bodyBackground;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.modal-header .close {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
background: transparent;
|
||||
.box-shadow(none);
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
|
||||
// MISC
|
||||
// -----------------------------------------------------
|
||||
|
||||
code, pre, pre.prettyprint, .well {
|
||||
background-color: @grayLighter;
|
||||
}
|
||||
|
||||
.hero-unit {
|
||||
.box-shadow(inset 0 1px 1px rgba(0,0,0,.05));
|
||||
border: 1px solid rgba(0,0,0,.05);
|
||||
.border-radius(0);
|
||||
}
|
||||
|
||||
.table-bordered, .well, .prettyprint {
|
||||
.border-radius(0);
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/bin/sh
|
||||
pygmentize -f html ../examples/test_context.py > ../pathod/templates/examples_context.html
|
||||
pygmentize -f html ../examples/test_setup.py > ../pathod/templates/examples_setup.html
|
||||
pygmentize -f html ../examples/test_setupall.py > ../pathod/templates/examples_setupall.html
|
||||
pygmentize -f html ../examples/pathod_pathoc.py > ../pathod/templates/pathod_pathoc.html
|
||||
@@ -1,208 +0,0 @@
|
||||
// Variables.less
|
||||
// Variables to customize the look and feel of Bootstrap
|
||||
// Swatch: Journal
|
||||
// Version: 2.0.4
|
||||
// -----------------------------------------------------
|
||||
|
||||
// GLOBAL VALUES
|
||||
// --------------------------------------------------
|
||||
|
||||
|
||||
// Grays
|
||||
// -------------------------
|
||||
@black: #000;
|
||||
@grayDarker: #222;
|
||||
@grayDark: #333;
|
||||
@gray: #888;
|
||||
@grayLight: #999;
|
||||
@grayLighter: #eee;
|
||||
@white: #fff;
|
||||
|
||||
|
||||
// Accent colors
|
||||
// -------------------------
|
||||
@blue: #4380D3;
|
||||
@blueDark: darken(@blue, 15%);
|
||||
@green: #22B24C;
|
||||
@red: #C00;
|
||||
@yellow: #FCFADB;
|
||||
@orange: #FF7F00;
|
||||
@pink: #CC99CC;
|
||||
@purple: #7a43b6;
|
||||
@tan: #FFCA73;
|
||||
|
||||
|
||||
|
||||
// Scaffolding
|
||||
// -------------------------
|
||||
@bodyBackground: #FCFBFD;
|
||||
@textColor: @grayDarker;
|
||||
|
||||
|
||||
// Links
|
||||
// -------------------------
|
||||
@linkColor: @blue;
|
||||
@linkColorHover: @red;
|
||||
|
||||
|
||||
// Typography
|
||||
// -------------------------
|
||||
@sansFontFamily: 'Open Sans', "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
@serifFontFamily: Georgia, "Times New Roman", Times, serif;
|
||||
@monoFontFamily: Menlo, Monaco, Consolas, "Courier New", monospace;
|
||||
|
||||
@baseFontSize: 14px;
|
||||
@baseFontFamily: @sansFontFamily;
|
||||
@baseLineHeight: 18px;
|
||||
@altFontFamily: @serifFontFamily;
|
||||
|
||||
@headingsFontFamily: inherit; // empty to use BS default, @baseFontFamily
|
||||
@headingsFontWeight: bold; // instead of browser default, bold
|
||||
@headingsColor: inherit; // empty to use BS default, @textColor
|
||||
|
||||
|
||||
// Tables
|
||||
// -------------------------
|
||||
@tableBackground: transparent; // overall background-color
|
||||
@tableBackgroundAccent: @grayLighter; // for striping
|
||||
@tableBackgroundHover: #f5f5f5; // for hover
|
||||
@tableBorder: #ddd; // table and cell border
|
||||
|
||||
|
||||
// Buttons
|
||||
// -------------------------
|
||||
@btnBackground: @white;
|
||||
@btnBackgroundHighlight: darken(@white, 10%);
|
||||
@btnBorder: darken(@white, 20%);
|
||||
|
||||
@btnPrimaryBackground: @linkColor;
|
||||
@btnPrimaryBackgroundHighlight: spin(@btnPrimaryBackground, 15%);
|
||||
|
||||
@btnInfoBackground: #5bc0de;
|
||||
@btnInfoBackgroundHighlight: #2f96b4;
|
||||
|
||||
@btnSuccessBackground: #62c462;
|
||||
@btnSuccessBackgroundHighlight: #51a351;
|
||||
|
||||
@btnWarningBackground: lighten(@orange, 10%);
|
||||
@btnWarningBackgroundHighlight: @orange;
|
||||
|
||||
@btnDangerBackground: #ee5f5b;
|
||||
@btnDangerBackgroundHighlight: #bd362f;
|
||||
|
||||
@btnInverseBackground: @linkColor;
|
||||
@btnInverseBackgroundHighlight: darken(@linkColor, 5%);
|
||||
|
||||
|
||||
// Forms
|
||||
// -------------------------
|
||||
@inputBackground: @white;
|
||||
@inputBorder: #ccc;
|
||||
@inputBorderRadius: 3px;
|
||||
@inputDisabledBackground: @grayLighter;
|
||||
@formActionsBackground: @grayLighter;
|
||||
|
||||
// Dropdowns
|
||||
// -------------------------
|
||||
@dropdownBackground: @bodyBackground;
|
||||
@dropdownBorder: rgba(0,0,0,.2);
|
||||
@dropdownLinkColor: @textColor;
|
||||
@dropdownLinkColorHover: @textColor;
|
||||
@dropdownLinkBackgroundHover: #eee;
|
||||
@dropdownDividerTop: #e5e5e5;
|
||||
@dropdownDividerBottom: @white;
|
||||
|
||||
|
||||
|
||||
// COMPONENT VARIABLES
|
||||
// --------------------------------------------------
|
||||
|
||||
// Z-index master list
|
||||
// -------------------------
|
||||
// Used for a bird's eye view of components dependent on the z-axis
|
||||
// Try to avoid customizing these :)
|
||||
@zindexDropdown: 1000;
|
||||
@zindexPopover: 1010;
|
||||
@zindexTooltip: 1020;
|
||||
@zindexFixedNavbar: 1030;
|
||||
@zindexModalBackdrop: 1040;
|
||||
@zindexModal: 1050;
|
||||
|
||||
|
||||
// Sprite icons path
|
||||
// -------------------------
|
||||
@iconSpritePath: "../img/glyphicons-halflings.png";
|
||||
@iconWhiteSpritePath: "../img/glyphicons-halflings-white.png";
|
||||
|
||||
|
||||
// Input placeholder text color
|
||||
// -------------------------
|
||||
@placeholderText: @grayLight;
|
||||
|
||||
|
||||
// Hr border color
|
||||
// -------------------------
|
||||
@hrBorder: @grayLighter;
|
||||
|
||||
|
||||
// Navbar
|
||||
// -------------------------
|
||||
@navbarHeight: 50px;
|
||||
@navbarBackground: @bodyBackground;
|
||||
@navbarBackgroundHighlight: @bodyBackground;
|
||||
|
||||
@navbarText: @textColor;
|
||||
@navbarLinkColor: @linkColor;
|
||||
@navbarLinkColorHover: @linkColor;
|
||||
@navbarLinkColorActive: @navbarLinkColorHover;
|
||||
@navbarLinkBackgroundHover: @grayLighter;
|
||||
@navbarLinkBackgroundActive: @grayLighter;
|
||||
|
||||
@navbarSearchBackground: lighten(@navbarBackground, 25%);
|
||||
@navbarSearchBackgroundFocus: @white;
|
||||
@navbarSearchBorder: darken(@navbarSearchBackground, 30%);
|
||||
@navbarSearchPlaceholderColor: #ccc;
|
||||
@navbarBrandColor: @blue;
|
||||
|
||||
|
||||
// Hero unit
|
||||
// -------------------------
|
||||
@heroUnitBackground: @grayLighter;
|
||||
@heroUnitHeadingColor: inherit;
|
||||
@heroUnitLeadColor: inherit;
|
||||
|
||||
|
||||
// Form states and alerts
|
||||
// -------------------------
|
||||
@warningText: #c09853;
|
||||
@warningBackground: #fcf8e3;
|
||||
@warningBorder: darken(spin(@warningBackground, -10), 3%);
|
||||
|
||||
@errorText: #b94a48;
|
||||
@errorBackground: #f2dede;
|
||||
@errorBorder: darken(spin(@errorBackground, -10), 3%);
|
||||
|
||||
@successText: #468847;
|
||||
@successBackground: #dff0d8;
|
||||
@successBorder: darken(spin(@successBackground, -10), 5%);
|
||||
|
||||
@infoText: #3a87ad;
|
||||
@infoBackground: #d9edf7;
|
||||
@infoBorder: darken(spin(@infoBackground, -10), 7%);
|
||||
|
||||
|
||||
|
||||
// GRID
|
||||
// --------------------------------------------------
|
||||
|
||||
// Default 940px grid
|
||||
// -------------------------
|
||||
@gridColumns: 12;
|
||||
@gridColumnWidth: 60px;
|
||||
@gridGutterWidth: 20px;
|
||||
@gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1));
|
||||
|
||||
// Fluid grid
|
||||
// -------------------------
|
||||
@fluidGridColumnWidth: 6.382978723%;
|
||||
@fluidGridGutterWidth: 2.127659574%;
|
||||
82
.travis.yml
@@ -1,79 +1,21 @@
|
||||
sudo: false
|
||||
language: python
|
||||
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
# Debian sid currently holds OpenSSL 1.0.2
|
||||
# change this with future releases!
|
||||
- debian-sid
|
||||
packages:
|
||||
- libssl-dev
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
include:
|
||||
- python: 2.7
|
||||
- python: 2.7
|
||||
env: NO_ALPN=1
|
||||
- language: generic
|
||||
os: osx
|
||||
osx_image: xcode7.1
|
||||
git:
|
||||
depth: 9999999
|
||||
- python: 3.5
|
||||
env: SCOPE="netlib ./test/mitmproxy/script"
|
||||
- python: 3.5
|
||||
env: SCOPE="netlib ./test/mitmproxy/script" NO_ALPN=1
|
||||
- python: 2.7
|
||||
env: DOCS=1
|
||||
script: 'cd docs && make html'
|
||||
allow_failures:
|
||||
- python: pypy
|
||||
|
||||
install:
|
||||
- |
|
||||
if [[ $TRAVIS_OS_NAME == "osx" ]]
|
||||
then
|
||||
brew update || brew update # try again if it fails
|
||||
brew outdated openssl || brew upgrade openssl
|
||||
brew install python
|
||||
fi
|
||||
- pip install -U virtualenv
|
||||
- ./dev.sh
|
||||
- source ./venv/bin/activate
|
||||
|
||||
before_script:
|
||||
- "openssl version -a"
|
||||
- "python -c \"from OpenSSL import SSL; print(SSL.SSLeay_version(SSL.SSLEAY_VERSION))\""
|
||||
|
||||
script:
|
||||
- "py.test --cov netlib --cov mitmproxy --cov pathod ./test/$SCOPE"
|
||||
|
||||
after_success:
|
||||
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
|
||||
- |
|
||||
if [[ $TRAVIS_OS_NAME == "osx" && $TRAVIS_PULL_REQUEST == "false" && ($TRAVIS_BRANCH == "master" || -n $TRAVIS_TAG) ]]
|
||||
then
|
||||
pip install -e ./release
|
||||
python ./release/rtool.py bdist
|
||||
python ./release/rtool.py upload-snapshot --bdist --wheel
|
||||
fi
|
||||
|
||||
notifications:
|
||||
irc:
|
||||
channels:
|
||||
- "irc.oftc.net#mitmproxy"
|
||||
on_success: change
|
||||
on_failure: always
|
||||
slack:
|
||||
rooms:
|
||||
- mitmproxy:YaDGC9Gt9TEM7o8zkC2OLNsu#ci
|
||||
on_success: always
|
||||
on_failure: always
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.cache/pip
|
||||
- $HOME/.pyenv
|
||||
- $HOME/Library/Caches/pip
|
||||
|
||||
378
CHANGELOG
@@ -1,270 +1,10 @@
|
||||
9 April 2016: mitmproxy 0.17
|
||||
26 Februrary 2014: mitmproxy 0.10.1:
|
||||
|
||||
* 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
|
||||
@@ -284,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.
|
||||
|
||||
@@ -298,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.
|
||||
|
||||
@@ -343,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.
|
||||
@@ -357,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:
|
||||
|
||||
|
||||
141
CONTRIBUTORS
@@ -1,136 +1,51 @@
|
||||
1813 Aldo Cortesi
|
||||
1228 Maximilian Hils
|
||||
282 Thomas Kriechbaumer
|
||||
83 Marcelo Glezer
|
||||
28 Jim Shaver
|
||||
854 Aldo Cortesi
|
||||
64 Maximilian Hils
|
||||
18 Henrik Nordstrom
|
||||
17 Shadab Zafar
|
||||
14 David Weinstein
|
||||
14 Pedro Worcel
|
||||
13 Thomas Roth
|
||||
11 Jake Drahos
|
||||
11 Justus Wingert
|
||||
11 Stephen Altamirano
|
||||
10 András Veres-Szentkirályi
|
||||
10 Chris Czub
|
||||
10 Sandor Nemes
|
||||
9 Kyle Morton
|
||||
9 Legend Tang
|
||||
9 Matthew Shao
|
||||
9 Rouli
|
||||
8 Chandler Abraham
|
||||
8 Jason A. Novak
|
||||
8 Rouli
|
||||
7 Alexis Hildebrandt
|
||||
7 Brad Peabody
|
||||
7 Matthias Urlichs
|
||||
5 Choongwoo Han
|
||||
5 Sam Cleveland
|
||||
6 Pedro Worcel
|
||||
5 Tomaz Muraus
|
||||
5 elitest
|
||||
5 iroiro123
|
||||
5 Matthias Urlichs
|
||||
4 root
|
||||
4 Bryan Bishop
|
||||
4 Marc Liyanage
|
||||
4 Michael J. Bazzinotti
|
||||
4 Valtteri Virtanen
|
||||
4 Wade 524
|
||||
4 Youhei Sakurai
|
||||
4 root
|
||||
3 Benjamin Lee
|
||||
3 Chris Neasbitt
|
||||
3 Eli Shvartsman
|
||||
3 Felix Yan
|
||||
3 Guillem Anguera
|
||||
3 Kyle Manna
|
||||
3 MatthewShao
|
||||
3 Ryan Welton
|
||||
3 Zack B
|
||||
2 Anant
|
||||
2 Bennett Blodinger
|
||||
2 Colin Bendell
|
||||
2 Heikki Hannikainen
|
||||
2 Israel Nir
|
||||
2 Jaime Soriano Pastor
|
||||
2 Jim Lloyd
|
||||
2 Krzysztof Bielicki
|
||||
2 Mark E. Haase
|
||||
2 Michael Frister
|
||||
2 Nick Badger
|
||||
2 Niko Kommenda
|
||||
2 Paul
|
||||
2 Rob Wills
|
||||
2 Sean Coates
|
||||
2 Terry Long
|
||||
2 Wade Catron
|
||||
3 Chris Neasbitt
|
||||
2 alts
|
||||
2 isra17
|
||||
2 Heikki Hannikainen
|
||||
2 Jim Lloyd
|
||||
2 Michael Frister
|
||||
2 Rob Wills
|
||||
2 Jaime Soriano Pastor
|
||||
2 israel
|
||||
2 requires.io
|
||||
1 Andrey Plotnikov
|
||||
1 Andy Smith
|
||||
1 Ben Lerner
|
||||
1 Bradley Baetz
|
||||
1 Chris Hamant
|
||||
1 Dan Wilbraham
|
||||
1 David Dworken
|
||||
1 David Shaw
|
||||
1 Doug Lethin
|
||||
1 Eric Entzel
|
||||
1 Felix Wolfsteller
|
||||
1 FreeArtMan
|
||||
1 Gabriel Kirkpatrick
|
||||
1 Henrik Nordström
|
||||
1 Ivaylo Popov
|
||||
1 JC
|
||||
1 Jakub Nawalaniec
|
||||
1 Jakub Wilk
|
||||
1 James Billingham
|
||||
1 Jean Regisser
|
||||
1 Jorge Villacorta
|
||||
1 Kit Randel
|
||||
1 Lucas Cimon
|
||||
1 M. Utku Altinkaya
|
||||
1 Mathieu Mitchell
|
||||
1 Michael Bisbjerg
|
||||
1 Mike C
|
||||
1 Mikhail Korobov
|
||||
1 Morton Fox
|
||||
1 Nick HS
|
||||
1 Nick Raptis
|
||||
1 Nicolas Esteves
|
||||
1 Oleksandr Sheremet
|
||||
1 Pritam Baral
|
||||
2 Mark E. Haase
|
||||
1 Paul
|
||||
1 Rich Somerfield
|
||||
1 Rory McCann
|
||||
1 Felix Wolfsteller
|
||||
1 Rune Halvorsen
|
||||
1 Ryo Onodera
|
||||
1 Sahn Lam
|
||||
1 Seppo Yli-Olli
|
||||
1 Sergey Chipiga
|
||||
1 Stefan Wärting
|
||||
1 Steve Phillips
|
||||
1 Steven Van Acker
|
||||
1 Suyash
|
||||
1 Tarashish Mishra
|
||||
1 TearsDontFalls
|
||||
1 Tim Becker
|
||||
1 Timothy Elliott
|
||||
1 Eric Entzel
|
||||
1 Dan Wilbraham
|
||||
1 Ulrich Petri
|
||||
1 Vyacheslav Bakhmutov
|
||||
1 Will Coster
|
||||
1 Andy Smith
|
||||
1 Yuangxuan Wang
|
||||
1 capt8bit
|
||||
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 vzvu3k6k
|
||||
1 依云
|
||||
1 Mathieu Mitchell
|
||||
1 Ivaylo Popov
|
||||
1 Henrik Nordström
|
||||
1 Michael Bisbjerg
|
||||
1 Nicolas Esteves
|
||||
1 Oleksandr Sheremet
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
FROM mitmproxy/base:latest-onbuild
|
||||
EXPOSE 8080
|
||||
EXPOSE 8081
|
||||
VOLUME /certs
|
||||
15
MANIFEST.in
@@ -1,4 +1,11 @@
|
||||
graft mitmproxy
|
||||
graft pathod
|
||||
graft netlib
|
||||
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.
|
||||
|
||||
147
README.rst
@@ -1,147 +0,0 @@
|
||||
mitmproxy
|
||||
^^^^^^^^^
|
||||
|
||||
|travis| |coveralls| |downloads| |latest_release| |python_versions|
|
||||
|
||||
This repository contains the **mitmproxy** and **pathod** projects, as well as their shared networking library, **netlib**.
|
||||
|
||||
``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
|
||||
--------------------
|
||||
|
||||
Documentation, tutorials and precompiled binaries can be found on the mitmproxy and pathod websites.
|
||||
|
||||
|mitmproxy_site| |pathod_site|
|
||||
|
||||
The latest documentation for mitmproxy is also available on ReadTheDocs.
|
||||
|
||||
|mitmproxy_docs|
|
||||
|
||||
You can join our developer chat on Slack.
|
||||
|
||||
|slack|
|
||||
|
||||
|
||||
Hacking
|
||||
-------
|
||||
|
||||
To get started hacking on mitmproxy, make sure you have Python_ 2.7.x. with
|
||||
virtualenv_ installed (you can find installation instructions for virtualenv here_).
|
||||
Then do the following:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
git clone https://github.com/mitmproxy/mitmproxy.git
|
||||
cd mitmproxy
|
||||
./dev
|
||||
|
||||
|
||||
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, netlib 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.bat 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.
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
||||
.. |mitmproxy_site| image:: https://shields.mitmproxy.org/api/https%3A%2F%2F-mitmproxy.org-blue.svg
|
||||
:target: https://mitmproxy.org/
|
||||
:alt: mitmproxy.org
|
||||
|
||||
.. |pathod_site| image:: https://shields.mitmproxy.org/api/https%3A%2F%2F-pathod.net-blue.svg
|
||||
:target: https://pathod.net/
|
||||
:alt: pathod.net
|
||||
|
||||
.. |mitmproxy_docs| image:: https://readthedocs.org/projects/mitmproxy/badge/
|
||||
:target: http://docs.mitmproxy.org/en/latest/
|
||||
:alt: mitmproxy documentation
|
||||
|
||||
.. |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
|
||||
:target: https://travis-ci.org/mitmproxy/mitmproxy
|
||||
:alt: Build Status
|
||||
|
||||
.. |coveralls| image:: https://shields.mitmproxy.org/coveralls/mitmproxy/mitmproxy/master.svg
|
||||
:target: https://coveralls.io/r/mitmproxy/mitmproxy
|
||||
:alt: Coverage Status
|
||||
|
||||
.. |downloads| image:: https://shields.mitmproxy.org/pypi/dm/mitmproxy.svg?color=orange
|
||||
:target: https://pypi.python.org/pypi/mitmproxy
|
||||
:alt: Downloads
|
||||
|
||||
.. |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/
|
||||
.. _here: http://virtualenv.readthedocs.org/en/latest/installation.html
|
||||
.. _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
|
||||
.. _issue_tracker: https://github.com/mitmproxy/mitmproxy/issues
|
||||
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
|
||||
14
dev.bat
@@ -1,14 +0,0 @@
|
||||
@echo off
|
||||
set VENV=.\venv
|
||||
|
||||
virtualenv %VENV% --always-copy
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
call %VENV%\Scripts\activate.bat
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
pip install -r requirements.txt
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
echo.
|
||||
echo * Created virtualenv environment in %VENV%.
|
||||
echo * Installed all dependencies into the virtualenv.
|
||||
echo * Activated virtualenv environment.
|
||||
13
dev.sh
@@ -1,13 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
VENV=./venv
|
||||
|
||||
python -m virtualenv $VENV --always-copy
|
||||
. $VENV/bin/activate
|
||||
pip install -U pip setuptools
|
||||
pip install -r requirements.txt
|
||||
|
||||
echo ""
|
||||
echo "* Created virtualenv environment in $VENV."
|
||||
echo "* Installed all dependencies into the virtualenv."
|
||||
echo "* You can now activate the virtualenv: \`. $VENV/bin/activate\`"
|
||||
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>
|
||||
|
||||
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 :option:`-c path`
|
||||
mitmproxy shortcut :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,39 +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.filt.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 :option:`--replace` and :option:`--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 :option:`--replace`,
|
||||
:option:`--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 :option:`--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 :option:`--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 :option:`-S path`
|
||||
mitmproxy shortcut :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 :option:`--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")!@)
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
.. _transparent:
|
||||
|
||||
Transparent Proxying
|
||||
====================
|
||||
|
||||
When a transparent proxy is used, traffic is redirected into a proxy at the
|
||||
network layer, without any client configuration being required. This makes
|
||||
@@ -11,14 +7,13 @@ 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_ on Linux
|
||||
or pf_ 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.
|
||||
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.
|
||||
|
||||
.. _iptables: http://www.netfilter.org/
|
||||
.. _pf: https://en.wikipedia.org/wiki/PF_\(firewall\)
|
||||
|
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"),
|
||||
]
|
||||