adrienverge / openfortivpn

Client for PPP+TLS VPN tunnel services
GNU General Public License v3.0
2.7k stars 320 forks source link

String "SV1" in User-Agent causes HTTP status 405 #409

Closed mss closed 5 years ago

mss commented 5 years ago

In #408 I announced that I'd open a new pull request to fix this issue but I even though the solution looks simple I'm not sure about the correct approach.

TL;DR: This is a special case of #366: There are versions of FortiGate (I guess) which respond with a 405 status code if the User-Agent header contains the string SV1. I'd just drop this string but maybe there are other versions which expect it?

The request looks like this:

POST /remote/logincheck HTTP/1.1
Host: vpn.example.com:443
User-Agent: Mozilla/5.0 SV1
Accept: text/plain
Accept-Encoding: identity
Content-Type: application/x-www-form-urlencoded
Cookie:
Content-Length: 92

username=USERNAME&credential=PASSWORD%23&realm=&ajax=1&redir=%2Fremote%2Findex&just_logged_in=1

and will receive a response like this:

HTTP/1.1 405 Method Not Allowed
Date: Fri, 07 Dec 2018 13:29:10 GMT
Server: xxxxxxxx-xxxxx
Set-Cookie:  SVPNCOOKIE=; path=/; expires=Fri, 07-Dec-2018 13:29:10 GMT; secure; httponly;
Set-Cookie: SVPNNETWORKCOOKIE=; path=/remote/network; expires=Fri, 07-Dec-2018 13:29:10 GMT; secure; httponly
Transfer-Encoding: chunked
Content-Type: text/html
X-Frame-Options: SAMEORIGIN
Content-Security-Policy: frame-ancestors 'self'
X-XSS-Protection: 1; mode=block

[Some HTML here]

I played around with the User-Agent header and something like Mozilla/5.0 (SV1) and also Mozilla/5.0 (SV2) will still receive a 405 but no body (wtf?) while something like Mozilla/5.0 (Linux) Gecko/20100101, Mozilla/5.0 SV9 or even just Mozilla/5.0 will get a proper status 200.

mss commented 5 years ago

The history of the string SV1 in User-Agent goes right back to the initial commit 171cebae7db0c0dbd5d0609c2d4a52ed98a05182 aka v1.0.0 — is there some older history?

I think just dropping that string and introducing a config option if that doesn't work for some people would be the right approach.

DimitriPapadopoulos commented 5 years ago

For what it's worth the official FortiClient seems to be sending User-Agent: Mozilla/5.0 SV1, at least usually. It might send Mozilla/5.0 (Mac OS X) in other cases. Just wondering, does this depend on the FortiGate version only, or on the settings too? For example MacOS clients only, etc.

mss commented 5 years ago

Unfortunately I have no idea what kind of device is in use since I am just a user.

mss commented 5 years ago

I intercepted the authentication flow of the Windows client available at https://forticlient.com via mitmproxy and got the User-Agent header value Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) [SV{v=01.01;}].

The interesting thing is that that client will receive an 405 as well. But afterwards the client will continue with a few more requests. The whole flow looks like this:

The only point where the credentials are transmitted (probably since the body seems to be obfuscated with some salt from the first request) is the POST though. So maybe 405 is a standard response for wrong credentials? The password I received doesn't work yet so I will have to try again when I get working credentials.

mss commented 5 years ago

I now got valid credentials and it looks like this is actually intended behaviour! With the correct credentials I can connect properly; with the wrong credentials and the string SV1 or SV2 in the User-Agent both this client an the official FortiClient will get a 405. Without that string, you get a proper (at least for this odd kind of SSL VPN) error.

FWIW, according to /remote/fortisslvpn_xml which is called later on successful login this is <fos platform='FG900D' major='5' minor='06' patch='3' build='1547' branch='1547' />.

mrbaseman commented 5 years ago

@mss thanks for reporting and analyzing this.