Las solicitudes de proxy a través de Python y Burpsuite no funcionan

0

Tengo BurpSuite configurado como un proxy. He generado e instalado un certificado para Burp en el llavero de mi Mac. En una caja Kali también configuré Iceweasel para que se ejecute mediante proxy a través de mi Proxy Burp que se ejecuta en mi Mac. Puedo navegar desde Kali a sitios http y https y burp intercepta las solicitudes. Los reenvío y confirmo las excepciones de seguridad y el navegador finalmente muestra páginas web.

Desde la línea de comandos de Kali exporté las siguientes dos variables

export http_proxy=http://172.xx.yy.z:8081
export https_proxy=http://172.xx.yy.z:8081

Escribí un script en python:

(env) ojblass@kali:~/effective_python$ cat ojblass_urllib_http.py
import urllib
url = urllib.urlopen("http://www.hotmail.com")
data = url.read()
print data

Esto correctamente golpea el proxy BurpSuite; sin embargo, cuando intento ejecutar el tráfico https a través de la solicitud no se intercepta:

(env) ojblass@kali:~/effective_python$ cat ojblass_urllib_https.py
import urllib
url = urllib.urlopen("https://mail.live.com/default.aspx")
data = url.read()
print data

En su lugar, se imprime el siguiente error:

<html><head><title>Burp Suite Professional</title>
<style type="text/css">
body { background: #dedede; font-family: Arial, sans-serif; color: #404042; -webkit-font-smoothing: antialiased; }
#container { padding: 0 15px; margin: 10px auto; background-color: #ffffff; }
a { word-wrap: break-word; }
a:link, a:visited { color: #e06228; text-decoration: none; }
a:hover, a:active { color: #404042; text-decoration: underline; }
h1 { font-size: 1.6em; line-height: 1.2em; font-weight: normal; color: #404042; }
h2 { font-size: 1.3em; line-height: 1.2em; padding: 0; margin: 0.8em 0 0.3em 0; font-weight: normal; color: #404042;}
.title, .navbar { color: #ffffff; background: #e06228; padding: 10px 15px; margin: 0 -15px 10px -15px; overflow: hidden; }
.title h1 { color: #ffffff; padding: 0; margin: 0; font-size: 1.8em; }
div.navbar {position: absolute; top: 18px; right: 25px;}div.navbar ul {list-style-type: none; margin: 0; padding: 0;}
div.navbar li {display: inline; margi-left: 20px;}
div.navbar a {color: white; padding: 10px}
div.navbar a:hover, div.navbar a:active {text-decoration: none; background: #404042;}
</style>
</head>
<body>
<div id="container">
<div class="title"><h1>Burp Suite Professional</h1></div>
<h1>Error</h1><p>Invalid&#32;client&#32;request&#32;received&#58;&#32;First&#32;line&#32;of&#32;request&#32;did&#32;not&#32;contain&#32;an&#32;absolute&#32;URL&#32;&#45;&#32;try&#32;enabling&#32;invisible&#32;proxy&#32;support&#46;</p>
<div class="request">GET&nbsp;https://mail.live.com/default.aspx&nbsp;HTTP/1.0<br>
User-Agent:&nbsp;Python-urllib/1.17<br>
Accept:&nbsp;*/*<br>
<br>
</div><p>&nbsp;</p>
</div>
</body>
</html>

El contenido principal del error indica que se recibió una solicitud de cliente no válida. La primera línea de solicitud no contenía una URL absoluta. He buscado en Google este error pero todo lo que parece venir no parece relevante. Soy nuevo en esto y agradecería cualquier información que pueda tener.

    
pregunta ojblass 03.02.2017 - 20:09
fuente

1 respuesta

0

He encontrado la respuesta. Urllib no es compatible con el proxy https. Encontré este sitio que tiene una receta para conectarse correctamente.

Aquí está el código en caso de que el enlace se detenga:

# urllib2 opener to connection through a proxy using the CONNECT method, (useful for SSL)
# tested with python 2.4

import urllib2
import urllib
import httplib
import socket


class ProxyHTTPConnection(httplib.HTTPConnection):

    _ports = {'http' : 80, 'https' : 443}


    def request(self, method, url, body=None, headers={}):
        #request is called before connect, so can interpret url and get
        #real host/port to be used to make CONNECT request to proxy
        proto, rest = urllib.splittype(url)
        if proto is None:
            raise ValueError, "unknown URL type: %s" % url
        #get host
        host, rest = urllib.splithost(rest)
        #try to get port
        host, port = urllib.splitport(host)
        #if port is not defined try to get from proto
        if port is None:
            try:
                port = self._ports[proto]
            except KeyError:
                raise ValueError, "unknown protocol for: %s" % url
        self._real_host = host
        self._real_port = port
        httplib.HTTPConnection.request(self, method, url, body, headers)


    def connect(self):
        httplib.HTTPConnection.connect(self)
        #send proxy CONNECT request
        self.send("CONNECT %s:%d HTTP/1.0\r\n\r\n" % (self._real_host, self._real_port))
        #expect a HTTP/1.0 200 Connection established
        response = self.response_class(self.sock, strict=self.strict, method=self._method)
        (version, code, message) = response._read_status()
        #probably here we can handle auth requests...
        if code != 200:
            #proxy returned and error, abort connection, and raise exception
            self.close()
            raise socket.error, "Proxy connection failed: %d %s" % (code, message.strip())
        #eat up header block from proxy....
        while True:
            #should not use directly fp probablu
            line = response.fp.readline()
            if line == '\r\n': break


class ProxyHTTPSConnection(ProxyHTTPConnection):

    default_port = 443

    def __init__(self, host, port = None, key_file = None, cert_file = None, strict = None):
        ProxyHTTPConnection.__init__(self, host, port)
        self.key_file = key_file
        self.cert_file = cert_file

    def connect(self):
        ProxyHTTPConnection.connect(self)
        #make the sock ssl-aware
        ssl = socket.ssl(self.sock, self.key_file, self.cert_file)
        self.sock = httplib.FakeSocket(self.sock, ssl)


class ConnectHTTPHandler(urllib2.HTTPHandler):

    def do_open(self, http_class, req):
        return urllib2.HTTPHandler.do_open(self, ProxyHTTPConnection, req)


class ConnectHTTPSHandler(urllib2.HTTPSHandler):

    def do_open(self, http_class, req):
        return urllib2.HTTPSHandler.do_open(self, ProxyHTTPSConnection, req)


if __name__ == '__main__':

    import sys

    opener = urllib2.build_opener(ConnectHTTPHandler, ConnectHTTPSHandler)
    urllib2.install_opener(opener)
    req = urllib2.Request(url='https://192.168.1.1')
    req.set_proxy('192.168.1.254:3128', 'https')
    f = urllib2.urlopen(req)
    print f.read()
    
respondido por el ojblass 03.02.2017 - 22:22
fuente

Lea otras preguntas en las etiquetas