Cuando las ballenas vuelan (episodio II) – Creando un entorno de análisis GSM usando Docker (parte 2)
Esta es la segunda parte de la serie (parte 1 y parte 3) y se empezará a explicar un escenario de análisis GSM usando los contenedores creados en la primera.
Obtener la clave de cifrado GSM con OsmocomBB
Una de las cosas que se puede hacer con OsmocomBB es acceder a la clave de sesión de cifrado simétrico GSM (Kc).
Nota: Tal y como se explicó en la anterior entrada, para seguir estos pasos son necesarios un teléfono compatible con OsmocomBB y un cable/adaptador USB-serie.
El primer paso será arrancar un contenedor de la imagen xenial-osmocombb
dándole acceso al dispositivo que representa al adaptador USB-serie:
docker run --device=/dev/ttyUSB0 --rm -it --name test-osmocombb pachulo/xenial-osmocombb
Este comando creará un contenedor efímero (--rm
), de nombre test-osmocombb
y ejecutará un terminal interactivo en el mismo (-it
).
Activar la emisión de señales (Tx)
Por cuestiones de seguridad (en algunos países está prohibido emitir en el espectro GSM sin licencia), OsmocomBB está configurado por defecto para tan sólo permitir la recepción de señales. Para obtener un firmware que sea capaz de emitir (para registrarse en la red del operador, por ejemplo) habrá que realizar las siguientes acciones.
Seguir las instrucciones del archivo /osmocom-bb/src/target/firmware/Makefile
:
# Uncomment this line if you want to enable Tx (Transmit) Support. #CFLAGS += -DCONFIG_TX_ENABLE
Y descomentar el FLAG con un comando como este:
sed -i 's/#CFLAGS += -DCONFIG_TX_ENABLE/CFLAGS += -DCONFIG_TX_ENABLE/g' /osmocom-bb/src/target/firmware/Makefile
Y después volver a compilar OsmocomBB con el siguiente comando:
cd /osmocom-bb/src && \ make distclean && \ make
osmocon
Una vez finalizado el anterior paso y desde la sesión del contenedor, se ejecutará osmocon con unas opciones parecidas a estas, teniendo en cuenta que según el teléfono usado puede ser otro firmware el que haya que cargar:
cd /osmocom-bb/src/host/osmocon && \ ./osmocon -p /dev/ttyUSB0 -m c123xor ../../target/firmware/board/compal_e88/layer1.compalram.bin
Nota: Las diferentes opciones de osmocon, así como los firmware disponibles para cada teléfono, están explicadas en la documentación.
Una vez ejecutado el comando, con el teléfono conectado al ordenador mediante el cable/adaptador USB-serie, se deberá pulsar el botón de encendido del teléfono brevemente para que cargue el firmware de OsmocomBB y no el original.
Si todo ha ido bien, en la consola se debería ver algo como:
Received PROMPT1 from phone, responding with CMD [16/147] read_file(../../target/firmware/board/compal_e88/layer1.compalram.bin): file_size=58484, hdr_len=4, dnload_len=58491 got 1 bytes from modem, data looks like: 1b . got 1 bytes from modem, data looks like: f6 . got 1 bytes from modem, data looks like: 02 . got 1 bytes from modem, data looks like: 00 . got 1 bytes from modem, data looks like: 41 A got 1 bytes from modem, data looks like: 02 . got 1 bytes from modem, data looks like: 43 C Received PROMPT2 from phone, starting download handle_write(): 4096 bytes (4096/58491) handle_write(): 4096 bytes (8192/58491) handle_write(): 4096 bytes (12288/58491) handle_write(): 4096 bytes (16384/58491) handle_write(): 4096 bytes (20480/58491) handle_write(): 4096 bytes (24576/58491) handle_write(): 4096 bytes (28672/58491) handle_write(): 4096 bytes (32768/58491) handle_write(): 4096 bytes (36864/58491) handle_write(): 4096 bytes (40960/58491) handle_write(): 4096 bytes (45056/58491) handle_write(): 4096 bytes (49152/58491) handle_write(): 4096 bytes (53248/58491) handle_write(): 4096 bytes (57344/58491) handle_write(): 1147 bytes (58491/58491) handle_write(): finished got 1 bytes from modem, data looks like: 1b . got 1 bytes from modem, data looks like: f6 . got 1 bytes from modem, data looks like: 02 . got 1 bytes from modem, data looks like: 00 . got 1 bytes from modem, data looks like: 41 A got 1 bytes from modem, data looks like: 03 . got 1 bytes from modem, data looks like: 42 B Received DOWNLOAD ACK from phone, your code is running now! battery_compal_e88_init: starting up OsmocomBB Layer 1 (revision osmocon_v0.0.0-1773-g0cdf4b0) ====================================================================== Device ID code: 0xb4fb Device Version code: 0x0000 ARM ID code: 0xfff3 cDSP ID code: 0x0128 Die ID code: ee0c2c2ab8021437 ====================================================================== REG_DPLL=0x2413 CNTL_ARM_CLK=0xf0a1 CNTL_CLK=0xff91 CNTL_RST=0xfff3 CNTL_ARM_DIV=0xfff9 ...
Y en la pantalla del teléfono:
Layer 1 osmocom-bb
mobile
El siguiente paso es abrir otra sesión en el contenedor:
docker exec -ti test-osmocombb /bin/bash
Y ejecutar el comando mobile para que se conecte al teléfono y haga las funciones de capa 2-3:
cd /osmocom-bb/src/host/layer23/src/mobile && \ ./mobile -i 127.0.0.1
Y permita la gestión del mismo. Para ello habrá que abrir una tercera sesión dentro del contenedor:
docker exec -ti test-osmocombb /bin/bash
Y conectarse, mediante telnet, al puerto abierto por mobile:
telnet 127.0.0.1 4247
Con lo que se obtendrá acceso a la interfaz de control de OsmocomBB:
Welcome to the OsmocomBB control interface OsmocomBB> ? show Show running system information list Print command list exit Exit current mode and down to previous mode help Description of the interactive help system enable Turn on privileged mode command terminal Set terminal line parameters who Display who is on vty monitor Monitor... no Negate a command or set its defaults
Nota: La documentación del comando mobile está disponible aquí.
Y desde la que, una vez activado el modo privilegiado con el comando enable
:
OsmocomBB> enable OsmocomBB# ? help Description of the interactive help system list Print command list write Write running configuration to memory, network, or terminal show Show running system information exit Exit current mode and down to previous mode disable Turn off privileged mode command configure Configuration from vty interface copy Copy configuration terminal Set terminal line parameters who Display who is on vty monitor Monitor... no Negate a command or set its defaults off Turn mobiles off (shutdown) and exit sim SIM actions network Network ... call Make a call sms Send an SMS service Send a Supplementary Service request test Manually trigger cell re-selection delete Delete
Será posible desbloquear la SIM con el PIN:
OsmocomBB# sim pin 1 1234
Y, después de esperar unos segundos a que se produzca el registro en la red del operador:
% (MS 1) % Trying to registering with network... % (MS 1) % On Network, normal service: Spain, Orange
Ya se podrá obtener información como el IMSI (International Mobile Subscriber Identity), el ICCID (Integrated Circuit Card IDentifier) y la clave Kc:
OsmocomBB# show subscriber 1 Mobile Subscriber of MS '1': IMSI: 2140345XXXXXXXX ICCID: 89340141716XXXXXXXX Service Provider Name: Orange SMS Service Center Address: +34656000311 Status: U1_UPDATED IMSI attached TMSI 0x7081xxxxx LAI: MCC 214 MNC 03 LAC 0xXXXX (Spain, Orange) Key: sequence 0 23 7d cf ff ff ff ff ff Registered PLMN: MCC 214 MNC 03 (Spain, Orange) Access barred cells: no Access classes: C0 ...
Así como los datos de la celda a la que está conectado:
OsmocomBB# show ms MS '1' is up, service is normal IMEI: 000000000000000 IMEISV: 0000000000000000 IMEI generation: fixed automatic network selection state: A2 on PLMN MCC=214 MNC=03 (Spain, Orange) cell selection state: C3 camped normally ARFCN=993 MCC=214 MNC=03 LAC=0x0XXX CELLID=0x0XXX (Spain, Orange) radio ressource layer state: idle mobility management layer state: MM idle, normal service ...
Analizar y decodificar el Common Control CHannel de un ARFCN con OsmocomBB y Wireshark
Para poder hacer esto habrá que arrancar el contenedor de la siguiente manera:
docker run --device=/dev/ttyUSB0 --net=host --rm -it --name test-osmocombb pachulo/xenial-osmocombb
Cargar el mismo firmware que para el ejemplo anterior:
cd /osmocom-bb/src/host/osmocon && \ ./osmocon -p /dev/ttyUSB0 -m c123xor ../../target/firmware/board/compal_e88/layer1.compalram.bin
Pero ejecutar en este caso la aplicación ccch_scan (en vez de mobile):
docker exec -ti test-osmocombb /bin/bash
Indicando en el parámetro ARFCN (Absolute Radio-Frequency Channel Number) el que se quiera sintonizar:
cd /osmocom-bb/src/host/layer23/src/misc &&; \ ./ccch_scan --arfcn 993 --gsmtap-ip 127.0.0.1
A partir de entonces, si se ejecuta Wireshark para sniffar el tráfico de red de la interfaz loopback, se visualizarán los mensajes decodificados del CCCH del ARFCN sintonizado.
Capturar el tráfico de la interfaz aérea de GSM con GR-GSM
Con la información obtenida en el paso anterior, ya se puede intentar sintonizar el canal al cual está conectado nuestro teléfono. Para ello es necesario ejecutar un contenedor gr-gsm:
docker run --device=/dev/bus/usb/002 --net=host --cap-add=NET_ADMIN --rm --name test-gr-gsm -it -v `pwd`/files:/root/files pachulo/xenial-gr-gsm
Nota: En este caso no hará falta hacer passthrough de la GPU, ya que todo el software que se necesita para este escenario funciona por línea de comandos.
Obtener el error de sintonización del RTL-SDR
Antes que nada, habrá que calcular que error tiene nuestro RTL-SDR a la hora de sintonizar una frecuencia (medido en ppm). Para ello se utilizará el software Kalibrate para, primero, escanear el espectro GSM:
root@latitude:/# kal -s EGSM -v 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 kal: Scanning for E-GSM-900 base stations. channel detect threshold: 18835.181650 E-GSM-900: chan: 9 (936.8MHz + 2.826kHz) power: 52243.45 ... chan: 993 (928.8MHz + 309Hz) power: 43248.09
Nota: Si al escanear el espectro no se encuentra ningún canal: a) estamos en una zona sin cobertura 2G b) el error de sintonización del cristal del RTL-SDR es tan grande que Kalibrate no es capaz de sintonizar ninguna. En caso de b) es posible ejecutar kal con un error inicial, usando la opción «-e».
Y después calcular el error sintonizando con uno de los canales detectados:
root@latitude:/# kal -c 993 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 kal: Calculating clock frequency offset. ... average absolute error: 23.051 ppm
Siendo el medio de este dispositivo 23.051 ppm.
Hay que tener en cuenta que este valor puede cambiar con la temperatura, así que vale la pena ejecutar lo siguiente durante unos 10 minutos antes de realizar el cálculo:
root@latitude:/# rtl_test Found 1 device(s): 0: Realtek, RTL2838UHIDIR, SN: 00000001 Using device 0: Generic RTL2832U OEM Found Rafael Micro R820T tuner Supported gain values (29): 0.0 0.9 1.4 2.7 3.7 7.7 8.7 12.5 14.4 15.7 16.6 19.7 20.7 22.9 25.4 28.0 29.7 32.8 33.8 36.4 37.2 38.6 40.2 42.1 43.4 43.9 44.5 48.0 49.6 Sampling at 2048000 S/s. Info: This tool will continuously read from the device, and report if samples get lost. If you observe no further output, everything is fine. Reading samples in async mode...
Capturar el downlink
Una vez realizados estos pasos ya se podrá pasar a capturar el tráfico del ARFCN de la celda donde está conectado nuestro teléfono (993 en nuestro caso) y guardando los resultados (en forma de bursts GSM) en el fichero test-burst.file
con la herramienta grgsm_capture.py
:
grgsm_capture.py --arfcn=993 --ppm=23 --burst-file=test-burst.file
Ahora será el momento de enviar un SMS al número de teléfono asignado a la tarjeta SIM del teléfono OsmocomBB:
OsmocomBB# % (MS 1) % SMS from +3466XXXXXXX: 'Testpurposes'
Una vez recibido, ya se podrá detener la captura y pasar a decodificar el canal BCCH (Broadcast Control CHannel) usando el fichero de bursts como entrada de la herramienta grgsm_decode
:
grgsm_decode --arfcn=993 --ppm=23 --burst-file=test-burst.file --timeslot=0 --mode=BCCH
En este momento, si se pone a capturar el tráfico de red con Wireshark en la interfaz loopback, se podrán visualizar los datos decodificados:
Nota: Se recomienda ejecutar Wireshark con el siguiente comando para ver el tráfico decodificado:
wireshark -k -f udp -Y gsmtap -i lo
El siguiente paso es verificar que hemos capturado el tráfico hacía nuestro teléfono, por lo que se puede aplicar un filtro de Wireshark para ver si se ha producido alguna comunicación con el TMSI (Temporary Mobile Subscriber Identity) asignado (y obtenido con OsmocomBB) gsm_a.tmsi == 0x7081e5c3
:
En este caso vemos dos paquetes del tipo «Paging Request Type 1» con destino nuestro terminal.
Nota: Hay que tener en cuenta que con el RTL-SDR sólo se está capturando el tráfico que va de la red del operador (las Base Transceiver Stations básicamente) a las Mobile Stations (los teléfonos).
Una vez hecho esto, habrá que examinar los paquetes de tipo «Immediate Assignment» para encontrar los que contienen el campo «Channel Description«. En este atributo se podrá observar a que timeslot y canal se asignan los terminales cuando necesitan un canal dedicado:
En nuestro ejemplo es el timeslot 1 y el canal SDCCH8 (Stand-alone Dedicated Control CHannel con 8 sub-slots).
Con esta información ya se podrá pasar a decodificar el canal con el siguiente comando:
grgsm_decode --arfcn=993 --ppm=23 --burst-file=test-burst.file --timeslot=1 --mode=SDCCH8
Aunque como la mayoría del tráfico de este canal va cifrado se decodificaran muy pocos paquetes. De todas formas ya se pueden averiguar dos cosas:
1. Que el dispositivo al que se está respondiendo es el nuestro, verificando el TMSI del paquete «Paging Response«:
2. El algoritmo de cifrado usado, ya que se comunica antes de empezar a cifrar el tráfico. A5/1 en el caso de nuestra comunicación:
Por último, para descifrar el tráfico que ha recibido nuestro teléfono se puede especificar la Kc (obtenida con OsmocomBB) como parámetro de grgsm_decode
:
grgsm_decode --burst-file=test-burst.file --arfcn=993 --ppm=23 --timeslot=1 --mode=SDCCH8 --kc=237dcfffffffffff
Con lo que se podrá ver los datos en claro, incluyendo el SMS que se ha enviado:
Bonus
Configurar OsmocomBB para que el teléfono no «salte» de celda
Uno de los problemas que puede plantearse a la hora de realizar este escenario es que el teléfono vaya saltando de una celda a otra, ya que si las potencias de transmisión son parecidas, cada cierto tiempo escaneará el espectro GSM y se conectará a la que emita con más fuerza. Esto puede dificultar la captura del tráfico con un dispositivo RTL-SDR, ya que este solo puede capturar un ancho de banda limitado (aprox. 2MHz).
Para cambiar este comportamiento habrá que escribir la configuración del teléfono en un fichero con el siguiente comando de la consola OsmocomBB:
OsmocomBB# write file Configuration saved to /root/.osmocom/bb/mobile.cfg
Para a continuación apagarlo, modificar la siguiente linea de la configuración:
< no stick --- > stick <ARFCN>
Substituyendo <ARFCN> por el de la celda a la que se quiera conectar de forma fija y volver a arrancar el teléfono con el firmware OsmocomBB.
SIMTester
En este apartado se va explicar como sería posible realizar análisis de seguridad de tarjetas SIM con SIMTester usando un teléfono compatible con OsmocomBB como lector.
Primero habrá que arrancar un nuevo contenedor OsmocomBB:
docker run --device=/dev/ttyUSB0 --rm -it --name test-simtester pachulo/xenial-osmocombb
Utilizar el teléfono como lector requiere un firmware especial, pero antes de poder crearlo habrá que instalar el JDK de Java 8:
apt update && \ apt install -y openjdk-8-jdk
Ahora habrá que compilar la rama luca/libosmosim
de OsmocomBB, pero antes se tendrá realizar una pequeña modificación, ya que parece que los Makefile tienen la ruta del JDK hardcodeada.:
cd /osmocom-bb/src && \ git checkout luca/libosmosim && \ sed -i 's/\/home\/gsmmap\/jdk1.7.0_45/\/usr\/lib\/jvm\/java-8-openjdk-amd64/g' host/layer23/src/libosmosim/Makefile* && \ make
Una vez finalizada la compilación ejecutaremos osmocon
para cargar el firmware cuando se encienda el teléfono:
cd /osmocom-bb/src/host/osmocon && \ ./osmocon -p /dev/ttyUSB0 -m c123xor ../../target/firmware/board/compal_e88/layer1.compalram.bin
Una vez hecho esto, en otro terminal dentro del contenedor:
docker exec -ti test-simtester /bin/bash
Ya se podrá descargar el software:
wget https://opensource.srlabs.de/attachments/download/117/SIMtester_v1.8.1.zip &&; \ unzip SIMtester_v1.8.1.zip
Y ejecutarlo, aunque antes habrá que asegurarse de que el archivo libosmosim.so
esté disponible en el java.library.path
:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/osmocom-bb/src/host/layer23/src/libosmosim/.libs/ && \ cd /SIMtester/binaries/v1.8.1 && \ java -jar SIMTester.jar -tf OsmocomBB
Pero, aunque parece que el programa se conecta correctamente al teléfono, no aparecen resultados:
######################################## SIMTester v1.8.1, 2016-02-04 Lukas Kuzmiak (lukas@srlabs.de) Security Research Labs, Berlin, 2017 ######################################## Using OsmocomBB mobile as SIM card reader Terminals connected: 1 de.srlabs.simlib.osmocardprovider.OsmoCardTerminal@5b2133b1 Using terminal: OsmoCardTerminal Card connected: de.srlabs.simlib.osmocardprovider.OsmoCard@33c7353a