Gilks / hostscan-bypass

Generate OpenConnect CSD files to bypass Cisco AnyConnect hostscan requirements
247 stars 46 forks source link

Doesn't work with TLS_RSA_WITH_AES_256_CBC_SHA256 cipher #6

Closed porjo closed 4 years ago

porjo commented 4 years ago

Not a bug, just an FYI for others.

Go dropped support for cipher TLS_RSA_WITH_AES_256_CBC_SHA256 here.

My anyconnect provider has locked their endpoint to only accept this cipher, and so I get a TLS negotiation failure when attempting to connect :cry:

Gilks commented 4 years ago

Interesting. At first glance, it doesn't look like they actually removed the ciphers. It appears they simply disabled them by default. That means this should be fixable!

A fix to this problem would likely be just figuring out how to explicitly enable the needed cipher in the go code.

Are you able to provide the exact error message you are referring to?

On Sun, Oct 13, 2019, 7:52 PM Ian Bishop notifications@github.com wrote:

Not a bug, just an FYI for others.

Golang dropped support for cipher TLS_RSA_WITH_AES_256_CBC_SHA256 here https://go-review.googlesource.com/c/go/+/35290/.

My anyconnect provider has locked their endpoint to only accept this cipher, and so I get a negotiation failure :(

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/Gilks/hostscan-bypass/issues/6?email_source=notifications&email_token=ACUP4TKVFZEBQYHJH62NJX3QOOYENA5CNFSM4JAJEYBKYY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4HRPBLAQ, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACUP4TM2OL3VTTPENTFR273QOOYENANCNFSM4JAJEYBA .

porjo commented 4 years ago

The error I get when connecting to the Anyconnect endpoint is: tls: handshake failure

Nmap scan of the endpoint shows this:

$ nmap --script ssl-enum-ciphers <endpoint> -p 443
Starting Nmap 7.80 ( https://nmap.org ) at 2019-10-14 11:33 AEST
Nmap scan report for <endpoin>t (x.x.x.x)
Host is up (0.037s latency).

PORT    STATE SERVICE
443/tcp open  https
| ssl-enum-ciphers: 
|   TLSv1.2: 
|     ciphers: 
|       TLS_RSA_WITH_AES_256_CBC_SHA256 (rsa 2048) - A
|     compressors: 
|       NULL
|     cipher preference: indeterminate
|     cipher preference error: Too few ciphers supported
|     warnings: 
|       Forward Secrecy not supported by any cipher
|_  least strength: A

I tried this:

func handleConnection(conn net.Conn, isTLS bool, hostscan Hostscan) {
[...]
                conf := tls.Config{
                        InsecureSkipVerify: true,
                        CipherSuites:       []uint16{tls.TLS_RSA_WITH_AES_256_CBC_SHA256},
                }

but get compile error: ./hostscan-bypass.go:133:33: undefined: tls.TLS_RSA_WITH_AES_256_CBC_SHA256

Gilks commented 4 years ago

I don't see TLS_RSA_WITH_AES_256_CBC_SHA256 in the list of ciphers at all. I can't find evidence that golang ever had support for this specific cipher! How strange.

After some digging around it appears someone else added support for TLS_RSA_WITH_AES_256_CBC_SHA256 in a PR. It never looks like it was merged though. If you use the version of golang from this repository you may have some luck.

porjo commented 4 years ago

I can't find evidence that golang ever had support for this specific cipher!

You're right - I misread that earlier commit! Thanks, I'll check out that other repo. UPDATE: that repo fails to build :disappointed:

Gilks commented 4 years ago

Hmm.. Well, I can't exactly test this idea but I don't see many changes in the commit that adds support for the TLS_RSA_WITH_AES_256_CBC_SHA256 cipher. Here's my attempt at trying to integrate it to the current version of golang using that commit.

I'd make a backup of the current ciphers_suites.go file and then copy this modified one into its place.. Fingers crossed that it works.

porjo commented 4 years ago

I tried building go with your file but it fails. What version of Go did you base that off? I followed the build instructions here https://golang.org/doc/install/source which uses 1.13.1

Gilks commented 4 years ago

I made an assumption I was on the latest version when in fact I was on version 1.12.9. I updated to version 1.31.1 and replaced cipher_suites.go with my modified version and received the following error when attempting to run the bypass:

/usr/local/go/src/crypto/tls/cipher_suites.go:18:2: cannot find package "internal/x/crypto/chacha20poly1305" in any of:
    /usr/local/go/src/vendor/internal/x/crypto/chacha20poly1305 (vendor tree)
    /usr/local/go/src/internal/x/crypto/chacha20poly1305 (from $GOROOT)
    /root/go/src/internal/x/crypto/chacha20poly1305 (from $GOPATH)

Here's the version of cipher_suites.go for golang 1.13.1. Sorry about that, I should have checked my version before claiming I was on the latest.

porjo commented 4 years ago

I tried again with the updated file. Compilation succeeds, however the test suite fails. Using the resulting go binary I've was able to compile hostscan-bypass and run it. This time it connects to the server, and I can see hexdumps of client traffic, however it doesn't complete and my client just sits at the 'enter your username and password' prompt. The client traffic is missing the endpoint string and hostscan-bypass never exits. Here's the (redacted) console output: https://pastebin.com/VjRt9U53

Gilks commented 4 years ago

That's odd. I'd assume if the SSL handshake went poorly that the connection would abort..

Are you using the hostscan-bypass from the git repo or are you working on a modified version?

EDIT: Also, are you seeing the AnyConnect client perform a posture assessment upon connection? The client is supposed to perform a GET /CACHE/sdesktop/install/binaries/update.txt right after it starts hanging for you.

Go to func handleServerMessage(...) and uncomment fmt.Printf("From Server [%d]:\n%s\n", id, hex.Dump(data[:n])) and try running it again. Maybe the server is responding with something that can give us a hint.

porjo commented 4 years ago

hostscan-bypass is from the git repo and unchanged except for the cipher modification and uncommenting printf lines.

I've emailed you the console output which includes server messages.

Gilks commented 4 years ago

Thank you for the log file! Looking over the log file you sent me I don't see any indication of hostscan being used in your environment. Are you sure your organization is using hostscan? You should see the following text should be visible when connecting with your AnyConnect client.

You could also try browsing to the following URL to see if there's any hostscan requirements being published.

https://<VPN Page>/CACHE/sdesktop/data.xml

porjo commented 4 years ago

You're right - it seems that no hostscan is required. Using hostscan-bypass to simply proxy traffic from my Linux openconnect client allowed me to connect succesfully! (I'd never tried this combination until now, thinking the issue was with hostscan and needing the CSD wrapper). The problem I have now is that hostscan-bypass consumes 100% cpu after connect and I doesn't pass traffic - I guess it wasn't intended to be a general purpose proxy :smile: I'll have a play with it and see what can be done. Thanks for your help!

Gilks commented 4 years ago

That's correct- the bypass was never intended to be a general purpose proxy. By the sounds of it you don't need the hostscan-bypass at all. You should just be able to use openconnect and connect directly to the network. Something like this:

openconnect <VPN URL>

Or if your environment doesn't allow the use of Linux/OS X you could try:

openconnect <VPN URL> --os=win

Hostscan is a feature that companies use to lockdown which assets are "allowed" to connect to the VPN. That's when you would need to use the hostscan-bypass. It generates a CSD file to mimic a corporate assets connection to the network. If hostscan is not in use you are usually free and clear to connect to VPN with openconnect.

porjo commented 4 years ago

You should just be able to use openconnect and connect directly to the network

That fails to negotiate TLS (due to the missing cipher support - it would appear that Go is not the only client that doesn't support that unusual cipher!). I'm just using hostscan-bypass for now as a convenient way to bridge the gap in cipher support. I'll find another proxy that is more suited to that task.

Gilks commented 4 years ago

If that's true I'd recommend opening up an issue on the OpenConnect repository over on gitlab. The devs are very responsive and quite helpful. I'd reference this issue while opening a request to add support for the TLS_RSA_WITH_AES_256_CBC_SHA256 cipher.

You could use the hostscan-bypass as a general purpose proxy but wouldn't it be so much nicer to be able to VPN directly from your linux host into the network?

EDIT: I am going to close this issue. If you decide to open an issue with the OpenConnect devs- feel free to post the link back here! I wouldn't mind seeing what they have to say on this.

porjo commented 4 years ago

Good idea! I've created ticket here: https://gitlab.com/openconnect/openconnect/issues/83