Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C2 Perscriptive Ordering #790

Open
DominicBreuker opened this issue Aug 18, 2022 · 12 comments
Open

C2 Perscriptive Ordering #790

DominicBreuker opened this issue Aug 18, 2022 · 12 comments
Labels
enhancement New feature or request

Comments

@DominicBreuker
Copy link
Contributor

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):

  • OS: Sliver ran on Kali Linux, Squid on Debian, the Target was Windows 10

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

@moloch--
Copy link
Member

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
Copy link
Contributor Author

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? #791 would be my take on that.

@moloch--
Copy link
Member

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
Copy link
Contributor Author

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--
Copy link
Member

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
Copy link
Contributor

cmprmsd commented Aug 19, 2022

@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 😁

@moloch--
Copy link
Member

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

@cmprmsd
Copy link
Contributor

cmprmsd commented Aug 19, 2022

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
Copy link
Contributor Author

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
Copy link
Contributor

cmprmsd commented Aug 20, 2022

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--
Copy link
Member

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

@moloch-- moloch-- added the enhancement New feature or request label Aug 22, 2022
@moloch-- moloch-- changed the title HTTP proxy not correctly identified C2 Perscriptive Ordering Aug 22, 2022
@Tru5tNo1
Copy link

Tru5tNo1 commented Mar 5, 2024

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants