Is it possible to use MITMf to sniff as a transparent proxy? If I connect to this proxy I would want to see my real IP, not the server IP. If possible, how can I do it? I found this file "ClientRequest.py" , but I don't know python. Maybe someone can help me to set the proxy not to edit the headers?

class ClientRequest(Request):

    ''' This class represents incoming client requests and is essentially where
    the magic begins.  Here we remove the client headers we dont like, and then
    respond with either favicon spoofing, session denial, or proxy through HTTP
    or SSL to the server.

    def __init__(self, channel, queued, reactor=reactor):
        Request.__init__(self, channel, queued)
        self.reactor       = reactor
        self.urlMonitor    = URLMonitor.getInstance()
        self.cookieCleaner = CookieCleaner.getInstance()
        self.dnsCache      = DnsCache.getInstance()
        #self.uniqueId      = random.randint(0, 10000)

    def cleanHeaders(self):
        headers = self.getAllHeaders().copy()

        if 'accept-encoding' in headers:
             del headers['accept-encoding']
             log.debug("[ClientRequest] Zapped encoding")

        if 'if-modified-since' in headers:
            del headers['if-modified-since']

        if 'cache-control' in headers:
            del headers['cache-control']

        if 'host' in headers:
                for entry in self.urlMonitor.cookies[self.urlMonitor.hijack_client]:
                    if headers['host'] == entry['host']:
                        log.info("Hijacking session for host: {}".format(headers['host']))
                        headers['cookie'] = entry['cookie']
            except KeyError:
                log.error("No captured sessions (yet) from {}".format(self.urlMonitor.hijack_client))

        return headers

    def getPathFromUri(self):
        if (self.uri.find("http://") == 0):
            index = self.uri.find('/', 7)
            return self.uri[index:]

        return self.uri   

    def handleHostResolvedSuccess(self, address):
        log.debug("[ClientRequest] Resolved host successfully: {} -> {}".format(self.getHeader('host'), address))
        host              = self.getHeader("host")
        headers           = self.cleanHeaders()
        client            = self.getClientIP()
        path              = self.getPathFromUri()
        url               = 'http://' + host + path
        self.uri = url # set URI to absolute

        if self.content:

        postData = self.content.read()

        hostparts = host.split(':')
        self.dnsCache.cacheResolution(hostparts[0], address)

        if (not self.cookieCleaner.isClean(self.method, client, host, headers)):
            log.debug("[ClientRequest] Sending expired cookies")
            self.sendExpiredCookies(host, path, self.cookieCleaner.getExpireHeaders(self.method, client, host, headers, path))

        elif self.urlMonitor.isSecureLink(client, url):
            log.debug("[ClientRequest] Sending request via SSL ({})".format((client,url)))
            self.proxyViaSSL(address, self.method, path, postData, headers, self.urlMonitor.getSecurePort(client, url))

            log.debug("[ClientRequest] Sending request via HTTP")
            #self.proxyViaHTTP(address, self.method, path, postData, headers)
            port = 80
            if len(hostparts) > 1:
                port = int(hostparts[1])

            self.proxyViaHTTP(address, self.method, path, postData, headers, port)

    def handleHostResolvedError(self, error):
        log.debug("[ClientRequest] Host resolution error: {}".format(error))

    def resolveHost(self, host):
        address = self.dnsCache.getCachedAddress(host)

        if address != None:
            log.debug("[ClientRequest] Host cached: {} {}".format(host, address))
            return defer.succeed(address)
            return reactor.resolve(host)

    def process(self):
        log.debug("[ClientRequest] Resolving host: {}".format(self.getHeader('host')))
        host = self.getHeader('host').split(":")[0]              

        deferred = self.resolveHost(host)

    def proxyViaHTTP(self, host, method, path, postData, headers, port):
        connectionFactory          = ServerConnectionFactory(method, path, postData, headers, self)
        connectionFactory.protocol = ServerConnection
        #self.reactor.connectTCP(host, 80, connectionFactory)
        self.reactor.connectTCP(host, port, connectionFactory)

    def proxyViaSSL(self, host, method, path, postData, headers, port):
        clientContextFactory       = ssl.ClientContextFactory()
        connectionFactory          = ServerConnectionFactory(method, path, postData, headers, self)
        connectionFactory.protocol = SSLServerConnection
        self.reactor.connectSSL(host, port, connectionFactory, clientContextFactory)

    def sendExpiredCookies(self, host, path, expireHeaders):
        self.setResponseCode(302, "Moved")
        self.setHeader("Connection", "close")
        self.setHeader("Location", "http://" + host + path)

        for header in expireHeaders:
            self.setHeader("Set-Cookie", header)

  • What OS are you using? a Linux distro, OS X, MS Windows?
    – Xanmashi
    Aug 17, 2016 at 9:03
  • I am using linux
    – johnmet
    Aug 17, 2016 at 10:03
  • I know how to make transparent proxy with SQIUD. But I need to use MITMF. Maybe I should use some iptables rules?
    – johnmet
    Aug 17, 2016 at 10:09
  • How to make it transparent?
    – johnmet
    Aug 17, 2016 at 10:32
  • Please explain what are you trying to achieve, maybe it will help understanding the question. thanks.
    – Eibo
    Aug 17, 2016 at 10:39

2 Answers 2


Based on the answers of this question, the answer is a matter of two principles:

  1. The proxy configuration. you can set the proxy not to edit headers, especially the fields such as X-Forwarded-For and X-Client-IP.
  2. Client modifications. Many transparent proxies will allow SSL traffic to pass by without proxying, since proxying an SSL connection requires spoofing certificates.
    So the SSL address is the "real" IP, and the non-SSL address is the address of the proxy.
  • How can I set the proxy not to edit the headers?
    – johnmet
    Aug 17, 2016 at 14:57
  • Use Wireshark or any network sniffer on the server and check outgoing packets.
    – Eibo
    Aug 17, 2016 at 15:40

It can not, a transparent proxy is more or less a language abuse, it is transparent to the end user because it doesn't require configuration on the end user part (the workstation just does normal requests).

For a proxy to work it has to intercept the flow, it will end the workstation flow and make the request on behalf of the client. The source address will be the proxy address for the remote server. (Some firewall will do an out of band analysis for clear text traffic where this isn't true, but it's usually 'brittle' and again limited to clear text only)

For analysis of SSL requests, the firewall will end the flow, it will present a certificate matching the site, mainly signing a new certificate with the same subject and alternative names, but issued by itself.
Hence the workstation talks ssl to the firewall, and the firewall talks ssl to the remote site. Usually (transparency) the firewall Authority will be self signed/enterprise CA so any workstation out of control (guests) will know there's a MITM.
But there's nothing preventing them to used a 'generally' trusted certificate (and that's just a matter of money to get the correct cert).

Your python code act as 'classic' proxy, the workstation connect to it, and the program makes the request to the remote site, passing the answer back to the original workstation.

TL;Dr: a man in the middle is, as the name state, in the middle of the communication and so the IP seen by the remote server will be the proxy public IP (wich could be the public IP of a firewall doing NAT later in the routing chain)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .