Introducción:

El sistema de transporte analazido en esta oportunidad utiliza tarjetas MIFARE Classic 1K y 1K-plus con tecnología NFC.
Cada tarjeta contiene 1024 bytes de información, los cuales están divididos en 16 sectores (0-15) de 64 bytes que a su vez conforman 4 bloques (0-3) de 16 bytes cada uno.

Para poder leer los datos de cualquier sector es necesario autenticarse usando sus claves, cada sector contiene 2 claves (KeyA/KeyB), las claves pueden repetirse o no, en este caso las 32 claves son diferentes.

No tiene mucho sentido explicar como obtener las claves ya que la criptografía que utilizó NXP (su fabricante) en las versiones 1K de las tarjetas fué vulnerada hace más de una década e incluso recientemente surgió un backdoor [1] tanto para la versión 1K como 1K-plus.

Ya con acceso directo a la información que contiene la tarjeta solo queda identificar el comportamiento que representa cada byte para entender su funcionamiento.

Breve descripción de cada sector:

S00: Identificación técnica. Este sector nunca cambia.
S01: Identificación personal. Este sector nunca cambia.
S02: Funcionamiento complejo, cambia en cada transacción.
S03: Fecha, puede cambiar en cada transacción de carga.
S04: Reservado para abonos.
S05: Reservado para abonos.
06: Value block.
S07: Value block.
S08: Value block.
S09: Backups del bloque 2 del sector 10.
S10: Timestamp+info/backup de los viajes.
S11: Backups del bloque 2 del sector 12.
S12: Timestamp+info/backup de las recargas.
S13: Sector reservado, sin uso.
S14: Sector reservado, sin uso.
S15: Sector reservado, sin uso.

Notas:

En el bloque 0 del sector 0 los primeros 4 bytes contienen el UID de la tarjeta con un checksum en el byte 5 llamado BCC, todo el bloque está protegido contra escritura según la especificación original de NXP [2].

El bloque 3 de cada sector contiene sus dos claves (KeyA/KeyB) y sus permisos.

Los bloques 0-2, con algunas excepciones que serán contempladas en párrafos posteriores, contienen cada uno un checksum (CRC) en los bytes 14-15 para validar su información.

En cualquier caso donde se intente autenticar contra el sistema donde las claves no coincidan y/o el CRC de cualquier bloque sea incorrecto la tarjeta no interactuará con el mismo.

Referencia visual de la estructura de la tarjeta:

mifareclassicdef
Estructura de una tarjeta MIFARE Classic 1K/1K-Plus

Reglas básicas:

En general y a menos que se especifique lo contrario vamos a tomar las siguientes afirmaciones como verdaderas para agilizar la lectura en los puntos posteriores:

El CRC de 16 bits es siempre el conjunto de bytes 14-15 de cada bloque.
El CRC se calcula para cada bloque y para hacerlo se toman los bytes 0-13 (en ese orden) y se utiliza el algoritmo CRC-16/CCITT-FALSE con el resultado en formato little-endian.
El resto de la información del bloque está en formato hexadecimal.
Los bloques que no tienen uso alguno no necesitan tener un CRC y siempre suman 0.
El bloque 3 conocido como tráiler block contiene las 2 claves (KeyA/KeyB) de su sector y los access bits que determinan los permisos que tienen esas claves que limitan, o no, las operaciones que pueden realizarse en ese sector. De ahora en más el bloque 3 no será mencionado nuevamente porque su única finalidad es autenticar y definir permisos, en circunstancias normales estos no cambian.

Generalización del procedimiento:

Para intentar entender cómo funciona un sistema del cual no tenemos datos previos una buena primera opción es ver si ocurren cambios de información entre diferentes operaciones. En particular en este caso teniendo la posibilidad de leer la información de la tarjeta sin restricciones podemos crear un procedimiento de lectura/carga/lectura o lectura/viaje/lectura que nos puede permitir ver los cambios entre transacciones y tratar de encontrar de esta forma patrones en el cambio de información.

Realizando este procedimiento incontables veces se apreciaron varios datos valiosos:

  • La información no está encriptada facilitando enormemente la lectura y compresión de datos.
  • Funcionamiento relativamente simple.
  • Aparente validación de datos sin cruzar información con base de datos en el procedimiento de carga; es importante aclarar que el procedimiento de carga no es simplemente cambiar los datos de un value block, esto quizás funcionaba hace varios años pero actualmente el sistema detecta inconsistencias en la tarjeta y la bloquea (relativamente rápido) si solo se realiza un cambio en el value block.
  • El bloqueo de tarjetas se realiza utilizando el UID del sector 0 bloque 0 (como debería ser), pero no detecta tarjetas gen2 lo cual permite utilizar información válida de una tarjeta cualquiera y cambiar el UID indefinidamente previo a cada transacción sin mayores problemas.
  • Entendiendo que función tiene cada byte se puede cambiar su valor a discreción siempre dentro de los parámetros del sistema sin mayores problemas.

En este texto nos concentraremos únicamente en las tarjetas comunes, hay diferentes tipos de tarjetas pero las podemos generalizar en:

  1. Común: utiliza saldo para su funcionamiento (value blocks).
  2. Abonos: utiliza un contador para calcular la cantidad de viajes disponibles, hay distintos tipos de abono pero todas funcionan de manera similar.

De ahora en más el texto será un poco más técnico y algunos procedimientos y funciones se describirán de forma breve asumiendo que el lector entiende los conceptos de números hexadecimales, integrales, ASCII, etc.

Primero se explicará qué hace técnicamente cada sector para luego explicar el flujo y lógica del sistema de una forma más amena tanto para realizar cargas como viajes.

Sector 0: Identificación técnica

El bloque 0 es el único bloque de la tarjeta que no puede reescribirse y contiene el UID de la tarjeta, este UID es un identificador numérico de 4 bytes (0-3) el cual puede ser generado al azar, con su correspondiente checksum BBC en el byte 5, el cual simplemente es un XOR del UID, el resto del bloque puede ser genérico y no contiene CRC en los bytes 14 y 15.

Dato: Desde hace varios años existen en el mercado tarjetas compatibles “made in China” donde el bloque 0 puede ser modificado ilimitadamente, se conocen como magic cards gen2, gen3 o gen4 (también conocidas como ULTIMATE).

El bloque 1 contiene el número de tarjeta (bytes 0-3) y lo que presumo es un número de emisión/activación (bytes 4-6). Los bytes 14-15 son el CRC del bloque.

El bloque 2 no cambia en ningún momento y es el mismo en todas las tarjetas. Los bytes 14-15 son el CRC del bloque.

Sector 1: Identificación personal

En este sector hay que analizar los 3 bloques simultáneamente, los bloques 0 y 1 no utilizan CRC y usualmente no contienen información pero están reservados para el nombre y apellido del usuario en formato ASCII, el bloque 2 contiene el DNI del usuario en los bytes 0-10 y el tipo de tarjeta en los bytes 11-13 (hay diferentes tipos de tarjetas: común, abono, etc). Los bytes 14-15 son el CRC del conjunto de bloques 0-2, en este caso para calcularlo hay que usar (en orden) el bloque 0 + bloque 1 + los primeros 14 bytes del bloque 2.

Sector 2: Funcionamiento complejo de cada transacción

En el bloque 0 los bytes 0-1 son estáticos, los bytes 2-6 son los mismos 4 bytes del UID del bloque 0 del sector 0, los bytes 7-13 son estáticos. Los bytes 14-15 son el CRC del bloque.

Los bloques 1 y 2 funcionan exactamente igual con los mismos datos.

Los bytes 0-1 son un contador que empieza de 0 con la particularidad que el byte 0 es el contador de cada transacción y el byte 1 solamente aumenta cuando el byte 0 llega a FF y tiene que reiniciar desde 0, después de un ciclo el par de bytes quedaría como 0001, dando teóricamente un máximo de 65.025 transacciones posibles.

Los bytes 2-3 no tienen un patrón específico para calcularlos pero tiene un ritmo cíclico indicando que si el valor actual del par de bytes es X el próximo valor será Y y viceversa.

El byte 4 suma en formato decimal 4 unidades cuando se realiza una recarga y resta 32 unidades en un viaje.

Los bytes 5-6 son estáticos.

Los bytes 7-8 son la fecha actual de la transacción contando los días desde el XX de Marzo de 1987, este día cambia cada un par de meses, asumo que es algún tipo de salto necesario, estas correcciones son siempre hacia el pasado lo cual requiere que se realizen cuando el sistema no está en funcionamiento.

Los bytes 9-13 son estáticos. Los bytes 14 y 15 son el CRC del bloque.

Sector 3: Cambio de fecha en cada recarga

El bloque 0 es estático y no es usado por lo cual no tiene CRC y suma 0.

Los bloques 1-2 contienen la fecha de la última recarga, los bytes 0-2 son estáticos, los bytes 3-4 son la fecha actual de la recarga utilizando el mismo sistema del bloque 2 del sector 2. Los bytes 5-13 suman 0. Los bytes 14-15 son el CRC del bloque.

Sectores 4 y 5: Reservado para abonos

Los distintos tipos de abonos funcionan similarmente, en general los bloques 1-2 tiene algún tipo de contador que cambia 1 unidad en formato decimal de forma intercambiable, no es objetivo de este proyecto ver estos sectores en detalle.

Sectores 6, 7 y 8: Value blocks

Estos 3 sectores son los value block de la tarjeta, en general un value block es un bloque de la tarjeta que permite hacer cálculos matemáticos, normalmente se utilizan como contadores o para sumar y restar saldos pero cualquier cálculo que requiera integrales se puede realizar sin problemas y si se requiere un número con decimales se pueden tomar los ultimos 2 digitos del integral como tales, de hecho eso es exactamente lo que hace el sistema. Los únicos 2 bloques utilizados por el sistema para este propósito actualmente son el bloque 1-2 del sector 6.

Sectores 9 y 10: Información de viajes

En cada viaje realizado se modifica el sector 10 bloque 2 con varios datos, los bloques 0-2 del sector 9 y los bloques 0-1 del sector 10 son usados como backup, en ese orden, cuando estos 5 bloques fueron utilizados al menos una vez el procedimiento se reinicia en el mismo orden.

Los bytes 0-1 son la fecha actual de la transacción contando los días en formato decimal desde el XX de Junio de 1990, este día puede tener una corrección al igual que la fecha del sector 2/3 cada un par de meses.

Los bytes 2-3 son la hora del día, una aproximación para generar la hora actual es tomar los minutos del día y multiplicarlos por 34.08 y utilizar el integral más cercano para después convertirlo a formato hexadecimal.

Los bytes 4-5 son el contador (bytes 0-1) del sector 2 de la transacción actual.

Los bytes 6-10 son el identificador del colectivo (más precisamente del lector que interactúa con la tarjeta).

Los bytes 11-13 son el costo del viaje. Los bytes 14-15 son el CRC del bloque.

Sectores 11 y 12: Información de cargas

En cada carga realizada se modifica el sector 12 bloque 2 con varios datos, los bloques 0-2 del sector 11 y los bloques 0-1 del sector 12 son usados como backup, en ese orden, cuando estos 5 bloques fueron utilizados al menos una vez el procedimiento se reinicia en el mismo orden.

Los bytes 0-1 son la fecha actual de la transacción contando los días en formato decimal desde el XX de Junio de 1990, este día puede tener una corrección al igual que la fecha del sector 2/3 cada un par de meses.

Los bytes 2-3 son la hora del día, una aproximación para generar la hora actual es tomar los minutos del día y multiplicarlos por 34.08 y utilizar el integral más cercano para después convertirlo a formato hexadecimal.

Los bytes 4-5 son el contador (bytes 0-1) del sector 2 de la transacción actual.

Los bytes 6-10 son el identificador del posnet que realiza la recarga.

Los bytes 11-13 son el nuevo saldo que tiene la tarjeta. Los bytes 14-15 son el CRC del bloque.

Sectores 13, 14 y 15: Sin uso

Si bien estos sectores no tienen función alguna en situaciones normales, recientemente el sistema empezó a grabar el sector 13 con pequeños segmentos de 3 bytes solamente cuando se realizan viajes, es necesario obtener más información para poder hacer un análisis más certero pero podemos asumir que es algún tipo de testeo o preparación para una nueva funcionalidad.

Detalle del funcionamiento técnico de un viaje

Al momento de realizar un viaje se modifican los sectores 2, 6, 9 (en caso de ser necesario) y 10.

En el sector 2 cambian los bloques 1-2 de forma simultánea con la misma información, se suma 1 unidad decimal al contador del byte 0 y en caso que este sume 256 su valor pasa a ser 0 y el byte 1 suma una unidad en decimales. Los bytes 2-3 cambian de forma cíclica entre valores pre-definidos. El byte 5 resta 32 unidades en decimales. Los bytes 6-7 son estáticos y los bytes 8-9 son la fecha actual. Los bytes 10-13 son estáticos.

El sector 6 contiene los últimos 2 saldos de la tarjeta en los bloques 1-2, siempre que se hace un viaje cambia el value block del bloque más antiguo.

El sector 10 contiene en su bloque 2 la información descrita en la sección correspondiente y realiza un backup exacto al bloque correspondiente del sector 9 o los 2 disponibles del mismo sector.

Detalle del funcionamiento técnico de una recarga

Al momento de realizar una recarga se modifican los sectores 2, 3, 6, 11 (en caso de ser necesario) y 12.

En el sector 2 cambian los bloques 1-2 de forma simultánea con la misma información, se suma 1 unidad decimal al contador del byte 0 y en caso que este sume 256 su valor pasa a ser 0 y el byte 1 suma una unidad en decimales. Los bytes 2-3 cambian de forma cíclica entre valores pre-definidos. El byte 5 suma 4 unidades en decimales. Los bytes 6-7 son estáticos y los bytes 8-9 son la fecha actual. Los bytes 10-13 son estáticos.

En el sector 3 cambian los bytes 3-4 del bloque 1 o del bloque 2, dependiendo cual es el que contiene la fecha más antigua. La fecha es la misma que fue utilizada en el sector 2.

El sector 6 contiene los últimos 2 saldos de la tarjeta en los bloques 1-2, siempre que se hace una recarga cambia el value block del bloque más antiguo.

El sector 12 contiene en su bloque 2 la información descrita en la sección correspondiente y realiza un backup exacto al bloque correspondiente del sector 11 o los 2 disponibles del mismo sector.

Observaciones y conclusiones

Fué muy interesante tratar de entender cómo funciona este sistema de transporte, creo que lo más importante a destacar es que como la información de la tarjeta no se encuentra encriptada resulta accesible, pero no del todo fácil, el procedimiento de ingeniería inversa.

Para poder afirmar que se entiende el funcionamiento de un sistema lo mejor que se puede hacer es una predicción y luego confirmarla, en este caso se creó una recarga en la tarjeta y despues se la validó interactuando con el sistema, si la predicción fuese correcta el nuevo saldo de la tarjeta debería ser el elegido. Nota: el saldo máximo posible de la tarjeta al momento de la operación era de 9999.

result
Sin comentarios.

Referencias: 1 2