MSCHAP-V2 authentication broken for PPTP VPN (logs included)

This bug is probably related to these two, but I have logs and “proofs”, so I wanted to separate it:

Basically, it’s about setting up a PPTP VPN client using MSCHAP-V2 authentication method (the first linked issue is about setting up VPN server, and the findings are the same; that’s why I conclude there’s something rotten in the authentication code itself). When I use the same credentials and use the CHAP protocol, I can connect (so the problem’s not in other unrelated parts).

I did an experiment with a VPN server on my XBian machine in the remote network. I tried to connect to this server first from my Windows machine (which works), and then using the client in Omnia (which does not work). Then I saved and compared the (server-side) logs (pptp.good.csv (7.1 KB) from the Windows connection, and pptp.bad.csv (6.9 KB) from Omnia; they’re not CSV files, but the forum forced me to fake the extension, sorry). Both attempts were made with username “test” and password “password”.

From the logs, it is apparent the connection sequence is almost identical up to the point where the client computes the authentication response. So I digged further. In short, I haven’t found the cause. But I’ve “convicted” Omnia from computing wrong auth response.

I’ve hacked a program that is able to do the same computations the authentication code should do. It’s published at Release Test · peci1/asleap · GitHub . I’ve verified the program works both on the RFC example and several successful Windows connections (most notably on the attached log file from Windows).

The program reports “Result is 0” when the client-computed auth response is correct, and “Result is 1” if it is wrong (given the username, password, and server and client challenge strings).

Here’s the result from the Windows connection:

$ ./asleap -B f9aafa086f8d21d6abc66f93baa67194 -A e4aa4e82f4f36f734bf825c997d2d517 -R c16ae55a4c5d0a25eb9229127c1e4b5180aaed33f912238e -U test -P password

asleap 2.2 - actively recover LEAP/PPTP passwords. <>
        challenge:         48f80b60f5aa72ea
        given hash 1:      c16ae55a4c5d0a25
        response hash 1:   c16ae55a4c5d0a25
        given hash 2:      eb9229127c1e4b51
        response hash 2:   eb9229127c1e4b51
        username:          test
        auth challenge:    f9aafa086f8d21d6abc66f93baa67194
        peer challenge:    e4aa4e82f4f36f734bf825c997d2d517
        peer response:     c16ae55a4c5d0a25eb9229127c1e4b5180aaed33f912238e
        password hash:     8846f7eaee8fb117ad06bdd830b7586c
Result is 0

And this one is from the Omnia connection:

$ ./asleap -B bd6afd22d13cde6bf4cc42d1f284d2fd -A e01e84355ea3520f6d41b2f21643aee9 -R ee015aea6fefd54cee015aea6fefd54cee015aea6fefd54c -U test -P password

asleap 2.2 - actively recover LEAP/PPTP passwords. <>
        challenge:         ee015aea6fefd54c
        given hash 1:      9aee403eb4204cb7
        response hash 1:   ee015aea6fefd54c
        username:          test
        auth challenge:    bd6afd22d13cde6bf4cc42d1f284d2fd
        peer challenge:    e01e84355ea3520f6d41b2f21643aee9
        peer response:     ee015aea6fefd54cee015aea6fefd54cee015aea6fefd54c
        password hash:     8846f7eaee8fb117ad06bdd830b7586c
Result is 1

I’m sorry the output of this program looks so messy, but I just quickly hacked it. Auth challenge (CLI option -B) is what’s sent by the server in the “CHAP Challenge” packet. Peer challenge (CLI option -A) are the first 16 chars from “CHAP Response”. These are randomly generated. Peer response (CLI option -R) are the last 48 chars from the end of “CHAP Response” with last two zeros excluded (or in machine-like language echo $CHAP_RESPONSE | tail -c50 | head -c48).

I think it’s now apparent that either Omnia computes the response wrongly, or uses (somehow) wrong password. The last thing I managed is to capture the command-line which is launched when the VPN connection is brought up:

/usr/sbin/pppd nodetach ipparam vpn1 ifname pptp-vpn1 +ipv6 set AUTOIPV6=1 nodefaultroute usepeerdns maxfail 1 user test password password ip-up-script /lib/netifd/ppp-up ipv6-up-script /lib/netifd/ppp-up ip-down-script /lib/netifd/ppp-down ipv6-down-script /lib/netifd/ppp-down mtu 1490 mru 1490 plugin pptp_server XXX file /etc/ppp/options.pptp

Now I’m in the end of my kung-fu. The password seems to be passed correctly to pppd (and, of course, I’ve also tried the whole setup with different passwords). I somehow can’t imagine pppd would contain such a bug nobody would notice in the 2 years since last version came out.

Did you do some Omnia-specific modifications to pppd? Or to some libraries pppd depends on? Or can’t there be some UTF-8/multibyte hell happening on the way?

1 Like

This bug has been fortunately fixed in Turris OS 3.5 (both for VPN client and server).