adamfisk/LittleProxy

Support certificate impersonation for Man in the Middle proxies

oxtoacart opened this issue · 4 comments

We've added back basic MITM under issue #79. To make this useful in production, it would be nice if someone could implement certificate impersonation.

See here for an explanation of how this is done by mitmproxy.

MitmManager already has a hook for this, so one would just need to implement an appropriate MitmManager.

I was looking at the mitmManager.. don't we need to change the flow for connect based on the mitmproxy. The connect comes in from the client to the proxy. The proxy then connects to the server and then moves the state to connect with the client (proxy). Based on this mitmproxy diagram we should auto send back a connect message to the client of the proxy to get it's SSL info ( not sure how to retrieve this yet). Then use that to impersonate the client via the proxy to the webserver.. Get the SSL info from the webserver and generate a server cert based on that information to trick the proxy client.. That sounds correct?

Well, there's a couple of aspects to this:

  1. The current flow does not try to support impersonating clients. The proxy uses its own certificate to connect to the server. As I understood it, the main use case is for the proxy to impersonate the server, so this should be okay for that.
  2. As it currently works, the proxy first encrypts the connection with the server, then tells the client that their CONNECT was ok, then handshakes with the client. By doing it this way, the proxy has the server's certificate available to hand to the client.

The difference from mitmproxy is that mitmproxy supports SNI, whereas I suspect that the current flow in LittleProxy does not (see #86). I'm also not sure how to hook into the SSL handshake the way that mitmproxy does. One thing that may complicate this is that Java 6 and 7 don't support server-side SNI, it's coming in Java 8. Another complication is that mitmproxy actually handshakes with the server in the middle of handshaking with the client. This is handled by javax.net.ssl.SSLEngine and it might be difficult for us to hook into that (though we could perhaps implement a custom KeyManager that makes the call to the server.

All that said, it would be cool if we can figure out a way to support SNI, but I think we should treat that as a phase II thing.

Certificate impersonation is done with ganskef/LittleProxy-mitm (#174). It was intended to be a part of LittleProxy, but it should be moved into a separate module (#173).

Connecting SNI enabled sites is working from Java 6 onwards by creating an SSLEngine with peer information (#207 #210), but this introduces a problem with misconfigured servers (ganskef/LittleProxy-mitm#2).

A security concern is that host name verification is not enabled with SSLEngine by default. Since Java 7, a method javax.net.ssl.SSLParameters.setEndpointIdentificationAlgorithm(String) does it (used by reflection to build with Java 6), but this is not available with Java 6 and Android too.

jekh commented

Now that this is done, I'll go ahead and close this issue.