mirror of
https://github.com/zhigang1992/mitmproxy.git
synced 2026-04-08 17:29:52 +08:00
rename examples directory to provide space for GUI scripts
This commit is contained in:
10
scripts/core/README
Normal file
10
scripts/core/README
Normal file
@@ -0,0 +1,10 @@
|
||||
add_header.py Simple script that just adds a header to every request.
|
||||
dup_and_replay.py Duplicates each request, changes it, and then replays the modified request.
|
||||
flowbasic Basic use of mitmproxy as a library.
|
||||
modify_form.py Modify all form submissions to add a parameter.
|
||||
modify_querystring.py Modify all query strings to add a parameters.
|
||||
proxapp How to embed a WSGI app in a mitmproxy server
|
||||
stub.py Script stub with a method definition for every event.
|
||||
stickycookies An example of writing a custom proxy with libmproxy.
|
||||
upsidedownternet.py Rewrites traffic to turn PNGs upside down.
|
||||
mitmproxywrapper.py Bracket mitmproxy run with proxy enable/disable on OS X
|
||||
2
scripts/core/add_header.py
Normal file
2
scripts/core/add_header.py
Normal file
@@ -0,0 +1,2 @@
|
||||
def response(context, flow):
|
||||
flow.response.headers["newheader"] = ["foo"]
|
||||
4
scripts/core/dup_and_replay.py
Normal file
4
scripts/core/dup_and_replay.py
Normal file
@@ -0,0 +1,4 @@
|
||||
def request(ctx, flow):
|
||||
f = ctx.duplicate_flow(flow)
|
||||
f.request.path = "/changed"
|
||||
ctx.replay_request(f)
|
||||
39
scripts/core/flowbasic
Normal file
39
scripts/core/flowbasic
Normal file
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
This example shows how to build a proxy based on mitmproxy's Flow
|
||||
primitives.
|
||||
|
||||
Note that request and response messages are not automatically replied to,
|
||||
so we need to implement handlers to do this.
|
||||
"""
|
||||
import os
|
||||
from libmproxy import proxy, flow
|
||||
|
||||
class MyMaster(flow.FlowMaster):
|
||||
def run(self):
|
||||
try:
|
||||
flow.FlowMaster.run(self)
|
||||
except KeyboardInterrupt:
|
||||
self.shutdown()
|
||||
|
||||
def handle_request(self, r):
|
||||
f = flow.FlowMaster.handle_request(self, r)
|
||||
if f:
|
||||
r.reply()
|
||||
return f
|
||||
|
||||
def handle_response(self, r):
|
||||
f = flow.FlowMaster.handle_response(self, r)
|
||||
if f:
|
||||
r.reply()
|
||||
print f
|
||||
return f
|
||||
|
||||
|
||||
config = proxy.ProxyConfig(
|
||||
cacert = os.path.expanduser("~/.mitmproxy/mitmproxy-ca.pem")
|
||||
)
|
||||
state = flow.State()
|
||||
server = proxy.ProxyServer(config, 8080)
|
||||
m = MyMaster(server, state)
|
||||
m.run()
|
||||
50
scripts/core/iframe_injector
Normal file
50
scripts/core/iframe_injector
Normal file
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
Zap encoding in requests and inject iframe after body tag in html responses.
|
||||
Usage:
|
||||
iframe_injector http://someurl/somefile.html
|
||||
"""
|
||||
from libmproxy import controller, proxy
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
class InjectingMaster(controller.Master):
|
||||
def __init__(self, server, iframe_url):
|
||||
controller.Master.__init__(self, server)
|
||||
self._iframe_url = iframe_url
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
return controller.Master.run(self)
|
||||
except KeyboardInterrupt:
|
||||
self.shutdown()
|
||||
|
||||
def handle_request(self, msg):
|
||||
if 'Accept-Encoding' in msg.headers:
|
||||
msg.headers["Accept-Encoding"] = 'none'
|
||||
msg.reply()
|
||||
|
||||
def handle_response(self, msg):
|
||||
if msg.content:
|
||||
c = msg.replace('<body>', '<body><iframe src="%s" frameborder="0" height="0" width="0"></iframe>' % self._iframe_url)
|
||||
if c > 0:
|
||||
print 'Iframe injected!'
|
||||
msg.reply()
|
||||
|
||||
|
||||
def main(argv):
|
||||
if len(argv) != 2:
|
||||
print "Usage: %s IFRAME_URL" % argv[0]
|
||||
sys.exit(1)
|
||||
iframe_url = argv[1]
|
||||
config = proxy.ProxyConfig(
|
||||
cacert = os.path.expanduser("~/.mitmproxy/mitmproxy-ca.pem")
|
||||
)
|
||||
server = proxy.ProxyServer(config, 8080)
|
||||
print 'Starting proxy...'
|
||||
m = InjectingMaster(server, iframe_url)
|
||||
m.run()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv)
|
||||
89
scripts/core/mitmproxywrapper.py
Normal file
89
scripts/core/mitmproxywrapper.py
Normal file
@@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Helper tool to enable/disable OS X proxy and wrap mitmproxy
|
||||
#
|
||||
# Get usage information with:
|
||||
#
|
||||
# mitmproxywrapper.py -h
|
||||
#
|
||||
|
||||
import subprocess
|
||||
import re
|
||||
import argparse
|
||||
|
||||
class Wrapper(object):
|
||||
|
||||
def __init__(self, port):
|
||||
self.port = port
|
||||
self.primary_service_name = self.find_primary_service_name()
|
||||
|
||||
def run_networksetup_command(self, *arguments):
|
||||
return subprocess.check_output(['sudo', 'networksetup'] + list(arguments))
|
||||
|
||||
def proxy_state_for_service(self, service):
|
||||
state = self.run_networksetup_command('-getwebproxy', service).splitlines()
|
||||
return dict([re.findall(r'([^:]+): (.*)', line)[0] for line in state])
|
||||
|
||||
def enable_proxy_for_service(self, service):
|
||||
print 'Enabling proxy on {}...'.format(service)
|
||||
for subcommand in ['-setwebproxy', '-setsecurewebproxy']:
|
||||
self.run_networksetup_command(subcommand, service, '127.0.0.1', str(self.port))
|
||||
|
||||
def disable_proxy_for_service(self, service):
|
||||
print 'Disabling proxy on {}...'.format(service)
|
||||
for subcommand in ['-setwebproxystate', '-setsecurewebproxystate']:
|
||||
self.run_networksetup_command(subcommand, service, 'Off')
|
||||
|
||||
def interface_name_to_service_name_map(self):
|
||||
order = self.run_networksetup_command('-listnetworkserviceorder')
|
||||
mapping = re.findall(r'\(\d+\)\s(.*)$\n\(.*Device: (.+)\)$', order, re.MULTILINE)
|
||||
return dict([(b, a) for (a, b) in mapping])
|
||||
|
||||
def run_command_with_input(self, command, input):
|
||||
popen = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
||||
(stdout, stderr) = popen.communicate(input)
|
||||
return stdout
|
||||
|
||||
def primary_interace_name(self):
|
||||
scutil_script = 'get State:/Network/Global/IPv4\nd.show\n'
|
||||
stdout = self.run_command_with_input('/usr/sbin/scutil', scutil_script)
|
||||
interface, = re.findall(r'PrimaryInterface\s*:\s*(.+)', stdout)
|
||||
return interface
|
||||
|
||||
def find_primary_service_name(self):
|
||||
return self.interface_name_to_service_name_map()[self.primary_interace_name()]
|
||||
|
||||
def proxy_enabled_for_service(self, service):
|
||||
return self.proxy_state_for_service(service)['Enabled'] == 'Yes'
|
||||
|
||||
def toggle_proxy(self):
|
||||
if self.proxy_enabled_for_service(self.primary_service_name):
|
||||
self.disable_proxy_for_service(self.primary_service_name)
|
||||
else:
|
||||
self.enable_proxy_for_service(self.primary_service_name)
|
||||
|
||||
def wrap_mitmproxy(self):
|
||||
if not self.proxy_enabled_for_service(self.primary_service_name):
|
||||
self.enable_proxy_for_service(self.primary_service_name)
|
||||
|
||||
subprocess.check_call(['mitmproxy', '-p', str(self.port), '--palette', 'light'])
|
||||
|
||||
if self.proxy_enabled_for_service(self.primary_service_name):
|
||||
self.disable_proxy_for_service(self.primary_service_name)
|
||||
|
||||
@classmethod
|
||||
def main(cls):
|
||||
parser = argparse.ArgumentParser(description='Helper tool for OS X proxy configuration and mitmproxy')
|
||||
parser.add_argument('-t', '--toggle', action='store_true', help='just toggle the proxy configuration')
|
||||
parser.add_argument('-p', '--port', type=int, help='override the default port of 8080', default=8080)
|
||||
args = parser.parse_args()
|
||||
|
||||
wrapper = cls(port=args.port)
|
||||
if args.toggle:
|
||||
wrapper.toggle_proxy()
|
||||
else:
|
||||
wrapper.wrap_mitmproxy()
|
||||
|
||||
if __name__ == '__main__':
|
||||
Wrapper.main()
|
||||
|
||||
8
scripts/core/modify_form.py
Normal file
8
scripts/core/modify_form.py
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
def request(context, flow):
|
||||
if "application/x-www-form-urlencoded" in flow.request.headers["content-type"]:
|
||||
frm = flow.request.get_form_urlencoded()
|
||||
frm["mitmproxy"] = ["rocks"]
|
||||
flow.request.set_form_urlencoded(frm)
|
||||
|
||||
|
||||
7
scripts/core/modify_querystring.py
Normal file
7
scripts/core/modify_querystring.py
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
def request(context, flow):
|
||||
q = flow.request.get_query()
|
||||
if q:
|
||||
q["mitmproxy"] = ["rocks"]
|
||||
flow.request.set_query(q)
|
||||
|
||||
47
scripts/core/proxapp
Normal file
47
scripts/core/proxapp
Normal file
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
This example shows how to graft a WSGI app onto mitmproxy. In this
|
||||
instance, we're using the Bottle framework (http://bottlepy.org/) to expose
|
||||
a single simplest-possible page.
|
||||
"""
|
||||
import bottle
|
||||
import os
|
||||
from libmproxy import proxy, flow
|
||||
|
||||
@bottle.route('/')
|
||||
def index():
|
||||
return 'Hi!'
|
||||
|
||||
|
||||
class MyMaster(flow.FlowMaster):
|
||||
def run(self):
|
||||
try:
|
||||
flow.FlowMaster.run(self)
|
||||
except KeyboardInterrupt:
|
||||
self.shutdown()
|
||||
|
||||
def handle_request(self, r):
|
||||
f = flow.FlowMaster.handle_request(self, r)
|
||||
if f:
|
||||
r.reply()
|
||||
return f
|
||||
|
||||
def handle_response(self, r):
|
||||
f = flow.FlowMaster.handle_response(self, r)
|
||||
if f:
|
||||
r.reply()
|
||||
print f
|
||||
return f
|
||||
|
||||
|
||||
config = proxy.ProxyConfig(
|
||||
cacert = os.path.expanduser("~/.mitmproxy/mitmproxy-ca.pem")
|
||||
)
|
||||
state = flow.State()
|
||||
server = proxy.ProxyServer(config, 8080)
|
||||
# Register the app using the magic domain "proxapp" on port 80. Requests to
|
||||
# this domain and port combination will now be routed to the WSGI app instance.
|
||||
server.apps.add(bottle.app(), "proxapp", 80)
|
||||
m = MyMaster(server, state)
|
||||
m.run()
|
||||
|
||||
19
scripts/core/redirect_requests.py
Normal file
19
scripts/core/redirect_requests.py
Normal file
@@ -0,0 +1,19 @@
|
||||
from libmproxy.flow import Response
|
||||
from netlib.odict import ODictCaseless
|
||||
|
||||
"""
|
||||
This example shows two ways to redirect flows to other destinations.
|
||||
"""
|
||||
|
||||
def request(context, flow):
|
||||
if flow.request.host.endswith("example.com"):
|
||||
resp = Response(flow.request,
|
||||
[1,1],
|
||||
200, "OK",
|
||||
ODictCaseless([["Content-Type","text/html"]]),
|
||||
"helloworld",
|
||||
None)
|
||||
flow.request.reply(resp)
|
||||
if flow.request.host.endswith("example.org"):
|
||||
flow.request.host = "mitmproxy.org"
|
||||
flow.request.headers["Host"] = ["mitmproxy.org"]
|
||||
42
scripts/core/stickycookies
Normal file
42
scripts/core/stickycookies
Normal file
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
This example builds on mitmproxy's base proxying infrastructure to
|
||||
implement functionality similar to the "sticky cookies" option. This is at
|
||||
a lower level than the Flow mechanism, so we're dealing directly with
|
||||
request and response objects.
|
||||
"""
|
||||
from libmproxy import controller, proxy
|
||||
import os
|
||||
|
||||
class StickyMaster(controller.Master):
|
||||
def __init__(self, server):
|
||||
controller.Master.__init__(self, server)
|
||||
self.stickyhosts = {}
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
return controller.Master.run(self)
|
||||
except KeyboardInterrupt:
|
||||
self.shutdown()
|
||||
|
||||
def handle_request(self, msg):
|
||||
hid = (msg.host, msg.port)
|
||||
if msg.headers["cookie"]:
|
||||
self.stickyhosts[hid] = msg.headers["cookie"]
|
||||
elif hid in self.stickyhosts:
|
||||
msg.headers["cookie"] = self.stickyhosts[hid]
|
||||
msg.reply()
|
||||
|
||||
def handle_response(self, msg):
|
||||
hid = (msg.request.host, msg.request.port)
|
||||
if msg.headers["set-cookie"]:
|
||||
self.stickyhosts[hid] = msg.headers["set-cookie"]
|
||||
msg.reply()
|
||||
|
||||
|
||||
config = proxy.ProxyConfig(
|
||||
cacert = os.path.expanduser("~/.mitmproxy/mitmproxy-ca.pem")
|
||||
)
|
||||
server = proxy.ProxyServer(config, 8080)
|
||||
m = StickyMaster(server)
|
||||
m.run()
|
||||
47
scripts/core/stub.py
Normal file
47
scripts/core/stub.py
Normal file
@@ -0,0 +1,47 @@
|
||||
"""
|
||||
This is a script stub, with definitions for all events.
|
||||
"""
|
||||
def start(ctx, argv):
|
||||
"""
|
||||
Called once on script startup, before any other events.
|
||||
"""
|
||||
ctx.log("start")
|
||||
|
||||
def clientconnect(ctx, client_connect):
|
||||
"""
|
||||
Called when a client initiates a connection to the proxy. Note that a
|
||||
connection can correspond to multiple HTTP requests
|
||||
"""
|
||||
ctx.log("clientconnect")
|
||||
|
||||
def request(ctx, flow):
|
||||
"""
|
||||
Called when a client request has been received.
|
||||
"""
|
||||
ctx.log("request")
|
||||
|
||||
def response(ctx, flow):
|
||||
"""
|
||||
Called when a server response has been received.
|
||||
"""
|
||||
ctx.log("response")
|
||||
|
||||
def error(ctx, flow):
|
||||
"""
|
||||
Called when a flow error has occured, 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.
|
||||
"""
|
||||
ctx.log("error")
|
||||
|
||||
def clientdisconnect(ctx, client_disconnect):
|
||||
"""
|
||||
Called when a client disconnects from the proxy.
|
||||
"""
|
||||
ctx.log("clientdisconnect")
|
||||
|
||||
def done(ctx):
|
||||
"""
|
||||
Called once on script shutdown, after any other events.
|
||||
"""
|
||||
ctx.log("done")
|
||||
8
scripts/core/upsidedownternet.py
Normal file
8
scripts/core/upsidedownternet.py
Normal file
@@ -0,0 +1,8 @@
|
||||
import Image, cStringIO
|
||||
def response(context, flow):
|
||||
if flow.response.headers["content-type"] == ["image/png"]:
|
||||
s = cStringIO.StringIO(flow.response.content)
|
||||
img = Image.open(s).rotate(180)
|
||||
s2 = cStringIO.StringIO()
|
||||
img.save(s2, "png")
|
||||
flow.response.content = s2.getvalue()
|
||||
Reference in New Issue
Block a user