BishopFox / sliver

Adversary Emulation Framework
GNU General Public License v3.0
8.26k stars 1.09k forks source link

C2 Perscriptive Ordering #790

Open DominicBreuker opened 2 years ago

DominicBreuker commented 2 years ago

Describe the bug When I set up an HTTP Squid proxy (local network, no HTTPS) in Windows 10, manual configuration, then Windows only accepts IP and port. The implant detects the proxy as a WinHTTP:NamedProxy and since no scheme is found, it defaults to HTTPS (code). Thus, it cannot connect, even though the proxy otherwise works perfectly.

To Reproduce Steps to reproduce the behavior:

  1. Get a Linux VM and configure a Squid proxy (I've used Squid 4.13)
  2. Get a Windows VM and configure the Squid VM as a manual HTTP proxy
  3. Get a Linux VM and run the Sliver server (I've used Sliver 1.5.16)
  4. Generate and deliver an HTTP implant to Windows VM (e.g., generate beacon --http 192.168.1.10 --debug --save /tmp/beacon.exe --seconds 5 --jitter 0 --os windows)
  5. Execute the implant and you will not get a session. The debug log will show two attempts to connect via the proxy with HTTPS, and it complains about the TLS handshake error. The Squid proxy logs will show error:invalid-request.

Expected behavior The implant should try both HTTP and HTTPS for the proxy URL if the scheme is not specified

Screenshots A screenshot of what the error looks like:

proxyerror

Desktop (please complete the following information):

Additional context I've PoCed a fix for this, will open a PR and link it here

moloch-- commented 2 years ago

The go http client makes a best effort to identify the proxy settings, you probably want to use the wininet driver to strictly adhere to the Windows system proxy settings, which is enabled via the advanced c2 options.

DominicBreuker commented 2 years ago

Yep that would probably work. I wondered though how I could know that upfront and if it would make sense to have the implant try all kinds of different options if I don't know them in advance? https://github.com/BishopFox/sliver/pull/791 would be my take on that.

moloch-- commented 2 years ago

So for the Go http library we use a modified go get proxied library located here in the code base: https://github.com/BishopFox/sliver/tree/master/implant/sliver/proxy

Which currently does employ multiple methods of identifying the proxy settings, complexities typically arise from authenticated proxies and quirks in Windows internal APIs, which is we recommend switching to wininet. However, wininet requires a lot of juggling back and forth between Go types and native C types, making it a little less stable than the Go http implementation. The wininet calls are also easier for security products to intercept and examine traffic so the Go http client is the default.

DominicBreuker commented 2 years ago

hmmm ok so I guess I could then probably just list different HTTP connection strings when generating the implant to make it try diffrent options one after another. E.g., generate beaon ... --http 192.168.122.111 --http 192.168.122.11?driver=wininet .... I think I got that now. Thx! :)

moloch-- commented 2 years ago

Yeap! There's for sure improvements we can still make to this, so feel free to send us PRs still. You can also force proxy settings via the c2 advanced options for the go http client in one of your connection strings.

For example, something like:

generate beaon ... --http 192.168.122.111?proxy=http://10.10.10.10:8080,192.168.122.11?driver=wininet ...
cmprmsd commented 2 years ago

@DominicBreuker I think your command should be: generate beaon ... --http 192.168.122.111,192.168.122.11?driver=wininet <- with comma in one argument else only the last occurence of --http will be used. I also stumbled over this behavior :grin:

moloch-- commented 2 years ago

Yea we need to find a way to have better UX around this feature.

cmprmsd commented 2 years ago

It's quite usable. You just have to know it. So it might be enough to make the docs clearer (in the client -h).

The more confusing thing is the connection strategy that you can't change arbitrarily by ordering your arguments.

E.g. --http --mtls --wg still calls first mtls, then wg then http,based on the performance of these protocols. However it would be clearer to have the --strategy=hmwd to tell the order of protocols.

DominicBreuker commented 2 years ago

for me personally it would be most intuitive if C2 endpoints were tried in the same order as they are specified. no need for a special argument. thx for the hint with the , btw!

cmprmsd commented 2 years ago

You're welcome :) I also thought the ordering would be that way. However, i guess that's because grumble does not allow multiple occurrences of an argument.

moloch-- commented 2 years ago

for me personally it would be most intuitive if C2 endpoints were tried in the same order as they are specified. no need for a special argument. thx for the hint with the , btw!

I think this is generally how I'd expect it to work too, and we can implement it this way it just requires a bit extra parsing of the raw args as grumble doesn't supply us with the order of the arguments after they're lexically parsed

Tru5tNo1 commented 6 months ago

I've encountered the same issue. In various situations (personally all of them), I've come across HTTP proxies and not HTTPS... the detection occurs correctly though it happens correctly. In many activities conducted, it seemed forced to set the name of the proxy server in advance, during the Beacon generation phase. What do you think?