diff options
Diffstat (limited to 'examples')
-rw-r--r-- | examples/complex/README.md | 2 | ||||
-rw-r--r-- | examples/complex/dns_spoofing.py | 3 | ||||
-rw-r--r-- | examples/complex/har_dump.py | 43 | ||||
-rw-r--r-- | examples/complex/remote_debug.py | 2 | ||||
-rw-r--r-- | examples/complex/tls_passthrough.py | 14 | ||||
-rw-r--r-- | examples/simple/add_header.py | 5 | ||||
-rw-r--r-- | examples/simple/add_header_class.py | 8 | ||||
-rw-r--r-- | examples/simple/custom_contentview.py | 8 | ||||
-rw-r--r-- | examples/simple/custom_option.py | 8 | ||||
-rw-r--r-- | examples/simple/filter_flows.py | 23 | ||||
-rw-r--r-- | examples/simple/io_read_dumpfile.py | 4 | ||||
-rw-r--r-- | examples/simple/io_write_dumpfile.py | 14 | ||||
-rw-r--r-- | examples/simple/log_events.py | 2 | ||||
-rw-r--r-- | examples/simple/modify_body_inject_iframe.py | 39 | ||||
-rw-r--r-- | examples/simple/modify_form.py | 5 | ||||
-rw-r--r-- | examples/simple/modify_querystring.py | 5 | ||||
-rw-r--r-- | examples/simple/redirect_requests.py | 3 | ||||
-rw-r--r-- | examples/simple/script_arguments.py | 17 | ||||
-rw-r--r-- | examples/simple/send_reply_from_proxy.py | 2 | ||||
-rw-r--r-- | examples/simple/upsidedownternet.py | 4 | ||||
-rw-r--r-- | examples/simple/wsgi_flask_app.py | 8 |
21 files changed, 109 insertions, 110 deletions
diff --git a/examples/complex/README.md b/examples/complex/README.md index 452f2395..77dbe2f5 100644 --- a/examples/complex/README.md +++ b/examples/complex/README.md @@ -5,7 +5,6 @@ | 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. | -| flowbasic.py | Basic use of mitmproxy's FlowMaster directly. | | full_transparency_shim.c | Setuid wrapper that can be used to run mitmproxy in full transparency mode, as a normal user. | | har_dump.py | Dump flows as HAR files. | | mitmproxywrapper.py | Bracket mitmproxy run with proxy enable/disable on OS X | @@ -16,3 +15,4 @@ | stream_modify.py | Modify a streamed response body. | | tcp_message.py | Modify a raw TCP connection | | tls_passthrough.py | Use conditional TLS interception based on a user-defined strategy. | +| xss_scanner.py | Scan all visited webpages. | diff --git a/examples/complex/dns_spoofing.py b/examples/complex/dns_spoofing.py index ca2bcd35..632783a7 100644 --- a/examples/complex/dns_spoofing.py +++ b/examples/complex/dns_spoofing.py @@ -54,5 +54,4 @@ class Rerouter: flow.request.port = port -def start(opts): - return Rerouter() +addons = [Rerouter()] diff --git a/examples/complex/har_dump.py b/examples/complex/har_dump.py index 9a86e45e..21bcc341 100644 --- a/examples/complex/har_dump.py +++ b/examples/complex/har_dump.py @@ -4,7 +4,6 @@ This inline script can be used to dump flows as HAR files. import json -import sys import base64 import zlib import os @@ -15,6 +14,7 @@ from datetime import timezone import mitmproxy from mitmproxy import version +from mitmproxy import ctx from mitmproxy.utils import strutils from mitmproxy.net.http import cookies @@ -25,17 +25,13 @@ HAR = {} SERVERS_SEEN = set() -def start(opts): - """ - Called once on script startup before any other events. - """ - if len(sys.argv) != 2: - raise ValueError( - 'Usage: -s "har_dump.py filename" ' - '(- will output to stdout, filenames ending with .zhar ' - 'will result in compressed har)' - ) +def load(l): + l.add_option( + "hardump", str, "", "HAR dump path.", + ) + +def configure(updated): HAR.update({ "log": { "version": "1.2", @@ -156,21 +152,20 @@ def done(): """ Called once on script shutdown, after any other events. """ - dump_file = sys.argv[1] + if ctx.options.hardump: + json_dump = json.dumps(HAR, indent=2) # type: str - json_dump = json.dumps(HAR, indent=2) # type: str - - if dump_file == '-': - mitmproxy.ctx.log(json_dump) - else: - raw = json_dump.encode() # type: bytes - if dump_file.endswith('.zhar'): - raw = zlib.compress(raw, 9) + if ctx.options.hardump == '-': + mitmproxy.ctx.log(json_dump) + else: + raw = json_dump.encode() # type: bytes + if ctx.options.hardump.endswith('.zhar'): + raw = zlib.compress(raw, 9) - with open(os.path.expanduser(dump_file), "wb") as f: - f.write(raw) + with open(os.path.expanduser(ctx.options.hardump), "wb") as f: + f.write(raw) - mitmproxy.ctx.log("HAR dump finished (wrote %s bytes to file)" % len(json_dump)) + mitmproxy.ctx.log("HAR dump finished (wrote %s bytes to file)" % len(json_dump)) def format_cookies(cookie_list): @@ -206,7 +201,7 @@ def format_request_cookies(fields): def format_response_cookies(fields): - return format_cookies((c[0], c[1].value, c[1].attrs) for c in fields) + return format_cookies((c[0], c[1][0], c[1][1]) for c in fields) def name_value(obj): diff --git a/examples/complex/remote_debug.py b/examples/complex/remote_debug.py index ae0dffc1..fa6f3d33 100644 --- a/examples/complex/remote_debug.py +++ b/examples/complex/remote_debug.py @@ -14,6 +14,6 @@ Usage: """ -def start(opts): +def load(l): import pydevd pydevd.settrace("localhost", port=5678, stdoutToServer=True, stderrToServer=True) diff --git a/examples/complex/tls_passthrough.py b/examples/complex/tls_passthrough.py index 6dba7ca1..9bb27d25 100644 --- a/examples/complex/tls_passthrough.py +++ b/examples/complex/tls_passthrough.py @@ -23,10 +23,10 @@ Authors: Maximilian Hils, Matthew Tuusberg import collections import random -import sys from enum import Enum import mitmproxy +from mitmproxy import ctx from mitmproxy.exceptions import TlsProtocolException from mitmproxy.proxy.protocol import TlsLayer, RawTCPLayer @@ -112,10 +112,16 @@ class TlsFeedback(TlsLayer): tls_strategy = None -def start(opts): +def load(l): + l.add_option( + "tlsstrat", int, 0, "TLS passthrough strategy (0-100)", + ) + + +def configure(updated): global tls_strategy - if len(sys.argv) == 2: - tls_strategy = ProbabilisticStrategy(float(sys.argv[1])) + if ctx.options.tlsstrat > 0: + tls_strategy = ProbabilisticStrategy(float(ctx.options.tlsstrat) / 100.0) else: tls_strategy = ConservativeStrategy() diff --git a/examples/simple/add_header.py b/examples/simple/add_header.py index 3e0b5f1e..64fc6267 100644 --- a/examples/simple/add_header.py +++ b/examples/simple/add_header.py @@ -1,2 +1,5 @@ -def response(flow): +from mitmproxy import http + + +def response(flow: http.HTTPFlow) -> None: flow.response.headers["newheader"] = "foo" diff --git a/examples/simple/add_header_class.py b/examples/simple/add_header_class.py index 9270be09..419c99ac 100644 --- a/examples/simple/add_header_class.py +++ b/examples/simple/add_header_class.py @@ -1,7 +1,9 @@ +from mitmproxy import http + + class AddHeader: - def response(self, flow): + def response(self, flow: http.HTTPFlow) -> None: flow.response.headers["newheader"] = "foo" -def start(opts): - return AddHeader() +addons = [AddHeader()] diff --git a/examples/simple/custom_contentview.py b/examples/simple/custom_contentview.py index 4bc17af0..71f92575 100644 --- a/examples/simple/custom_contentview.py +++ b/examples/simple/custom_contentview.py @@ -3,6 +3,10 @@ This example shows how one can add a custom contentview to mitmproxy. The content view API is explained in the mitmproxy.contentviews module. """ from mitmproxy import contentviews +import typing + + +CVIEWSWAPCASE = typing.Tuple[str, typing.Iterable[typing.List[typing.Tuple[str, typing.AnyStr]]]] class ViewSwapCase(contentviews.View): @@ -13,14 +17,14 @@ class ViewSwapCase(contentviews.View): prompt = ("swap case text", "z") content_types = ["text/plain"] - def __call__(self, data: bytes, **metadata): + def __call__(self, data: typing.AnyStr, **metadata) -> CVIEWSWAPCASE: return "case-swapped text", contentviews.format_text(data.swapcase()) view = ViewSwapCase() -def start(opts): +def load(l): contentviews.add(view) diff --git a/examples/simple/custom_option.py b/examples/simple/custom_option.py index 324d27e7..5b6070dd 100644 --- a/examples/simple/custom_option.py +++ b/examples/simple/custom_option.py @@ -1,11 +1,11 @@ from mitmproxy import ctx -def start(options): +def load(l): ctx.log.info("Registering option 'custom'") - options.add_option("custom", bool, False, "A custom option") + l.add_option("custom", bool, False, "A custom option") -def configure(options, updated): +def configure(updated): if "custom" in updated: - ctx.log.info("custom option value: %s" % options.custom) + ctx.log.info("custom option value: %s" % ctx.options.custom) diff --git a/examples/simple/filter_flows.py b/examples/simple/filter_flows.py index 24e8b6c1..70979591 100644 --- a/examples/simple/filter_flows.py +++ b/examples/simple/filter_flows.py @@ -1,23 +1,26 @@ """ This scripts demonstrates how to use mitmproxy's filter pattern in scripts. -Usage: - mitmdump -s "flowfilter.py FILTER" """ -import sys from mitmproxy import flowfilter +from mitmproxy import ctx, http class Filter: - def __init__(self, spec): - self.filter = flowfilter.parse(spec) + def __init__(self): + self.filter = None # type: flowfilter.TFilter - def response(self, flow): + def configure(self, updated): + self.filter = flowfilter.parse(ctx.options.flowfilter) + + def load(self, l): + l.add_option( + "flowfilter", str, "", "Check that flow matches filter." + ) + + def response(self, flow: http.HTTPFlow) -> None: if flowfilter.match(self.filter, flow): print("Flow matches filter:") print(flow) -def start(opts): - if len(sys.argv) != 2: - raise ValueError("Usage: -s 'filt.py FILTER'") - return Filter(sys.argv[1]) +addons = [Filter()] diff --git a/examples/simple/io_read_dumpfile.py b/examples/simple/io_read_dumpfile.py index edbbe2dd..ea544cc4 100644 --- a/examples/simple/io_read_dumpfile.py +++ b/examples/simple/io_read_dumpfile.py @@ -1,13 +1,15 @@ #!/usr/bin/env python + +# type: ignore # # Simple script showing how to read a mitmproxy dump file # - from mitmproxy import io from mitmproxy.exceptions import FlowReadException import pprint import sys + with open(sys.argv[1], "rb") as logfile: freader = io.FlowReader(logfile) pp = pprint.PrettyPrinter(indent=4) diff --git a/examples/simple/io_write_dumpfile.py b/examples/simple/io_write_dumpfile.py index 311950af..cf7c4f52 100644 --- a/examples/simple/io_write_dumpfile.py +++ b/examples/simple/io_write_dumpfile.py @@ -7,23 +7,21 @@ to multiple files in parallel. """ import random import sys -from mitmproxy import io +from mitmproxy import io, http +import typing # noqa class Writer: - def __init__(self, path): + def __init__(self, path: str) -> None: if path == "-": - f = sys.stdout + f = sys.stdout # type: typing.IO[typing.Any] else: f = open(path, "wb") self.w = io.FlowWriter(f) - def response(self, flow): + def response(self, flow: http.HTTPFlow) -> None: if random.choice([True, False]): self.w.add(flow) -def start(opts): - if len(sys.argv) != 2: - raise ValueError('Usage: -s "flowriter.py filename"') - return Writer(sys.argv[1]) +addons = [Writer(sys.argv[1])] diff --git a/examples/simple/log_events.py b/examples/simple/log_events.py index a81892aa..581b99f3 100644 --- a/examples/simple/log_events.py +++ b/examples/simple/log_events.py @@ -7,6 +7,6 @@ If you want to help us out: https://github.com/mitmproxy/mitmproxy/issues/1530 : from mitmproxy import ctx -def start(opts): +def load(l): ctx.log.info("This is some informative text.") ctx.log.error("This is an error.") diff --git a/examples/simple/modify_body_inject_iframe.py b/examples/simple/modify_body_inject_iframe.py index ab5abf27..595bd9f2 100644 --- a/examples/simple/modify_body_inject_iframe.py +++ b/examples/simple/modify_body_inject_iframe.py @@ -1,29 +1,26 @@ -# Usage: mitmdump -s "iframe_injector.py url" # (this script works best with --anticache) -import sys from bs4 import BeautifulSoup +from mitmproxy import ctx, http class Injector: - def __init__(self, iframe_url): - self.iframe_url = iframe_url + def load(self, loader): + loader.add_option( + "iframe", str, "", "IFrame to inject" + ) - def response(self, flow): - if flow.request.host in self.iframe_url: - return - html = BeautifulSoup(flow.response.content, "html.parser") - if html.body: - iframe = html.new_tag( - "iframe", - src=self.iframe_url, - frameborder=0, - height=0, - width=0) - html.body.insert(0, iframe) - flow.response.content = str(html).encode("utf8") + def response(self, flow: http.HTTPFlow) -> None: + if ctx.options.iframe: + html = BeautifulSoup(flow.response.content, "html.parser") + if html.body: + iframe = html.new_tag( + "iframe", + src=ctx.options.iframe, + frameborder=0, + height=0, + width=0) + html.body.insert(0, iframe) + flow.response.content = str(html).encode("utf8") -def start(opts): - if len(sys.argv) != 2: - raise ValueError('Usage: -s "iframe_injector.py url"') - return Injector(sys.argv[1]) +addons = [Injector()] diff --git a/examples/simple/modify_form.py b/examples/simple/modify_form.py index b425efb0..8742a976 100644 --- a/examples/simple/modify_form.py +++ b/examples/simple/modify_form.py @@ -1,4 +1,7 @@ -def request(flow): +from mitmproxy import http + + +def request(flow: http.HTTPFlow) -> None: if flow.request.urlencoded_form: # If there's already a form, one can just add items to the dict: flow.request.urlencoded_form["mitmproxy"] = "rocks" diff --git a/examples/simple/modify_querystring.py b/examples/simple/modify_querystring.py index ee8a89ad..12b16fda 100644 --- a/examples/simple/modify_querystring.py +++ b/examples/simple/modify_querystring.py @@ -1,2 +1,5 @@ -def request(flow): +from mitmproxy import http + + +def request(flow: http.HTTPFlow) -> None: flow.request.query["mitmproxy"] = "rocks" diff --git a/examples/simple/redirect_requests.py b/examples/simple/redirect_requests.py index 51876df7..ddb89961 100644 --- a/examples/simple/redirect_requests.py +++ b/examples/simple/redirect_requests.py @@ -1,9 +1,10 @@ """ This example shows two ways to redirect flows to another server. """ +from mitmproxy import http -def request(flow): +def request(flow: http.HTTPFlow) -> None: # pretty_host takes the "Host" header of the request into account, # which is useful in transparent mode where we usually only have the IP # otherwise. diff --git a/examples/simple/script_arguments.py b/examples/simple/script_arguments.py deleted file mode 100644 index b46a1960..00000000 --- a/examples/simple/script_arguments.py +++ /dev/null @@ -1,17 +0,0 @@ -import argparse - - -class Replacer: - def __init__(self, src, dst): - self.src, self.dst = src, dst - - def response(self, flow): - flow.response.replace(self.src, self.dst) - - -def start(opts): - parser = argparse.ArgumentParser() - parser.add_argument("src", type=str) - parser.add_argument("dst", type=str) - args = parser.parse_args() - return Replacer(args.src, args.dst) diff --git a/examples/simple/send_reply_from_proxy.py b/examples/simple/send_reply_from_proxy.py index bef2e7e7..5011fd2e 100644 --- a/examples/simple/send_reply_from_proxy.py +++ b/examples/simple/send_reply_from_proxy.py @@ -5,7 +5,7 @@ without sending any data to the remote server. from mitmproxy import http -def request(flow): +def request(flow: http.HTTPFlow) -> None: # pretty_url takes the "Host" header of the request into account, which # is useful in transparent mode where we usually only have the IP otherwise. diff --git a/examples/simple/upsidedownternet.py b/examples/simple/upsidedownternet.py index 8ba450ab..f150a5c3 100644 --- a/examples/simple/upsidedownternet.py +++ b/examples/simple/upsidedownternet.py @@ -2,11 +2,11 @@ This script rotates all images passing through the proxy by 180 degrees. """ import io - from PIL import Image +from mitmproxy import http -def response(flow): +def response(flow: http.HTTPFlow) -> None: if flow.response.headers.get("content-type", "").startswith("image"): s = io.BytesIO(flow.response.content) img = Image.open(s).rotate(180) diff --git a/examples/simple/wsgi_flask_app.py b/examples/simple/wsgi_flask_app.py index db3b1adf..4be38000 100644 --- a/examples/simple/wsgi_flask_app.py +++ b/examples/simple/wsgi_flask_app.py @@ -10,14 +10,14 @@ app = Flask("proxapp") @app.route('/') -def hello_world(): +def hello_world() -> str: return 'Hello World!' -def start(opts): - # Host app at the magic domain "proxapp" on port 80. Requests to this +def load(l): + # Host app at the magic domain "proxapp.local" on port 80. Requests to this # domain and port combination will now be routed to the WSGI app instance. - return wsgiapp.WSGIApp(app, "proxapp", 80) + return wsgiapp.WSGIApp(app, "proxapp.local", 80) # SSL works too, but the magic domain needs to be resolvable from the mitmproxy machine due to mitmproxy's design. # mitmproxy will connect to said domain and use serve its certificate (unless --no-upstream-cert is set) |