Skip to content

Instantly share code, notes, and snippets.

@mhils
Created January 8, 2015 11:17
Show Gist options
  • Save mhils/d37ec10401eed8f8c797 to your computer and use it in GitHub Desktop.
Save mhils/d37ec10401eed8f8c797 to your computer and use it in GitHub Desktop.
mitmproxy client ip spoofing
You currently suggest the following iptables rules:
# iptables -A PREROUTING -s {SOURCE} -p tcp -m tcp --dport 80 -j
REDIRECT --to-ports 8080
In order to utilize fully transparent mode, you also need:
# iptables -t mangle -N DIVERT
# iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
# ip tables -t mangle -A DIVERT -j MARK --set-mark 0x2/0x2 # your mark may vary
# iptables -t mangle -A DIVERT -j ACCEPT
# ip rule add fwmark 0x2/0x2 lookup 101 # your name id may vary
# ip route add local 0.0.0.0/0 dev lo table 101
If you are deploying this on a router, you'll need something like this
because normally the input chain is heavily filtered.
# iptables -I INPUT 1 -m mark --mark 0x2/0x2 -j ACCEPT
You may also need to disable rp_filter. (I did not test it with it enabled):
# sysctl -w net.ipv4.conf.all.rp_filter=0
--- netlib/tcp.py.bak.transparent 2014-10-01 15:26:04.141214810 -0700
+++ netlib/tcp.py 2014-10-01 17:47:54.286213299 -0700
@@ -179,13 +179,14 @@
class TCPClient:
rbufsize = -1
wbufsize = -1
- def __init__(self, host, port, source_address=None, use_ipv6=False):
+ def __init__(self, host, port, source_address=None, use_ipv6=False, fully_trans=False):
self.host, self.port = host, port
self.source_address = source_address
self.use_ipv6 = use_ipv6
self.connection, self.rfile, self.wfile = None, None, None
self.cert = None
self.ssl_established = False
+ self.fully_trans = fully_trans
def convert_to_ssl(self, cert=None, sni=None, method=TLSv1_METHOD, options=None):
"""
@@ -216,7 +217,10 @@
def connect(self):
try:
connection = socket.socket(socket.AF_INET6 if self.use_ipv6 else socket.AF_INET, socket.SOCK_STREAM)
+ if self.fully_trans:
+ connection.setsockopt(socket.SOL_IP, 19, 1)
if self.source_address:
+ self.source_address = (self.source_address[0], 0)
connection.bind(self.source_address)
connection.connect((self.host, self.port))
self.rfile = Reader(connection.makefile('rb', self.rbufsize))
@@ -362,9 +366,10 @@
class TCPServer:
request_queue_size = 20
- def __init__(self, server_address, use_ipv6=False):
+ def __init__(self, server_address, use_ipv6=False, fully_trans=False):
self.server_address = server_address
self.use_ipv6 = use_ipv6
+ self.fully_trans = fully_trans
self.__is_shut_down = threading.Event()
self.__shutdown_request = False
self.socket = socket.socket(socket.AF_INET6 if self.use_ipv6 else socket.AF_INET, socket.SOCK_STREAM)
@@ -372,6 +377,8 @@
self.socket.bind(self.server_address)
self.server_address = self.socket.getsockname()
self.port = self.server_address[1]
+ if self.fully_trans:
+ self.socket.setsockopt(socket.SOL_IP, 19, 1)
self.socket.listen(self.request_queue_size)
def request_thread(self, request, client_address):
--- libmproxy/cmdline.py.bak.transparent 2014-10-01 17:39:52.458213386 -0700
+++ libmproxy/cmdline.py 2014-10-01 17:39:57.595213385 -0700
@@ -222,6 +222,11 @@
help="Set transparent to client proxy mode."
)
parser.add_argument(
+ "-TS",
+ action="store_true", dest="fully_transparent_proxy", default=False,
+ help="Set transparent to server proxy mode."
+ )
+ parser.add_argument(
"-u",
action="store", dest="stickyauth_filt", default=None, metavar="FILTER",
help="Set sticky auth filter. Matched against requests."
--- libmproxy/proxy.py.bak.transparent 2014-10-01 15:31:30.399214753 -0700
+++ libmproxy/proxy.py 2014-10-01 17:43:16.879213350 -0700
@@ -24,7 +24,7 @@
class ProxyConfig:
- def __init__(self, certfile = None, cacert = None, clientcerts = None, no_upstream_cert=False, body_size_limit = None, reverse_proxy=None, forward_proxy=None, transparent_proxy=None, authenticator=None):
+ def __init__(self, certfile = None, cacert = None, clientcerts = None, no_upstream_cert=False, body_size_limit = None, reverse_proxy=None, forward_proxy=None, transparent_proxy=None, fully_transparent_proxy=False, authenticator=None):
self.certfile = certfile
self.cacert = cacert
self.clientcerts = clientcerts
@@ -33,13 +33,14 @@
self.reverse_proxy = reverse_proxy
self.forward_proxy = forward_proxy
self.transparent_proxy = transparent_proxy
+ self.fully_transparent_proxy = fully_transparent_proxy
self.authenticator = authenticator
self.certstore = certutils.CertStore()
class ServerConnection(tcp.TCPClient):
def __init__(self, config, scheme, host, port, sni):
- tcp.TCPClient.__init__(self, host, port)
+ tcp.TCPClient.__init__(self, host, port, fully_trans=config.fully_transparent_proxy)
self.config = config
self.scheme, self.sni = scheme, sni
self.requestcount = 0
@@ -179,6 +180,8 @@
self.server_conn.conn_info = conn_info
self.channel.ask("serverconnect", self.server_conn)
+ if self.config.fully_transparent_proxy:
+ self.server_conn.source_address = self.client_address
self.server_conn.connect()
except tcp.NetLibError, v:
raise ProxyError(502, v)
@@ -532,7 +535,7 @@
self.config, self.port, self.address = config, port, address
self.server_version = server_version
try:
- tcp.TCPServer.__init__(self, (address, port))
+ tcp.TCPServer.__init__(self, (address, port), fully_trans=config.fully_transparent_proxy)
except socket.error, v:
raise ProxyServerError('Error starting proxy server: ' + v.strerror)
self.channel = None
@@ -649,5 +652,6 @@
reverse_proxy = rp,
forward_proxy = fp,
transparent_proxy = trans,
+ fully_transparent_proxy = options.fully_transparent_proxy,
authenticator = authenticator
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment