Un blog de Seguridad Informática, desde un punto de vista tecnológico

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

2 comentarios

  1. Pingback: Cuando las ballenas vuelan (episodio II) – Creando un entorno de análisis GSM usando Docker (parte 3) | Testpurposes

  2. Pingback: Cuando las ballenas vuelan (episodio II) – Creando un entorno de análisis GSM usando Docker (parte 1) | Testpurposes

Deja un comentario