mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-22 15:37:45 +00:00
remove context from all scripts
This commit is contained in:
parent
7a5b21556b
commit
c048ae1d5b
@ -1,2 +1,2 @@
|
||||
def response(context, flow):
|
||||
def response(flow):
|
||||
flow.response.headers["newheader"] = "foo"
|
||||
|
@ -14,7 +14,7 @@ def proxy_address(flow):
|
||||
return ("localhost", 8081)
|
||||
|
||||
|
||||
def request(context, flow):
|
||||
def request(flow):
|
||||
if flow.request.method == "CONNECT":
|
||||
# If the decision is done by domain, one could also modify the server address here.
|
||||
# We do it after CONNECT here to have the request data available as well.
|
||||
|
@ -62,9 +62,9 @@ class ViewPigLatin(contentviews.View):
|
||||
pig_view = ViewPigLatin()
|
||||
|
||||
|
||||
def start(context):
|
||||
context.add_contentview(pig_view)
|
||||
def start():
|
||||
contentviews.add(pig_view)
|
||||
|
||||
|
||||
def done(context):
|
||||
context.remove_contentview(pig_view)
|
||||
def done():
|
||||
contentviews.remove(pig_view)
|
||||
|
@ -28,7 +28,7 @@ import re
|
||||
parse_host_header = re.compile(r"^(?P<host>[^:]+|\[.+\])(?::(?P<port>\d+))?$")
|
||||
|
||||
|
||||
def request(context, flow):
|
||||
def request(flow):
|
||||
if flow.client_conn.ssl_established:
|
||||
flow.request.scheme = "https"
|
||||
sni = flow.client_conn.connection.get_servername()
|
||||
|
@ -1,4 +1,7 @@
|
||||
def request(context, flow):
|
||||
f = context.duplicate_flow(flow)
|
||||
from mitmproxy import master
|
||||
|
||||
|
||||
def request(flow):
|
||||
f = master.duplicate_flow(flow)
|
||||
f.request.path = "/changed"
|
||||
context.replay_request(f)
|
||||
master.replay_request(f, block=True, run_scripthooks=False)
|
||||
|
@ -1,3 +1,3 @@
|
||||
def response(context, flow):
|
||||
def response(flow):
|
||||
flow.response.status_code = 500
|
||||
flow.response.content = b""
|
||||
|
@ -3,14 +3,16 @@
|
||||
import sys
|
||||
from mitmproxy import filt
|
||||
|
||||
state = {}
|
||||
|
||||
def start(context):
|
||||
|
||||
def start():
|
||||
if len(sys.argv) != 2:
|
||||
raise ValueError("Usage: -s 'filt.py FILTER'")
|
||||
context.filter = filt.parse(sys.argv[1])
|
||||
state["filter"] = filt.parse(sys.argv[1])
|
||||
|
||||
|
||||
def response(context, flow):
|
||||
if flow.match(context.filter):
|
||||
def response(flow):
|
||||
if flow.match(state["filter"]):
|
||||
print("Flow matches filter:")
|
||||
print(flow)
|
||||
|
@ -3,8 +3,10 @@ import sys
|
||||
|
||||
from mitmproxy.flow import FlowWriter
|
||||
|
||||
state = {}
|
||||
|
||||
def start(context):
|
||||
|
||||
def start():
|
||||
if len(sys.argv) != 2:
|
||||
raise ValueError('Usage: -s "flowriter.py filename"')
|
||||
|
||||
@ -12,9 +14,9 @@ def start(context):
|
||||
f = sys.stdout
|
||||
else:
|
||||
f = open(sys.argv[1], "wb")
|
||||
context.flow_writer = FlowWriter(f)
|
||||
state["flow_writer"] = FlowWriter(f)
|
||||
|
||||
|
||||
def response(context, flow):
|
||||
def response(flow):
|
||||
if random.choice([True, False]):
|
||||
context.flow_writer.add(flow)
|
||||
state["flow_writer"].add(flow)
|
||||
|
@ -54,7 +54,13 @@ class _HARLog(HAR.log):
|
||||
return self.__page_list__
|
||||
|
||||
|
||||
def start(context):
|
||||
class Context(object):
|
||||
pass
|
||||
|
||||
context = Context()
|
||||
|
||||
|
||||
def start():
|
||||
"""
|
||||
On start we create a HARLog instance. You will have to adapt this to
|
||||
suit your actual needs of HAR generation. As it will probably be
|
||||
@ -79,7 +85,7 @@ def start(context):
|
||||
context.seen_server = set()
|
||||
|
||||
|
||||
def response(context, flow):
|
||||
def response(flow):
|
||||
"""
|
||||
Called when a server response has been received. At the time of this
|
||||
message both a request and a response are present and completely done.
|
||||
@ -201,7 +207,7 @@ def response(context, flow):
|
||||
context.HARLog.add(entry)
|
||||
|
||||
|
||||
def done(context):
|
||||
def done():
|
||||
"""
|
||||
Called once on script shutdown, after any other events.
|
||||
"""
|
||||
|
@ -4,25 +4,27 @@ import sys
|
||||
from bs4 import BeautifulSoup
|
||||
from mitmproxy.models import decoded
|
||||
|
||||
iframe_url = None
|
||||
|
||||
def start(context):
|
||||
|
||||
def start():
|
||||
if len(sys.argv) != 2:
|
||||
raise ValueError('Usage: -s "iframe_injector.py url"')
|
||||
context.iframe_url = sys.argv[1]
|
||||
global iframe_url
|
||||
iframe_url = sys.argv[1]
|
||||
|
||||
|
||||
def response(context, flow):
|
||||
if flow.request.host in context.iframe_url:
|
||||
def response(flow):
|
||||
if flow.request.host in iframe_url:
|
||||
return
|
||||
with decoded(flow.response): # Remove content encoding (gzip, ...)
|
||||
html = BeautifulSoup(flow.response.content, "lxml")
|
||||
if html.body:
|
||||
iframe = html.new_tag(
|
||||
"iframe",
|
||||
src=context.iframe_url,
|
||||
src=iframe_url,
|
||||
frameborder=0,
|
||||
height=0,
|
||||
width=0)
|
||||
html.body.insert(0, iframe)
|
||||
flow.response.content = str(html).encode("utf8")
|
||||
context.log("Iframe inserted.")
|
||||
|
@ -1,4 +1,4 @@
|
||||
def request(context, flow):
|
||||
def request(flow):
|
||||
if flow.request.urlencoded_form:
|
||||
flow.request.urlencoded_form["mitmproxy"] = "rocks"
|
||||
else:
|
||||
|
@ -1,2 +1,2 @@
|
||||
def request(context, flow):
|
||||
def request(flow):
|
||||
flow.request.query["mitmproxy"] = "rocks"
|
||||
|
@ -5,16 +5,20 @@ import sys
|
||||
from mitmproxy.models import decoded
|
||||
|
||||
|
||||
def start(context):
|
||||
state = {}
|
||||
|
||||
|
||||
def start():
|
||||
if len(sys.argv) != 3:
|
||||
raise ValueError('Usage: -s "modify_response_body.py old new"')
|
||||
# You may want to use Python's argparse for more sophisticated argument
|
||||
# parsing.
|
||||
context.old, context.new = sys.argv[1].encode(), sys.argv[2].encode()
|
||||
state["old"], state["new"] = sys.argv[1].encode(), sys.argv[2].encode()
|
||||
|
||||
|
||||
def response(context, flow):
|
||||
def response(flow):
|
||||
with decoded(flow.response): # automatically decode gzipped responses.
|
||||
flow.response.content = flow.response.content.replace(
|
||||
context.old,
|
||||
context.new)
|
||||
state["old"],
|
||||
state["new"]
|
||||
)
|
||||
|
@ -1,9 +1,10 @@
|
||||
import time
|
||||
import mitmproxy
|
||||
from mitmproxy.script import concurrent
|
||||
|
||||
|
||||
@concurrent # Remove this and see what happens
|
||||
def request(context, flow):
|
||||
context.log("handle request: %s%s" % (flow.request.host, flow.request.path))
|
||||
def request(flow):
|
||||
mitmproxy.log("handle request: %s%s" % (flow.request.host, flow.request.path))
|
||||
time.sleep(5)
|
||||
context.log("start request: %s%s" % (flow.request.host, flow.request.path))
|
||||
mitmproxy.log("start request: %s%s" % (flow.request.host, flow.request.path))
|
||||
|
@ -4,6 +4,7 @@ instance, we're using the Flask framework (http://flask.pocoo.org/) to expose
|
||||
a single simplest-possible page.
|
||||
"""
|
||||
from flask import Flask
|
||||
import mitmproxy
|
||||
|
||||
app = Flask("proxapp")
|
||||
|
||||
@ -15,10 +16,10 @@ def hello_world():
|
||||
|
||||
# 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.
|
||||
def start(context):
|
||||
context.app_registry.add(app, "proxapp", 80)
|
||||
def start():
|
||||
mitmproxy.master.apps.add(app, "proxapp", 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)
|
||||
# but won't send any data.
|
||||
context.app_registry.add(app, "example.com", 443)
|
||||
mitmproxy.master.apps.add(app, "example.com", 443)
|
||||
|
@ -5,7 +5,7 @@ from mitmproxy.models import HTTPResponse
|
||||
from netlib.http import Headers
|
||||
|
||||
|
||||
def request(context, flow):
|
||||
def request(flow):
|
||||
# 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.
|
||||
|
@ -2,23 +2,21 @@ from netlib.http import decoded
|
||||
import re
|
||||
from six.moves import urllib
|
||||
|
||||
|
||||
def start(context):
|
||||
# set of SSL/TLS capable hosts
|
||||
context.secure_hosts = set()
|
||||
# set of SSL/TLS capable hosts
|
||||
secure_hosts = set()
|
||||
|
||||
|
||||
def request(context, flow):
|
||||
def request(flow):
|
||||
flow.request.headers.pop('If-Modified-Since', None)
|
||||
flow.request.headers.pop('Cache-Control', None)
|
||||
|
||||
# proxy connections to SSL-enabled hosts
|
||||
if flow.request.pretty_host in context.secure_hosts:
|
||||
if flow.request.pretty_host in secure_hosts:
|
||||
flow.request.scheme = 'https'
|
||||
flow.request.port = 443
|
||||
|
||||
|
||||
def response(context, flow):
|
||||
def response(flow):
|
||||
with decoded(flow.response):
|
||||
flow.request.headers.pop('Strict-Transport-Security', None)
|
||||
flow.request.headers.pop('Public-Key-Pins', None)
|
||||
@ -31,7 +29,7 @@ def response(context, flow):
|
||||
location = flow.response.headers['Location']
|
||||
hostname = urllib.parse.urlparse(location).hostname
|
||||
if hostname:
|
||||
context.secure_hosts.add(hostname)
|
||||
secure_hosts.add(hostname)
|
||||
flow.response.headers['Location'] = location.replace('https://', 'http://', 1)
|
||||
|
||||
# strip secure flag from 'Set-Cookie' headers
|
||||
|
@ -1,4 +1,4 @@
|
||||
def responseheaders(context, flow):
|
||||
def responseheaders(flow):
|
||||
"""
|
||||
Enables streaming for all responses.
|
||||
"""
|
||||
|
@ -16,5 +16,5 @@ def modify(chunks):
|
||||
yield chunk.replace("foo", "bar")
|
||||
|
||||
|
||||
def responseheaders(context, flow):
|
||||
def responseheaders(flow):
|
||||
flow.response.stream = modify
|
||||
|
@ -1,79 +1,80 @@
|
||||
import mitmproxy
|
||||
"""
|
||||
This is a script stub, with definitions for all events.
|
||||
"""
|
||||
|
||||
|
||||
def start(context):
|
||||
def start():
|
||||
"""
|
||||
Called once on script startup, before any other events.
|
||||
"""
|
||||
context.log("start")
|
||||
mitmproxy.log("start")
|
||||
|
||||
|
||||
def clientconnect(context, root_layer):
|
||||
def clientconnect(root_layer):
|
||||
"""
|
||||
Called when a client initiates a connection to the proxy. Note that a
|
||||
connection can correspond to multiple HTTP requests
|
||||
"""
|
||||
context.log("clientconnect")
|
||||
mitmproxy.log("clientconnect")
|
||||
|
||||
|
||||
def request(context, flow):
|
||||
def request(flow):
|
||||
"""
|
||||
Called when a client request has been received.
|
||||
"""
|
||||
context.log("request")
|
||||
mitmproxy.log("request")
|
||||
|
||||
|
||||
def serverconnect(context, server_conn):
|
||||
def serverconnect(server_conn):
|
||||
"""
|
||||
Called when the proxy initiates a connection to the target server. Note that a
|
||||
connection can correspond to multiple HTTP requests
|
||||
"""
|
||||
context.log("serverconnect")
|
||||
mitmproxy.log("serverconnect")
|
||||
|
||||
|
||||
def responseheaders(context, flow):
|
||||
def responseheaders(flow):
|
||||
"""
|
||||
Called when the response headers for a server response have been received,
|
||||
but the response body has not been processed yet. Can be used to tell mitmproxy
|
||||
to stream the response.
|
||||
"""
|
||||
context.log("responseheaders")
|
||||
mitmproxy.log("responseheaders")
|
||||
|
||||
|
||||
def response(context, flow):
|
||||
def response(flow):
|
||||
"""
|
||||
Called when a server response has been received.
|
||||
"""
|
||||
context.log("response")
|
||||
mitmproxy.log("response")
|
||||
|
||||
|
||||
def error(context, flow):
|
||||
def error(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.
|
||||
"""
|
||||
context.log("error")
|
||||
mitmproxy.log("error")
|
||||
|
||||
|
||||
def serverdisconnect(context, server_conn):
|
||||
def serverdisconnect(server_conn):
|
||||
"""
|
||||
Called when the proxy closes the connection to the target server.
|
||||
"""
|
||||
context.log("serverdisconnect")
|
||||
mitmproxy.log("serverdisconnect")
|
||||
|
||||
|
||||
def clientdisconnect(context, root_layer):
|
||||
def clientdisconnect(root_layer):
|
||||
"""
|
||||
Called when a client disconnects from the proxy.
|
||||
"""
|
||||
context.log("clientdisconnect")
|
||||
mitmproxy.log("clientdisconnect")
|
||||
|
||||
|
||||
def done(context):
|
||||
def done():
|
||||
"""
|
||||
Called once on script shutdown, after any other events.
|
||||
"""
|
||||
context.log("done")
|
||||
mitmproxy.log("done")
|
||||
|
@ -11,7 +11,7 @@ mitmdump -T --host --tcp ".*" -q -s examples/tcp_message.py
|
||||
from netlib import strutils
|
||||
|
||||
|
||||
def tcp_message(ctx, tcp_msg):
|
||||
def tcp_message(tcp_msg):
|
||||
modified_msg = tcp_msg.message.replace("foo", "bar")
|
||||
|
||||
is_modified = False if modified_msg == tcp_msg.message else True
|
||||
|
@ -20,13 +20,14 @@ Example:
|
||||
|
||||
Authors: Maximilian Hils, Matthew Tuusberg
|
||||
"""
|
||||
from __future__ import (absolute_import, print_function, division)
|
||||
from __future__ import absolute_import, print_function, division
|
||||
import collections
|
||||
import random
|
||||
|
||||
import sys
|
||||
from enum import Enum
|
||||
|
||||
import mitmproxy
|
||||
from mitmproxy.exceptions import TlsProtocolException
|
||||
from mitmproxy.protocol import TlsLayer, RawTCPLayer
|
||||
|
||||
@ -97,7 +98,6 @@ class TlsFeedback(TlsLayer):
|
||||
|
||||
def _establish_tls_with_client(self):
|
||||
server_address = self.server_conn.address
|
||||
tls_strategy = self.script_context.tls_strategy
|
||||
|
||||
try:
|
||||
super(TlsFeedback, self)._establish_tls_with_client()
|
||||
@ -110,15 +110,18 @@ class TlsFeedback(TlsLayer):
|
||||
|
||||
# inline script hooks below.
|
||||
|
||||
tls_strategy = None
|
||||
|
||||
def start(context):
|
||||
|
||||
def start():
|
||||
global tls_strategy
|
||||
if len(sys.argv) == 2:
|
||||
context.tls_strategy = ProbabilisticStrategy(float(sys.argv[1]))
|
||||
tls_strategy = ProbabilisticStrategy(float(sys.argv[1]))
|
||||
else:
|
||||
context.tls_strategy = ConservativeStrategy()
|
||||
tls_strategy = ConservativeStrategy()
|
||||
|
||||
|
||||
def next_layer(context, next_layer):
|
||||
def next_layer(next_layer):
|
||||
"""
|
||||
This hook does the actual magic - if the next layer is planned to be a TLS layer,
|
||||
we check if we want to enter pass-through mode instead.
|
||||
@ -126,14 +129,13 @@ def next_layer(context, next_layer):
|
||||
if isinstance(next_layer, TlsLayer) and next_layer._client_tls:
|
||||
server_address = next_layer.server_conn.address
|
||||
|
||||
if context.tls_strategy.should_intercept(server_address):
|
||||
if tls_strategy.should_intercept(server_address):
|
||||
# We try to intercept.
|
||||
# Monkey-Patch the layer to get feedback from the TLSLayer if interception worked.
|
||||
next_layer.__class__ = TlsFeedback
|
||||
next_layer.script_context = context
|
||||
else:
|
||||
# We don't intercept - reply with a pass-through layer and add a "skipped" entry.
|
||||
context.log("TLS passthrough for %s" % repr(next_layer.server_conn.address), "info")
|
||||
next_layer_replacement = RawTCPLayer(next_layer.ctx, logging=False)
|
||||
mitmproxy.log("TLS passthrough for %s" % repr(next_layer.server_conn.address), "info")
|
||||
next_layer_replacement = RawTCPLayer(next_layer.ctx, ignore=True)
|
||||
next_layer.reply.send(next_layer_replacement)
|
||||
context.tls_strategy.record_skipped(server_address)
|
||||
tls_strategy.record_skipped(server_address)
|
||||
|
@ -3,7 +3,7 @@ from PIL import Image
|
||||
from mitmproxy.models import decoded
|
||||
|
||||
|
||||
def response(context, flow):
|
||||
def response(flow):
|
||||
if flow.response.headers.get("content-type", "").startswith("image"):
|
||||
with decoded(flow.response): # automatically decode gzipped responses.
|
||||
try:
|
||||
|
@ -5,12 +5,12 @@ from a_helper import parser
|
||||
var = 0
|
||||
|
||||
|
||||
def start(ctx):
|
||||
def start():
|
||||
global var
|
||||
var = parser.parse_args(sys.argv[1:]).var
|
||||
|
||||
|
||||
def here(ctx):
|
||||
def here():
|
||||
global var
|
||||
var += 1
|
||||
return var
|
||||
|
@ -1,36 +1,37 @@
|
||||
import mitmproxy
|
||||
log = []
|
||||
|
||||
|
||||
def clientconnect(ctx, cc):
|
||||
ctx.log("XCLIENTCONNECT")
|
||||
def clientconnect(cc):
|
||||
mitmproxy.log("XCLIENTCONNECT")
|
||||
log.append("clientconnect")
|
||||
|
||||
|
||||
def serverconnect(ctx, cc):
|
||||
ctx.log("XSERVERCONNECT")
|
||||
def serverconnect(cc):
|
||||
mitmproxy.log("XSERVERCONNECT")
|
||||
log.append("serverconnect")
|
||||
|
||||
|
||||
def request(ctx, f):
|
||||
ctx.log("XREQUEST")
|
||||
def request(f):
|
||||
mitmproxy.log("XREQUEST")
|
||||
log.append("request")
|
||||
|
||||
|
||||
def response(ctx, f):
|
||||
ctx.log("XRESPONSE")
|
||||
def response(f):
|
||||
mitmproxy.log("XRESPONSE")
|
||||
log.append("response")
|
||||
|
||||
|
||||
def responseheaders(ctx, f):
|
||||
ctx.log("XRESPONSEHEADERS")
|
||||
def responseheaders(f):
|
||||
mitmproxy.log("XRESPONSEHEADERS")
|
||||
log.append("responseheaders")
|
||||
|
||||
|
||||
def clientdisconnect(ctx, cc):
|
||||
ctx.log("XCLIENTDISCONNECT")
|
||||
def clientdisconnect(cc):
|
||||
mitmproxy.log("XCLIENTDISCONNECT")
|
||||
log.append("clientdisconnect")
|
||||
|
||||
|
||||
def error(ctx, cc):
|
||||
ctx.log("XERROR")
|
||||
def error(cc):
|
||||
mitmproxy.log("XERROR")
|
||||
log.append("error")
|
||||
|
@ -3,5 +3,5 @@ from mitmproxy.script import concurrent
|
||||
|
||||
|
||||
@concurrent
|
||||
def request(context, flow):
|
||||
def request(flow):
|
||||
time.sleep(0.1)
|
||||
|
@ -2,5 +2,5 @@ from mitmproxy.script import concurrent
|
||||
|
||||
|
||||
@concurrent
|
||||
def start(context):
|
||||
def start():
|
||||
pass
|
||||
|
@ -1,4 +1,6 @@
|
||||
import mitmproxy
|
||||
|
||||
def request(ctx, f):
|
||||
f = ctx.duplicate_flow(f)
|
||||
ctx.replay_request(f)
|
||||
|
||||
def request(f):
|
||||
f = mitmproxy.master.duplicate_flow(f)
|
||||
mitmproxy.master.replay_request(f, block=True, run_scripthooks=False)
|
||||
|
@ -1,2 +1,2 @@
|
||||
def request(ctx, r):
|
||||
raise ValueError
|
||||
def request(r):
|
||||
raise ValueError()
|
||||
|
@ -1,3 +1,3 @@
|
||||
|
||||
def start(ctx):
|
||||
def start():
|
||||
raise ValueError()
|
||||
|
@ -3,5 +3,5 @@ def modify(chunks):
|
||||
yield chunk.replace(b"foo", b"bar")
|
||||
|
||||
|
||||
def responseheaders(context, flow):
|
||||
def responseheaders(flow):
|
||||
flow.response.stream = modify
|
||||
|
@ -1,4 +1,4 @@
|
||||
def tcp_message(ctx, flow):
|
||||
def tcp_message(flow):
|
||||
message = flow.messages[-1]
|
||||
if not message.from_client:
|
||||
message.content = message.content.replace(b"foo", b"bar")
|
||||
|
@ -1,2 +1,2 @@
|
||||
def done(ctx):
|
||||
def done():
|
||||
raise RuntimeError()
|
||||
|
Loading…
Reference in New Issue
Block a user