aboutsummaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/README1
-rw-r--r--examples/dns_spoofing.py35
-rw-r--r--examples/stream_modify.py22
3 files changed, 58 insertions, 0 deletions
diff --git a/examples/README b/examples/README
index 85ab272a..f24c4de7 100644
--- a/examples/README
+++ b/examples/README
@@ -1,6 +1,7 @@
# inline script examples
add_header.py Simple script that just adds a header to every request.
change_upstream_proxy.py Dynamically change the upstream proxy
+dns_spoofing.py Use mitmproxy in a DNS spoofing scenario.
dup_and_replay.py Duplicates each request, changes it, and then replays the modified request.
iframe_injector.py Inject configurable iframe into pages.
modify_form.py Modify all form submissions to add a parameter.
diff --git a/examples/dns_spoofing.py b/examples/dns_spoofing.py
new file mode 100644
index 00000000..cfba7c54
--- /dev/null
+++ b/examples/dns_spoofing.py
@@ -0,0 +1,35 @@
+"""
+This inline scripts makes it possible to use mitmproxy in scenarios where IP spoofing has been used to redirect
+connections to mitmproxy. The way this works is that we rely on either the TLS Server Name Indication (SNI) or the
+Host header of the HTTP request.
+Of course, this is not foolproof - if an HTTPS connection comes without SNI, we don't
+know the actual target and cannot construct a certificate that looks valid.
+Similarly, if there's no Host header or a spoofed Host header, we're out of luck as well.
+Using transparent mode is the better option most of the time.
+
+Usage:
+ mitmproxy
+ -p 80
+ -R http://example.com/ // Used as the target location if no Host header is present
+ mitmproxy
+ -p 443
+ -R https://example.com/ // Used as the target locaction if neither SNI nor host header are present.
+
+mitmproxy will always connect to the default location first, so it must be reachable.
+As a workaround, you can spawn an arbitrary HTTP server and use that for both endpoints, e.g.
+mitmproxy -p 80 -R http://localhost:8000
+mitmproxy -p 443 -R https2http://localhost:8000
+"""
+
+
+def request(context, flow):
+ if flow.client_conn.ssl_established:
+ # TLS SNI or Host header
+ flow.request.host = flow.client_conn.connection.get_servername() or flow.request.pretty_host(hostheader=True)
+
+ # If you use a https2http location as default destination, these attributes need to be corrected as well:
+ flow.request.port = 443
+ flow.request.scheme = "https"
+ else:
+ # Host header
+ flow.request.host = flow.request.pretty_host(hostheader=True) \ No newline at end of file
diff --git a/examples/stream_modify.py b/examples/stream_modify.py
new file mode 100644
index 00000000..56d26e6d
--- /dev/null
+++ b/examples/stream_modify.py
@@ -0,0 +1,22 @@
+"""
+This inline script modifies a streamed response.
+If you do not need streaming, see the modify_response_body example.
+Be aware that content replacement isn't trivial:
+ - If the transfer encoding isn't chunked, you cannot simply change the content length.
+ - If you want to replace all occurences of "foobar", make sure to catch the cases
+ where one chunk ends with [...]foo" and the next starts with "bar[...].
+"""
+
+
+def modify(chunks):
+ """
+ chunks is a generator that can be used to iterate over all chunks.
+ Each chunk is a (prefix, content, suffix) tuple.
+ For example, in the case of chunked transfer encoding: ("3\r\n","foo","\r\n")
+ """
+ for prefix, content, suffix in chunks:
+ yield prefix, content.replace("foo", "bar"), suffix
+
+
+def responseheaders(context, flow):
+ flow.response.stream = modify \ No newline at end of file