Introducción
GSM (Global System for Mobile Communications) (2G) es un estándar de comunicación desarrollado para la transmisión de voz y datos en redes móviles. Originalmente fue creado en Europa en los años 80 por el Instituto Europeo de Normas de Telecomunicaciones (ETSI) y se convirtió en el sistema de telefonía móvil más popular a nivel mundial, utilizado por la mayoría de operadores de redes móviles en el mundo. La tecnología GSM permite que los usuarios de diferentes operadores puedan comunicarse entre sí y utilizar servicios como SMS (mensajes de texto) o llamadas. Con la llegada de 4G y 5G, el uso de redes GSM ha disminuido y algunas operadoras están retirando gradualmente el soporte para estas redes.
La radiofrecuencia (RF) utilizada en GSM se encuentra en el rango de las ondas ultra-altas (UHF), específicamente entre 850 MHz y 1900 MHz. Hoy en día la más utilizada es la banda GSM-900 (880–960 MHz). Es posible capturar estas emisiones de las estaciones base y decodificarlas. Las comunicaciones entre las estaciones base y los dispositivos móviles se suelen encontrar cifradas por lo que únicamente será posible decodificar las emisiones públicas, como las que incluyen la identificación de la red o la lista de estaciones base cercanas. Podremos descifrar nuestras comunicaciones si disponemos de la clave de cifrado, la cual se encuentra guardada en un fichero de la tarjeta SIM (Subscriber Identity Module).
El software utilizado será GNURadio en su versión 3.10 junto a la biblioteca gr-gsm. Esta biblioteca es compatible hasta la versión 3.8 de GNURadio por lo que será necesario utilizar una adaptación creada por bkerler y parchear ciertos archivos para lograr la compatibilidad completa con las últimas versiones de GNURadio. Como sistema operativo utilizaremos Kali Linux, aunque este artículo es válido para cualquier distribución basada en Debian.
Como hardware cualquier radio definida por software (SDR) que sea capaz de recibir emisiones en la banda de los 900 MHz, como el RTL-SDR.
Instalación de gr-gsm y sus dependencias
Podemos instalar el paquete gr-gsm desde el gestor de paquetes predeterminado:
sudo apt install gr-gsm
En esta opción las funciones relacionadas con el guardado y cargado de archivos bursts no funcionan correctamente con GNURadio 3.10 y la biblioteca gr-gsm por lo que es necesario aplicar un parche compilando e instalando el programa desde el código fuente. Instalamos sus dependencias.
sudo apt install -y cmake autoconf libtool pkg-config build-essential python3-docutils libcppunit-dev swig doxygen liblog4cpp5-dev python3-scipy gnuradio-dev gr-osmosdr libosmocore-dev
A continuación clonamos el repositorio y nos movemos al directorio del proyecto.
git clone https://github.com/bkerler/gr-gsm/
cd gr-gsm
Ahora nos movemos a la carpeta lib/misc_utils que contiene los ficheros a descargar y modificar.
cd lib/misc_utils
Modificamos el archivo burst_file_source_impl.cc añadiendo una cabecera con la biblioteca a modificar pmt_serialize.cc. Añadimos #include "pmt_serialize.cc" debajo de la línea #include "stdio.h".
vi burst_file_source_impl.cc
A continuación descargamos los archivos pmt_serialize.cc y pmt_int.h desde el repositorio de GNURadio. Esta biblioteca se encarga de codificar datos de bursts para guardarlos en un archivo mediante su serialización, y de cargarlos mediante su deserialización.
wget https://github.com/gnuradio/gnuradio/raw/refs/heads/maint-3.10/gnuradio-runtime/lib/pmt/pmt_serialize.cc
wget https://github.com/gnuradio/gnuradio/raw/refs/heads/maint-3.10/gnuradio-runtime/lib/pmt/pmt_int.h
Luego modificamos el archivo pmt_serialize.cc con dos cambios.
vi pmt_serialize.cc
En primer lugar reemplazamos el código de la función deserialize_untagged_u32 en la línea 183 con el código siguiente (el código anterior se encuentra comentado).
/*
uint8_t buf[sizeof(uint32_t)];
std::streambuf::traits_type::int_type t;
t = sb.sgetn((char*)buf, sizeof(buf));
sb.pubseekoff(sizeof(uint32_t), std::ios_base::cur);
*ip = big_to_native_u32(buf);
return t != std::streambuf::traits_type::eof();
*/
std::streambuf::traits_type::int_type t;
int i;
t = sb.sbumpc();
i = t & 0xff;
t = sb.sbumpc();
i = (i << 8) | (t & 0xff);
t = sb.sbumpc();
i = (i << 8) | (t & 0xff);
t = sb.sbumpc();
i = (i << 8) | (t & 0xff);
*ip = i;
return t != std::streambuf::traits_type::eof();
En segundo lugar, reemplazamos el código dentro del switch (utag) y el caso UVI_U8 de la línea 681 con el siguiente código (el código anterior se encuentra comentado).
/*
deserialize_untagged_u8_vector(u8v, nitems, sb);
pmt_t vec = init_u8vector(nitems, &u8v[0]);
return vec;
*/
pmt_t vec = make_u8vector(nitems, 0);
for (uint32_t i = 0; i < nitems; i++) {
deserialize_untagged_u8(&u8, sb);
u8vector_set(vec, i, u8);
}
return vec;
Después, ya podemos movernos al directorio raíz del proyecto, compilar el proyecto e instalarlo.
cd ../..
mkdir build
cd build
cmake ..
mkdir $HOME/.grc_gnuradio/ $HOME/.gnuradio/
make -j16
sudo make install
sudo ldconfig
Escaneo del rango de frecuencias GSM-900
Con el programa instalado podemos iniciar con el escaneo de estaciones base GSM con la radio definida de software. En el caso de utilizar algunos RTL-SDR con osciladores TCXO de baja calidad necesitaremos hallar el valor PPM (partes por millón) ya que en estos casos la frecuencia sintonizada se desvía en cierta medida de la verdadera. La recepción de señales GSM requiere sincronizar a la frecuencia exacta. Para hallar este valor utilizaremos la herramienta kalibrate, que instalaremos.
sudo apt install kalibrate-rtl -y
Escaneamos la banda GSM-900 con la opción -s y encontramos varias estaciones base.
kal -s GSM900
Found 1 device(s):
0: Generic RTL2832U OEM
Using device 0: Generic RTL2832U OEM
Detached kernel driver
Found Rafael Micro R820T tuner
Exact sample rate is: 270833.002142 Hz
[R82XX] PLL not locked!
kal: Scanning for GSM-900 base stations.
GSM-900:
chan: 111 (957.2MHz + 3.007kHz) power: 24399.37
chan: 113 (957.6MHz + 2.684kHz) power: 30071.01
Debemos de anotar el canal con más potencia, en este caso el 113. Ahora escaneamos únicamente este canal con la opción -c.
kal -c 113
Found 1 device(s):
0: Generic RTL2832U OEM
Using device 0: Generic RTL2832U OEM
Found Rafael Micro R820T tuner
Exact sample rate is: 270833.002142 Hz
[R82XX] PLL not locked!
kal: Calculating clock frequency offset.
Using GSM-900 channel 113 (957.6MHz)
Tuned to 957.600000MHz (reported tuner error: 0Hz)
average [min, max] (range, stddev)
+ 2.648kHz [2600, 2699] (99, 427.253452)
overruns: 0
not found: 11
average absolute error: 42.765 ppm
Encontramos un valor de PPM de 42.765, que redondeamos a 43. Ahora ya podemos escanear todas las estaciones base utilizando la herramienta gsgsm_scanner con las opciones -b para especificar la banda, el valor PPM con -p, la ganancia máxima del receptor con -g y la velocidad de escaneo más rápida --speed 29.
grgsm_scanner -b GSM900 -p 43 -g 30 --speed 29
...
Scanning: 0.00% done..
Reattached kernel driver
...
ARFCN: 975, Freq: 925.2M, CID: XXXX, LAC: XXXXX, MCC: 214, MNC: 3, Pwr: -43
ARFCN: 977, Freq: 925.6M, CID: XXXX, LAC: XXXXX, MCC: 214, MNC: 3, Pwr: -34
ARFCN: 978, Freq: 925.8M, CID: XXXX, LAC: XXXXX, MCC: 214, MNC: 3, Pwr: -27
ARFCN: 992, Freq: 928.6M, CID: XXXX, LAC: XXXXX, MCC: 214, MNC: 3, Pwr: -43
ARFCN: 984, Freq: 927.0M, CID: XXXX, LAC: XXXXX, MCC: 214, MNC: 3, Pwr: -43
...
Entre las celdas encontradas, podemos tomar el valor de la celda con más potencia, en este caso la de número de canal (ARFCN) 978 y frecuencia 925.8MHz.
Monitorización de canal C0
Con la herramienta grgsm_livemon y grgsm_livemon_headless podemos monitorizar el canal C0 de la estación base GSM. Con la primera herramienta tenemos acceso a una interfaz gráfica donde podemos cambiar la frecuencia y con la segunda herramienta no se crea una interfaz gráfica. Utilizamos los valores de la frecuencia -f, la ganancia -g y el valor PPM -p.
grgsm_livemon -f 925.8M -g 30 -p 43
Se imprimirán por pantalla las diferentes tramas si son decodificadas. Podremos decodificarlas utilizando Wireshark, monitorizando por -f paquetes UDP con el filtro -Y gsmtap en la interfaz -i lo.
wireshark -k -f udp -Y gsmtap -i lo
Encontramos mensajes, como los System Information que se envían por el canal BCCH (Broadcast Control Channel), que difunde información general de la célula, como el identificador de la célula y la red, y la lista de frecuencias vecinas. O por el CCCH, como el Paging Request Type 1, que notifica al dispositivo móvil cuando hay una llamada entrante o un SMS para que responda en el canal de acceso.
Grabado de la banda base de una celda en un archivo
Con la herramienta grgsm_capture podemos guardar la banda base de la señal para su posterior análisis. Especificaremos la frecuencia -f, la ganancia -g, la tasa de muestreo -s, en este caso 250k ya que solo vamos a capturar una celda. Especificamos el valor PPM -p y finalmente el nombre del archivo.
grgsm_capture -f 925.8M -g 30 -s 250k -p 30 -T 5 9258_recording
Grabado de la banda base de varias celdas en un archivo
También es posible capturar con la herramienta grgsm_capture un área más amplia del especto, con una tasa de muestreo -s 2.0M para capturar varias celdas que se encuentren próximas. Luego se podrá utilizar la herramienta grgsm_channelize para dividir el archivo en cada celda individualizada. Especificaremos con el parámetro -i el archivo con la captura y con el parámetro -f la frecuencia central, en este caso 925.6MHz, junto a la tasa de muestreo de salida -o. Finalmente especificaremos los números de canal (ARFCNs) de las celdas deseadas, en este caso la de la frecuencia 925.2MHz (975), 925.6MHz (977) y 925.8MHz (978).
grgsm_capture -f 925.8M -g 30 -s 2.0M -p 30 9258_recording.bin
grgsm_channelize -s 2.0M -f 925.8M -o 250k -i 9258_recording.bin 975 977 978
Obtenemos en la carpeta 9258_recording los archivos out_975.cfile, outfile_977.cfile y outfile_978.cfile.
ls -1 9258_recording
out_975.cfile
out_977.cfile
out_978.cfile
Decodificación de las capturas
Con la herramienta grgsm_decode podemos decodificar y descifrar la capturas de banda base y de bursts. Los archivos bursts son otro tipo de captura que solamente captura las ráfagas demoduladas con los datos sin decodificar de la estación base y no de toda la banda base. En este caso especificaremos el canal con -m. Podemos decodificar el canal BCCH (de señalización), BCCH_SDCCH4 o SDCCH8 (de control), o los de tráfico TCHF o TCHH.
También especificaremos el intervalo de tiempo con -t (del 0 al 7, ya que GSM usa TDMA, lo cual permite que varios usuarios compartan el mismo canal de frecuencia dividiendo el tiempo de transmisión en intervalos). Especificamos el archivo con la captura con -c junto a su ARFCN con -a y su tasa de muestreo -s. Los paquetes podrán ser observados con Wireshark como anteriormente.
grgsm_decode -m BCCH_SDCCH4 -t 0 -c 9258_recording/out_975.cfile -a 975 -s 250k
grgsm_decode -m SDCCH8 -t 0 -c 9258_recording/out_975.cfile -a 975 -s 250k
En este caso encontramos paquetes sin identificar, ya que se encuentran cifrados y van dirigidos a un dispositivo móvil en concreto. En el caso de que las llamadas no estén cifradas podremos buscar en todos los intervalos por el canal TCHF o TCHH para guardar la llamada en un archivo de audio con el codec GSM con la opción -o.
grgsm_decode -m TCHF -t {0..7} -c 9258_recording/out_975.cfile -a 975 -s 250k -o output.gsm
grgsm_decode -m TCHH -t {0..7} -c 9258_recording/out_975.cfile -a 975 -s 250k -o output.gsm
Referencia de los mensajes GSM
Los paquetes como System Information, Paging Request, y Location Update son fundamentales en el funcionamiento de la red GSM, ya que permiten la comunicación de información de control y señalización entre la red y los dispositivos móviles.
System Information: paquetes que envía la estación base a todos los dispositivos móviles en su área de cobertura. Estos mensajes contienen información esencial sobre la red y la celda en la que el dispositivo está registrado.Paging Request: utilizado por la red GSM para notificar a un dispositivo móvil que tiene una llamada entrante, un mensaje de texto (SMS) o alguna otra comunicación pendiente.Location Update: se usa para notificar a la red cuando un dispositivo móvil cambia de área de localización (LA, Location Area) o cuando se registra por primera vez en la red GSM. Esto permite que la red siempre conozca la ubicación aproximada del dispositivo.Channel Request: se envía cuando un dispositivo móvil solicita acceso a la red, por ejemplo, para iniciar una llamada o enviar un mensaje SMS.Immediate Assignment: se envía en respuesta a una solicitud de canal, y asigna un canal de control específico al dispositivo móvil para continuar la comunicación. Esto asegura que el dispositivo pueda comenzar la transmisión de datos o voz en un canal dedicado.Authentication Request: se utiliza para verificar la identidad del dispositivo móvil antes de que pueda acceder a la red GSM. Cuando un dispositivo intenta registrarse en la red, la red envía este mensaje, y el dispositivo debe responder con una respuesta basada en su clave de autenticación.Ciphering Mode Command: establece un cifrado en la comunicación entre el dispositivo y la estación base, protegiendo la privacidad de los datos que se transmiten.Assignment Command: es enviado por la red para indicar que el dispositivo móvil debe cambiarse a un canal de tráfico (TCH) cuando se establece una llamada de voz o una conexión de datos.Handover Command: es usado cuando la red decide cambiar la conexión del dispositivo móvil a una nueva celda durante una llamada o sesión de datos activa. Este comando indica al dispositivo la nueva frecuencia y el canal al cual debe cambiarse para mantener la calidad de la señal a medida que se mueve.
Conclusión
Las herramientas contenidas en gr-gsm son útiles para fines de análisis, investigación, e incluso para mejorar el conocimiento sobre la estructura de las redes GSM.