86 lines
2.9 KiB
Python
86 lines
2.9 KiB
Python
import asyncio
|
|
import importlib
|
|
import traceback
|
|
import os
|
|
import argparse
|
|
import ipaddress
|
|
import socket
|
|
|
|
import forwarding
|
|
import handler
|
|
|
|
|
|
async def queue_handler(queue: asyncio.Queue):
|
|
last_edit_timestamp = os.stat(handler.__file__).st_mtime_ns
|
|
while True:
|
|
tag, data = await queue.get()
|
|
try:
|
|
timestamp = os.stat(handler.__file__).st_mtime_ns
|
|
if timestamp > last_edit_timestamp:
|
|
importlib.reload(handler)
|
|
last_edit_timestamp = timestamp
|
|
|
|
if asyncio.iscoroutinefunction(handler.handle):
|
|
await handler.handle(tag, data)
|
|
else:
|
|
handler.handle(tag, data)
|
|
except Exception:
|
|
traceback.print_exc()
|
|
|
|
|
|
async def main():
|
|
p = argparse.ArgumentParser()
|
|
p.add_argument('remote_host', type=str, help='Host you want to spy on')
|
|
p.add_argument('remote_port', type=int, help='Port on remote_host')
|
|
p.add_argument('--listen-host', type=str, default='0.0.0.0', help='MITM binds to this (default 0.0.0.0)')
|
|
p.add_argument('--listen-port', type=int, default=1337, help='MITM port (default 1337)')
|
|
p.add_argument('--output-host', type=str, default='10.227.12.40',
|
|
help='IP used to proxy remote_host (default 10.227.12.40)')
|
|
p.add_argument('--output-port', type=int, default=1337, help='Port used by proxy (default 1337)')
|
|
args = p.parse_args()
|
|
|
|
remote_host_ip = ipaddress.IPv4Address(socket.gethostbyname(args.remote_host))
|
|
listen_host_ip = ipaddress.IPv4Address(args.listen_host)
|
|
output_host_ip = ipaddress.IPv4Address(args.output_host)
|
|
|
|
# set up iptables
|
|
|
|
os.system(f'sudo iptables '
|
|
f'-t nat -A OUTPUT '
|
|
f'-d {remote_host_ip} -p tcp --dport {args.remote_port} '
|
|
f'-j DNAT --to 127.0.0.1:{args.listen_port}')
|
|
|
|
os.system(f'sudo iptables '
|
|
f'-t nat -A OUTPUT '
|
|
f'-d {output_host_ip} -p tcp --dport {args.output_port} '
|
|
f'-j DNAT --to {remote_host_ip}:{args.remote_port}')
|
|
|
|
# run man-in-the-middle
|
|
|
|
queue = asyncio.Queue()
|
|
forwarder = forwarding.Forwarder(str(listen_host_ip), args.listen_port,
|
|
str(output_host_ip), args.output_port,
|
|
queue)
|
|
|
|
queue_task = asyncio.create_task(queue_handler(queue))
|
|
|
|
await forwarder.run()
|
|
|
|
queue_task.cancel()
|
|
|
|
# tear down iptables
|
|
|
|
os.system(f'sudo iptables '
|
|
f'-t nat -D OUTPUT '
|
|
f'-d {remote_host_ip} -p tcp --dport {args.remote_port} '
|
|
f'-j DNAT --to 127.0.0.1:{args.listen_port}')
|
|
|
|
os.system(f'sudo iptables '
|
|
f'-t nat -D OUTPUT '
|
|
f'-d {output_host_ip} -p tcp --dport {args.output_port} '
|
|
f'-j DNAT --to {remote_host_ip}:{args.remote_port}')
|
|
|
|
|
|
if __name__ == '__main__':
|
|
asyncio.run(main())
|