Xepor (pronounced /ˈzɛfə/, zephyr) is a web routing framework for reverse engineers and security researchers. It provides a Flask-like API for hackers to intercept and modify HTTP requests and/or HTTP responses in a human-friendly coding style.
This project is meant to be used with mitmproxy. Users write scripts with xepor
, and run the script inside mitmproxy with mitmproxy -s your-script.py
.
If you want to step from PoC to production, from demo(e.g. http-reply-from-proxy.py, http-trailers.py, http-stream-modify.py) to something you could take out with your WiFi Pineapple, then Xepor is for you!
@api.route()
, just like Flask! Write everything in one script and no if..else
any more.InterceptedAPI
instance.mitmproxy
/ mitmweb
+ regular
/ transparent
/ socks5
/ reverse:SPEC
/ upstream:SPEC
) are fully supported.SSL stripping is NOT provided by this project.
pip install xepor
Take the script from examples/httpbin as an example.
mitmweb -s example/httpbin/httpbin.py
Set your Browser HTTP Proxy to http://127.0.0.1:8080
, and access the web interface at http://127.0.0.1:8081/.
Send a GET request from http://httpbin.org/#/HTTP_Methods/get_get , Then you could see the modification made by Xepor in mitmweb interface, browser dev tools or Wireshark.
The httpbin.py
do two things.
payload=evil_param
inside HTTP request.Authorization
headers from HTTP requests and print the password to the attacker.Just what mitmproxy always does, but with code written in xepor way.
# https://github.com/xepor/xepor-examples/tree/main/httpbin/httpbin.py
from mitmproxy.http import HTTPFlow
from xepor import InterceptedAPI, RouteType
HOST_HTTPBIN = "httpbin.org"
api = InterceptedAPI(HOST_HTTPBIN)
@api.route("/get")
def change_your_request(flow: HTTPFlow):
"""
Modify URL query param.
Test at:
http://httpbin.org/#/HTTP_Methods/get_get
"""
flow.request.query["payload"] = "evil_param"
@api.route("/basic-auth/{usr}/{pwd}", rtype=RouteType.RESPONSE)
def capture_auth(flow: HTTPFlow, usr=None, pwd=None):
"""
Sniffing password.
Test at:
http://httpbin.org/#/Auth/get_basic_auth__user___passwd_
"""
print(
f"auth @ {usr} + {pwd}:",
f"Captured {'successful' if flow.response.status_code < 300 else 'unsuccessful'} login:",
flow.request.headers.get("Authorization", ""),
)
addons = [api]