Skip to content

Instantly share code, notes, and snippets.

@digitalist
Last active August 3, 2020 08:12
Show Gist options
  • Select an option

  • Save digitalist/908f55a25db6df2fe2edbce410734778 to your computer and use it in GitHub Desktop.

Select an option

Save digitalist/908f55a25db6df2fe2edbce410734778 to your computer and use it in GitHub Desktop.
Little quick and dirty mitmproxy response rewrite example
# (this script works best with --anticache)
# run it like this: mitmdump -q -s ~/b/mitm/replace.py
from mitmproxy import ctx, http
import re
DPREFIX = '[DEBUG]> ' # stupid
"""
Dict of url regexps with content-type matching and replacement pairs
I would add regexp flags as a third element of replacement list
"""
DEFAULT_REPLACE_PARAMS = {
# break every site if you want
".+": {
"options": {"debug": False}, # will not print found sites
"content_type": "", # care to choose correct content type
"patterns": [
['', ''], # fill in replacement patterns
]
},
# mr. putin is a dickhead on a russian news site
"^https*://(www\.)*gazeta\.ru*": {
"options": {"debug": True},
"content_type": "text/html",
"patterns": [
["Путин", "Хуютин", ],
["видео", "хуидио", ],
]
},
# change js example
".*localhost.*": {
"options": {"debug": True},
"content_type": "application/javascript",
"patterns": [
["/\*@ipoint1\*/", "alert('mitm intercept');", ]
]
}
}
"""
Dict of content-types we don't need in this case: video, image etc.
"""
DEFAULT_SKIP_CONTENT_TYPES = [
'^image'
]
DEFAULT_REPLACE_PARAMS_COMPILED = {} # let's precompile url regexp during startup
for k, v in DEFAULT_REPLACE_PARAMS.items():
compiled = re.compile(k)
DEFAULT_REPLACE_PARAMS_COMPILED[compiled] = v
def get_replacements_by_url(url, content_type: str = None, url_dict: dict = None):
"""
we get an url and return a list of patterns to replace according to url_dict rules
:param url:
:param content_type:
:param url_dict:
:return: list of replacement pairs or empty list if none found
"""
if not url_dict:
url_dict = DEFAULT_REPLACE_PARAMS_COMPILED # this should be faster, since regexps are precompiled
for url_pattern, entry in url_dict.items():
o = entry['options']
c = entry['content_type']
if re.search(url_pattern, url):
if o['debug']:
# do not use print, use mitmproxy logging
print(f'{DPREFIX}found', url, content_type)
pass
if content_type and c and re.search(c, content_type):
# do not use print, use mitmproxy logging
print(f'{DPREFIX}found', url, content_type)
pass
else:
continue # we didn't find correct content-type header,
return entry['patterns']
return []
def content_type_ok(content_type: str):
"""
Check if we need that content type
:param content_type:
:return: bool
"""
for c in DEFAULT_SKIP_CONTENT_TYPES:
if content_type and content_type.startswith(c):
return False
return True
def get_content_type(flow: http.HTTPFlow):
content_type = flow.response.headers[b"content-type"] \
if b"content-type" in flow.response.headers \
else None
return content_type
class Injector:
"""
fairly minimal standard mitmproxy boilerplate
"""
def load(self, loader):
"""
Init something here, take some args
"""
pass
def response(self, flow: http.HTTPFlow) -> None:
content_type = get_content_type(flow)
if content_type_ok(content_type): # omit images/video
patterns = get_replacements_by_url(flow.request.url, content_type)
for pair in patterns:
search, replace = pair
flow.response.text = re.sub(search, replace, flow.response.text)
addons = [Injector()] # init
@alexalwks

Copy link
Copy Markdown

GOD BLESS YOU.
I searched this everywhere 5 hours

@digitalist

Copy link
Copy Markdown
Author

glad I could help :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment