rapid7 / metasploit-framework

Metasploit Framework
https://www.metasploit.com/
Other
33.91k stars 13.93k forks source link

Meterpreter Fails to use Squid Kerberos/NTLM authentication proxy with HTTP/1.0 #5626

Closed Loki1980 closed 9 years ago

Loki1980 commented 9 years ago

Hi all,

I'm having trouble using windows/x64/meterpreter/reverse_https in an environment with a Squid Kerberos/NTLM authentication proxy. The initial connection works fine, but then, when the stage takes over, it is unable to connect because it does not send the "Proxy-Connection: Keep-Alive" header, so it does not get the "Proxy-Authenticate" header with the challenge from the proxy.

Below an example of request/response for the initial connection (which works) and the stage

CONNECT X.X.X.X:443 HTTP/1.0 Host: X.X.X.X:443 Proxy-Connection: Keep-Alive Pragma: no-cache Proxy-Authorization: Negotiate TlRMTVNTUAABAAAAl4II4gAAAAAAAAAAAAAAAAAAAAAGAbEdAAAADw== Content-Length: 0

HTTP/1.0 407 Proxy Authentication Required Server: squid/2.7.STABLE9 Date: Mon, 29 Jun 2015 13:45:21 GMT Content-Type: text/html Content-Length: 1169 X-Squid-Error: ERR_CACHE_ACCESS_DENIED 0 Proxy-Authenticate: Negotiate TlRMTVNTUAA [... REMOVED ...] X-Cache: MISS from debian-proxy X-Cache-Lookup: NONE from debian-proxy:3128 Via: 1.0 debian-proxy:3128 (squid/2.7.STABLE9) Connection: keep-alive Proxy-Connection: keep-alive

CONNECT X.X.X.X:443 HTTP/1.1 Host: X.X.X.X:443 Proxy-Authorization: Negotiate TlRMTVNTUAABAAAAl4II4gAAAAAAAAAAAAAAAAAAAAAGAbEdAAAADw==

HTTP/1.0 407 Proxy Authentication Required Server: squid/2.7.STABLE9 Date: Mon, 29 Jun 2015 13:45:26 GMT Content-Type: text/html Content-Length: 1169 X-Squid-Error: ERR_CACHE_ACCESS_DENIED 0 X-Cache: MISS from debian-proxy X-Cache-Lookup: NONE from debian-proxy:3128 Via: 1.0 debian-proxy:3128 (squid/2.7.STABLE9) Connection: close

Stageless payload have the same problem, they are not able to authenticate on the proxy because of the missing header. I am using the latest version of metasploit-framework from git.

OJ commented 9 years ago

Proxy issues are going to be the death of me ;) This isn't the first report of this issue that I've seen, but I've not had an NTLM proxy set up so I haven't been able to test this case. This is the most thorough report so far, so thanks for that!

I'm not convinced that the lack of the Proxy-Connection header is the thing that's killing it, but it's an interesting insight and something to bear in mind. A couple of things you should be aware of:

This is why you see a successful connection when the payload fires, but from there Meterpreter fails to get through because the API set is different, and the winhttp libraries aren't doing the same thing. This is something I really need to fix but have found it hard without an environment to work in.

Out of interest, is this environment you're working in on site with a client or is it local? Would you be open to testing fixes if I can look into this tomorrow?

Thanks @Loki1980 :)

Loki1980 commented 9 years ago

Hi @OJ

this is a local environment I made for testing, so yes I can definitely help you if you want :) According to the tests I have done I think that the header is actually the key; if the meterpreter points to a local proxy (like zap) that uses as upstream proxy the "corporate" squid proxy, than everything works, and if I dump the traffic with wireshark I can see that zap is sending to squid the Proxy-Connection header also for the payload. Without zap it doesn't work even if I explicity specify the proxy host and port using the PayloadProxyHost and PayloadProxyPort variables.

Thank you very much for your quick response!

OJ commented 9 years ago

OK mate that sounds great. I'll get into this first thing in the morning (it's midnight here now).

Thank you for the detailed report. Super helpful! I will be in touch tomorrow. Cheers!

OJ commented 9 years ago

I've just gone through the process of setting up Squid with NTLM auth and domain-joined a machine that isn't able to see an external network unless going via the proxy, which only supports NTLM. This is the set up:

                         +----------+                       
                         |   PDC    |                       
                         |10.1.10.11|                       
                         +---+--+---+                       
                             ^  |                           
                             |  |                           
                             |  v                           
+----------------+      +----+--+----+       +-------------+
|Windows 7 Client+----->+Squid  Proxy+------>+MSF  Listener|
|   10.1.10.41   |      | 10.1.10.40 |       | 192.168.1.1 |
+----------------+      +------------+       +-------------+

The Squid proxy can bridge to the 192.168.1/24 network. The listener is set up to listen on that network, and so the Windows 7 client can't get to it without going through that proxy.

Here is a sample handshake from Meterpreter after the stage has been loaded.

Step 1

Step 1 This image shows the initial attempt to post RECV to the target endpoint. This includes the Proxy-Connection: Keep-Alive header. The Proxy responds asking for NTLM auth.

Step 2

Step 2 Meterpreter responds with the Proxy-Authorization: NTLM ... header, and the proxy again responds appropriately.

Step 3

Step 3 Final bit of negotiation.

Step 4

Step 4 And finally the request succeeds.

Doh!

While these screenshots are clearly for HTTP, the behaviour is the same for HTTPS.

Can you please confirm the Windows version of the target?

Thanks.

Loki1980 commented 9 years ago

Hey @OJ ,

I really don't know what to say.. my setup is quite similar (it is just a bit more complex), the client version is windows 7 x64 Sp1. What changes is the version of squid, mine is 2.7.STABLE9 (the one from the packages of debian wheezy), yours is 3.4.12.

If you look at the responses of the squid3 proxy server you'll notice that it uses http/1.1,while Squid 2.7 uses instead http/1.0. Since http1.1 and 1.0 handle connections very differently that may be the reason why your setup works and mine not, but still I don't understand why in your case the "Proxy-connection" header is always sent by meterpreter... What payload did you use? /windows/x64/meterpreter/reverse_http or /windows/x64/meterpreter_reverse_http

I don't know if there is a way to force squid3 to always respond using http/1.0, maybe you can try forcing the meterpreter to use http/1.0 and see what happens in that case?

Loki1980 commented 9 years ago

hey @OJ ,

I confirm you it is a problem with the HTTP/1.0 connections. I activated the HTTP/1.1 support on squid 2.7 (even if it is experimental) and now meterpreter works :-)

OJ commented 9 years ago

Great find! That gives me something to work with. Thanks so much dude! On Jun 30, 2015 6:55 PM, "Loki1980" notifications@github.com wrote:

hey @OJ https://github.com/OJ ,

I confirm you it is a problem with the HTTP/1.0 connection. I activated the HTTP/1.1 support on squid 2.7 (even if it is experimental) and now meterpreter works :-)

— Reply to this email directly or view it on GitHub https://github.com/rapid7/metasploit-framework/issues/5626#issuecomment-117062422 .

OJ commented 9 years ago

@Loki1980 http://blogs.msdn.com/b/httpcontext/archive/2012/02/21/changes-in-winhttp-on-windows-7-and-onwards-wrto-http-1-0.aspx <~ ooooh

OJ commented 9 years ago

This is concerning:

screen shot 2015-06-30 at 7 55 13 pm

Basically means if the proxy is HTTP/1.0, then NTLM authentication can't be used with WinHTTP. Hmm.

Loki1980 commented 9 years ago

Hey @OJ ,

that explains why it works perfectly when using a HTTP/1.1 compliant proxy and fails with a HTTP/1.0 one! so.. basically the only thing you could possibly do to handle this particular situation is to make meterpreter use wininet API instead of WinHttp if it is using an ntlm proxy which responds using http/1.0??

OJ commented 9 years ago

Hey Loki,

I'm currently working on a fix for this. Should be done by the end of today... I hope! On Jul 2, 2015 12:10 AM, "Loki1980" notifications@github.com wrote:

Hey @OJ https://github.com/OJ ,

that explains why it works perfectly when using a HTTP/1.1 compliant proxy and fails with a HTTP/1.0 one! so.. basically the only thing you could possibly do to handle this particular situation is to make meterpreter use wininet API instead of WinHttp if it is using an ntlm proxy which responds using http/1.0??

— Reply to this email directly or view it on GitHub https://github.com/rapid7/metasploit-framework/issues/5626#issuecomment-117689129 .

OJ commented 9 years ago

Hey @Loki1980 I've now got an env set up with NTLM auth going through Squid 2.7 that has just HTTP 1.0 support and I'm seeing the same breakage.

This is great, because I can finally see the failures that other people have been having.

This is terrible, because now I have to fix it ;) I'm on it though!

OJ commented 9 years ago

Hey all, I've added some documentation to the wiki that talks about all this stuff in a bit of detail. I'd appreciate a review. Thanks!

https://github.com/rapid7/metasploit-framework/wiki/The-ins-and-outs-of-HTTP-and-HTTPS-communications-in-Meterpreter-and-Metasploit-Stagers

bcook-r7 commented 9 years ago

We should be good now that #5691 is merged.