0
votes

I run a local HTTP proxy server on my machine and perform some logging. And I'd like to log SSL traffic as well. For this purpose I run another proxy server, written in Python, which acts as a SSL server, with my self-signed certificate, to which the HTTP server forwads CONNECT requests. The SSL proxy uses for SSL handling the 'ssl' standard Python module. This SSL proxy should forward SSL traffic to the destination web server.

The HTTP proxy successfully forwards CONNECT requests from the browser and the connection between the browser and SSL proxy establishes OK. And SSL proxy receives SSL packets from the browser with SSL socket function 'read', which presumably should return already decrypted data. This is an example packet which is received on the SSL proxy:

'\x16\x03\x01\x00\xc5\x01\x00\x00\xc1\x03\x03\xeb\xd09\x12\xe3=$Id:\xe5\xf9<Px\xf0\xda\x81R&\x02\xcau\xd2t=@\xe9\x95\xf8\x7f\x86\x00\x00\x18\xc0+\xc0/\xc0\n\xc0\t\xc0\x13\xc0\x14\x003\x002\x009\x00/\x005\x00\n\x01\x00\x00\x80\x00\x00\x00\x17\x00\x15\x00\x00\x12wiki.archlinux.org\xff\x01\x00\x01\x00\x00\n\x00\x08\x00\x06\x00\x17\x00\x18\x00\x19\x00\x0b\x00\x02\x01\x00\x00#\x00\x003t\x00\x00\x00\x10\x00#\x00!\x05h2-15\x05h2-14\x02h2\x08spdy/3.1\x08http/1.1\x00\x05\x00\x05\x01\x00\x00\x00\x00\x00\r\x00\x12\x00\x10\x04\x01\x05\x01\x02\x01\x04\x03\x05\x03\x02\x03\x04\x02\x02\x02'

This can be recognized as a handshake SSL packet with the leading 0x16 byte and with the length of 197 bytes. The destination server address (wiki.archlinux.org) is readable, as well as protocols (spdy and http), but what is the general format of this data? Is there some tools or libraries with which these packets can be parsed?

1

1 Answers

0
votes

The general format of these data is described in the RFCs for TLS1.2 and below. What you need to parse is an ASN.1 parser like this one. But before you do it you should probably understand what kind of information you get. Otherwise you would find out too late, that you will not find the destination server inside the SSL data in all cases, because it is only given if the client uses the Server Name Indication extension. While all modern browsers do this older browser do not and some mobile applications or script don't do it either. This means you should instead use the destination given in the CONNECT request.

For more details on how to write such a proxy I would recommend to have a look at mitmproxy which maybe already does what you are trying to implement or provides the library libmproxy to help you write your own proxy. And it is written in python so you at least can learn from the open source how do implement the necessary functionality.