what-vpn icon indicating copy to clipboard operation
what-vpn copied to clipboard

AnyLink

Open DimitriPapadopoulos opened this issue 1 year ago • 14 comments

Have you heard of AnyLink? It appears to be compatible with the OpenConnect server, written in Go.

I am not sure whether it requires a new category or falls in the existing ocserv/AnyConnect category.

@itviewer was kind enough to set up a test server for a very limited time: https://gitlab.com/openconnect/ocserv/-/merge_requests/331#note_1348026291

DimitriPapadopoulos avatar Apr 11 '23 20:04 DimitriPapadopoulos

Output of sudo openconnect -u test tlslink.com:4433 -v -v -v -v --dump-http-traffic: tlslink.log

DimitriPapadopoulos avatar Apr 11 '23 20:04 DimitriPapadopoulos

Looks like the test server has already been taken down.

Output of sudo openconnect -u test tlslink.com:4433 -v -v -v -v --dump-http-traffic: tlslink.log

Cool. Did you also actually test what what-vpn -kv tlslink.com:4443 shows?

I am not sure whether it requires a new category or falls in the existing ocserv/AnyConnect category.

It basically speaks the same protocol, right? Wherever possible I try to make sure that what-vpn uses details of the protocol that would be unlikely to be repeated/echoed inadvertently on a different type of TLS/HTTPS server.

Should be pretty trivial to distinguish AnyLink responses from Cisco or ocserv, given that it's open-source. https://github.com/dlenski/what-vpn/blob/master/what_vpn/sniffers.py#L130-L175

dlenski avatar Apr 11 '23 23:04 dlenski

I didn't try what-vpn -kv tlslink.com:4443. HTTP headers might help distinguish AnyLink: https://github.com/bjdgyc/anylink/blob/b84d10d64f098716c6dd5fd26d77e955dbc0f095/server/handler/link_base.go#L47

But then do we want to distinguish between AnyLink and AnyConnect/OpenConnect or not?

@itviewer Could you perhaps extend the text account on tlslink.com for a few days?

DimitriPapadopoulos avatar Apr 12 '23 05:04 DimitriPapadopoulos

@DimitriPapadopoulos the account has been enabled again, info same as https://gitlab.com/openconnect/ocserv/-/merge_requests/331#note_1348026291

itviewer avatar Apr 12 '23 06:04 itviewer

Thanks. It just occurred to me, we don't need an account to query the server with what-vpn. We just need the server to be up. Any way, the account and the verbose log might help nevertheless in the future. For now, the server goes undetected, perhaps because it bans web browsers:

$ what-vpn -kv tlslink.com:4433

Sniffing tlslink.com:4433 ...
  Is it AnyConnect/OpenConnect? no match
  Is it Juniper/Pulse? no match
  Is it Juniper Secure Connect? no match
  Is it PAN GlobalProtect? no match
  Is it Barracuda? no match
  Is it Check Point? no match
  Is it SSTP? no match
  Is it OpenVPN? no match
  Is it Fortinet? no match
  Is it Array Networks? no match
  Is it F5 BigIP? no match
  Is it SonicWall NX (formerly Dell)? no match
  Is it Aruba VIA? no match
  Is it H3C TLS VPN? no match
  => no match

We might have to modify the user-agent string.

DimitriPapadopoulos avatar Apr 12 '23 06:04 DimitriPapadopoulos

@DimitriPapadopoulos https://github.com/bjdgyc/anylink/blob/4d15fe286a366916b975722be84d94595d89b5ac/server/handler/link_auth.go#L29

if !((strings.Contains(userAgent, "anyconnect") || strings.Contains(userAgent, "openconnect") || strings.Contains(userAgent, "anylink")) &&
		xAggregateAuth == "1" && xTranscendVersion == "1") {
		w.WriteHeader(http.StatusForbidden)
		fmt.Fprintf(w, "error request")
		return
	}

itviewer avatar Apr 12 '23 06:04 itviewer

@DimitriPapadopoulos https://github.com/bjdgyc/anylink/blob/4d15fe286a366916b975722be84d94595d89b5ac/server/handler/link_auth.go#L29

if !((strings.Contains(userAgent, "anyconnect") || strings.Contains(userAgent, "openconnect") || strings.Contains(userAgent, "anylink")) &&
		xAggregateAuth == "1" && xTranscendVersion == "1") {
		w.WriteHeader(http.StatusForbidden)
		fmt.Fprintf(w, "error request")
		return
	}

Sorry, that is for client authentication check, if you use browser, see here https://github.com/bjdgyc/anylink/blob/4d15fe286a366916b975722be84d94595d89b5ac/server/handler/link_home.go#L19

itviewer avatar Apr 12 '23 06:04 itviewer

and here for web server routing https://github.com/bjdgyc/anylink/blob/4d15fe286a366916b975722be84d94595d89b5ac/server/handler/server.go#L80

itviewer avatar Apr 12 '23 06:04 itviewer

Well, if the server explicitly varies its behavior for certain user-agent header values, that makes for a pretty trivial way to distinguish it from other servers :stuck_out_tongue_closed_eyes:

dlenski avatar Apr 12 '23 18:04 dlenski

Indeed, we can easily distinguish it. Do you want to distinguish it in the what-vpn output, given that they share the same protocol?

I don't know how feasible it would be to distinguish ocserv and AnyConnect, but you don't distinguish them it in the what-vpn output.

DimitriPapadopoulos avatar Apr 12 '23 20:04 DimitriPapadopoulos

Indeed, we can easily distinguish it. Do you want to distinguish it in the what-vpn output, given that they share the same protocol?

Yes. The goal of what-vpn is basically to output:

  1. This is a TLS-based VPN server that speaks protocol X (with as much confidence as possible)
  2. If possible to determine, what version/flavor/product/variant is the server?
  • Many servers don't explicitly volunteer this, likely for security reasons, but in some cases like AnyConnect-vs-ocserv it's pretty straightforward to find reliable distinguishers anyway.
  1. If possible, what else can we say about the components or requirements of the server?
  • This is a lot fuzzier and more protocol-dependent… search for component to find examples.

I don't know how feasible it would be to distinguish ocserv and AnyConnect, but you don't distinguish them it in the what-vpn output.

:question:

Yes it does, certainly tries very hard to (https://github.com/dlenski/what-vpn/blob/master/what_vpn/sniffers.py#L154-L175), including taking advantage of a bug/mistake in older ocserv’s HTTP responses to pinpoint the specific version :nerd_face:

dlenski avatar Apr 12 '23 21:04 dlenski

I see a single line for AnyConnect/OpenConnect matches (it's the same sniffer):

$ what-vpn vpn.colorado.edu
vpn.colorado.edu: AnyConnect/OpenConnect (Cisco)

In the case of a match, you get details on the matching (Cisco). My question was, do we want the same sniffer / line in output? I guess the answer is yes. Typically we would have:

$ what-vpn tlslink.com:4433
tlslink.com:4433: AnyConnect/OpenConnect (AnyLink)

DimitriPapadopoulos avatar Apr 12 '23 22:04 DimitriPapadopoulos

My question was, do we want the same sniffer / line in output? I guess the answer is yes. Typically we would have:

$ what-vpn tlslink.com:4433
tlslink.com:4433: AnyConnect/OpenConnect (AnyLink)

Yes, I think that would make sense. :+1:

Perhaps the Hit() object should have an explicit protocol attribute that says "the server speaks protocol X". I originally thought there would be a 1:1 mapping of "sniffers" to "VPN protocols", but there are already exceptions: the juniper_pulse sniffer will detect…

  1. (Ancient) servers that only speak the Juniper/NC/oNCP protocol.
  2. (Most modern) servers that speak both the Juniper/Junos/Ivanti Pulse protocol and the old Juniper protocol.
  3. (Some modern) servers that speak the the Juniper/Junos/Ivanti Pulse protocol but have the old Juniper protocol intentionally disabled.

dlenski avatar Apr 12 '23 23:04 dlenski

The main page of the server returns:

AnyLink 是一个企业级远程办公 SSL VPN 软件,可以支持多人同时在线使用。

It roughly translates to:

Enterprise-level remote office SSL VPN software that supports multiple simultaneous users.

DimitriPapadopoulos avatar May 06 '23 13:05 DimitriPapadopoulos