{"action":"created","issue":{"url":"https://api.github.com/repos/rapid7/metasploit-payloads/issues/5","labels_url":"https://api.github.com/repos/rapid7/metasploit-payloads/issues/5/labels{/name}","comments_url":"https://api.github.com/repos/rapid7/metasploit-payloads/issues/5/comments","events_url":"https://api.github.com/repos/rapid7/metasploit-payloads/issues/5/events","html_url":"https://github.com/rapid7/metasploit-payloads/pull/5","id":92859533,"number":5,"title":"Fallback to WinINET when WinHTTP fails to authenticate to proxies","user":{"login":"OJ","id":28896,"avatar_url":"https://avatars.githubusercontent.com/u/28896?v=3","gravatar_id":"","url":"https://api.github.com/users/OJ","html_url":"https://github.com/OJ","followers_url":"https://api.github.com/users/OJ/followers","following_url":"https://api.github.com/users/OJ/following{/other_user}","gists_url":"https://api.github.com/users/OJ/gists{/gist_id}","starred_url":"https://api.github.com/users/OJ/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OJ/subscriptions","organizations_url":"https://api.github.com/users/OJ/orgs","repos_url":"https://api.github.com/users/OJ/repos","events_url":"https://api.github.com/users/OJ/events{/privacy}","received_events_url":"https://api.github.com/users/OJ/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/rapid7/metasploit-payloads/labels/bug","name":"bug","color":"fc2929"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":12,"created_at":"2015-07-03T11:48:59Z","updated_at":"2015-07-09T05:52:02Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/rapid7/metasploit-payloads/pulls/5","html_url":"https://github.com/rapid7/metasploit-payloads/pull/5","diff_url":"https://github.com/rapid7/metasploit-payloads/pull/5.diff","patch_url":"https://github.com/rapid7/metasploit-payloads/pull/5.patch"},"body":"Since moving to WinHTTP for HTTP/S comms in Windows we've had issues with communications in cases where the target lives behind a proxy that authenticates via NTLM. It was discovered, with help from @Loki1980, that the reason we were seeing breakages was because of proxies being configured to respond with HTTP version `1.0`.\r\n\r\nFrom Windows 7 onwards, the WinHTTP implementation is strictly compliant to the `1.1` RFC. As a result, any communications with proxies that doesn't result in a `1.0` response results in WinHTTP failing to authenticate with the proxy using NTLM (thanks to the lack of support of the keep alive header).\r\n\r\nFor some more information, have a read of [this](http://blogs.msdn.com/b/httpcontext/archive/2012/02/21/changes-in-winhttp-on-windows-7-and-onwards-wrto-http-1-0.aspx).\r\n\r\nThis PR contains that does the following:\r\n\r\n* Uses WinHTTP by default, as this is the preferred case, especially given that we still want to use the SSL cert validation features if possible.\r\n* If a `407` error code is returned, it is shows that proxy authentication has failed and given that WinHTTP can't handle this case (there's no workaround), some of the underlying function pointers are switched around to use WinINET instead.\r\n* The transport the switches back to itself, forcing an initialisation of WinINET.\r\n* From here, WinINET continues on it's merry way, because it's clearly the honey badger of HTTP RFCs.\r\n\r\nThis PR should fix these issues:\r\n\r\n* https://github.com/rapid7/metasploit-framework/issues/5626\r\n* https://github.com/rapid7/metasploit-framework/issues/5462\r\n\r\n## Sample runs\r\n\r\nSample runs are boring, because they look like any other normal Meterpreter session, so I haven't included them here.\r\n\r\n## Verification\r\n\r\nGiven the nature of this change it's important to make sure that existing stuff doesn't break as well as having the new stuff work correctly. Before this can be verified, it's important to have an environment configured that has a proxy that uses HTTP 1.0 and is configured to do NTLM authentication. This is what I did:\r\n\r\n- [ ] Have a domain handy and ready to rock\r\n- [ ] Create a VM with Debian 7.8 Wheezy installed\r\n- [ ] Install squid 2.7: `sudo apt-get install squid`\r\n- [ ] Add the machine to your active directory domain (used instructions found [here](http://admin-reminder.blogspot.com.au/2011/10/squid-authenticating-against-active.html), don't miss any steps)\r\n- [ ] Validate that you're able to authenticate to the domain using the steps show in the previous article\r\n- [ ] Make sure that the squid user (called `proxy`) is added to the `winbindd_priv` group and restart squid\r\n- [ ] Use the following squid configuration:\r\n```\r\nauth_param ntlm program /usr/bin/ntlm_auth --helper-protocol=squid-2.5-ntlmssp\r\nauth_param ntlm children 5\r\nauth_param ntlm keep_alive on\r\nacl all src all\r\nacl manager proto cache_object\r\nacl localhost src 127.0.0.1/32\r\nacl to_localhost dst 127.0.0.0/8 0.0.0.0/32\r\nacl localnet src 10.0.0.0/8\t# RFC1918 possible internal network\r\nacl localnet src 172.16.0.0/12\t# RFC1918 possible internal network\r\nacl localnet src 192.168.0.0/16\t# RFC1918 possible internal network\r\nacl SSL_ports port 443\t\t# https\r\nacl SSL_ports port 8443\t\t# https\r\nacl SSL_ports port 563\t\t# snews\r\nacl SSL_ports port 873\t\t# rsync\r\nacl Safe_ports port 80\t\t# http\r\nacl Safe_ports port 21\t\t# ftp\r\nacl Safe_ports port 443\t\t# https\r\nacl Safe_ports port 8443\t\t# https\r\nacl Safe_ports port 70\t\t# gopher\r\nacl Safe_ports port 210\t\t# wais\r\nacl Safe_ports port 1025-65535\t# unregistered ports\r\nacl Safe_ports port 280\t\t# http-mgmt\r\nacl Safe_ports port 488\t\t# gss-http\r\nacl Safe_ports port 591\t\t# filemaker\r\nacl Safe_ports port 777\t\t# multiling http\r\nacl Safe_ports port 631\t\t# cups\r\nacl Safe_ports port 873\t\t# rsync\r\nacl Safe_ports port 901\t\t# SWAT\r\nacl purge method PURGE\r\nacl CONNECT method CONNECT\r\nacl users proxy_auth REQUIRED\r\nhttp_access allow manager localhost\r\nhttp_access deny manager\r\nhttp_access allow purge localhost\r\nhttp_access deny purge\r\nhttp_access deny !Safe_ports\r\nhttp_access deny CONNECT !SSL_ports\r\nhttp_access allow localhost\r\nhttp_access allow users\r\nhttp_access deny all\r\nicp_access allow localnet\r\nicp_access deny all\r\nhttp_port 3128\r\nhierarchy_stoplist cgi-bin ?\r\naccess_log /var/log/squid/access.log squid\r\ndebug_options ALL,1 33,8\r\nrefresh_pattern ^ftp:\t\t1440\t20%\t10080\r\nrefresh_pattern ^gopher:\t1440\t0%\t1440\r\nrefresh_pattern -i (/cgi-bin/|\\?) 0\t0%\t0\r\nrefresh_pattern (Release|Packages(.gz)*)$\t0\t20%\t2880\r\nrefresh_pattern .\t\t0\t20%\t4320\r\nacl shoutcast rep_header X-HTTP09-First-Line ^ICY.[0-9]\r\nupgrade_http0.9 deny shoutcast\r\nacl apache rep_header Server ^Apache\r\nbroken_vary_encoding allow apache\r\nextension_methods REPORT MERGE MKACTIVITY CHECKOUT\r\nhosts_file /etc/hosts\r\nforwarded_for off\r\ncoredump_dir /var/spool/squid\r\n```\r\n- [ ] Configure a machine (Windows 7 or higher) so that it's joined to the same domain, and change the internet settings to use the squid proxy that is configured on your debian host on port `3128`\r\n- [ ] Using IE, make sure that you can browse to websites via the proxy. If you can't, you might need to configure the VM to automatically pass username/password to any site.\r\n\r\nWith all of that in place, you should have a scenario where the target user is configured to use a proxy that requires NTLM authentication and only supports HTTP `1.0`. Assuming that's the case:\r\n\r\n- [ ] Create listeners for TCP, HTTP and HTTPS. It's important that HTTPS is on `8443` as the Squid configuration above allows SSL on this port.\r\n- [ ] Create new payloads for x86 and x64 for `reverse_http` and `reverse_https`, both staged and stageless.\r\n\r\nFor each payload:\r\n- [ ] Make sure that you receive a valid connection.\r\n- [ ] Make sure that new transports for HTTP and HTTPS can be added and that they function when you switch to them.\r\n- [ ] Make sure that migration works still.\r\n\r\nAlso make sure that cases where this obscure proxy configuration _isn't_ in place still actually behaves by doing all the same stuff on a machine that doesn't have the proxy configured this way.\r\n\r\nPhew!\r\n\r\nApologies to the port b\\*st\\*rd that has to land this. Ping @Loki1980, I'd appreciate it if he could take a look at this as well as I know he has this environment already set up. Ping @zeknox as I know he's had this issue recently and perhaps he'd be keen to test this in that environment as well. If anyone needs binaries I'm happy to build them.\r\n\r\nThanks to everyone for the reports and the help with reproducing the problem. I hope that this fallback to WinInet in this case will resolve the last of the proxy issues we've been having so far."},"comment":{"url":"https://api.github.com/repos/rapid7/metasploit-payloads/issues/comments/119828425","html_url":"https://github.com/rapid7/metasploit-payloads/pull/5#issuecomment-119828425","issue_url":"https://api.github.com/repos/rapid7/metasploit-payloads/issues/5","id":119828425,"user":{"login":"OJ","id":28896,"avatar_url":"https://avatars.githubusercontent.com/u/28896?v=3","gravatar_id":"","url":"https://api.github.com/users/OJ","html_url":"https://github.com/OJ","followers_url":"https://api.github.com/users/OJ/followers","following_url":"https://api.github.com/users/OJ/following{/other_user}","gists_url":"https://api.github.com/users/OJ/gists{/gist_id}","starred_url":"https://api.github.com/users/OJ/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OJ/subscriptions","organizations_url":"https://api.github.com/users/OJ/orgs","repos_url":"https://api.github.com/users/OJ/repos","events_url":"https://api.github.com/users/OJ/events{/privacy}","received_events_url":"https://api.github.com/users/OJ/received_events","type":"User","site_admin":false},"created_at":"2015-07-09T05:52:02Z","updated_at":"2015-07-09T05:52:02Z","body":"Thanks Brent. Hopefully the instructions were useful, I know that setting it up was the worst part of the work for me! Cheers for looking into it."}}