Comprueba si leer un tag NFC es seguro

Como adelantamos en el anterior post, una de las utilidades de NFC es el uso de NFC Forum tags para guardar e intercambiar información, normalmente de tipo comercial. Estos tags deben ser fieles a una especificación determinada: el formato NDEF (NFC Data Exchange Format). Gracias a este formato es posible intercambiar mensajes NDEF entre las diferentes partes, pudiendo tener cada mensaje diferentes registros donde almacenar información. El tipo de información que se puede introducir en estos registros es variado, y puede ir desde texto simple a diferentes formatos de audio o vídeo (media), pasando por una URI para realizar acciones automáticas en el dispositivo lector, normalmente un teléfono móvil. Podéis echar un vistazo a la especificación de NDEF para profundizar más en el tema.

En este post nos vamos a centrar en las posibilidades que ofrecen los registros de tipo URI y qué acciones se pueden realizar al leerse en un teléfono móvil con tecnología NFC. Los tipos de URI que se aceptan según la especificación son los siguientes:


URI Identifier Codes
Schemes
0x01
http://www.
0x02
https://www.
0x03
http://
0x04
https://
0x05
tel:
0x06
mailto:
0x07
ftp://anonymous:anonymous@
0x08
ftp://ftp.
0x09
ftps://
0x0A
sftp://
0x0B
smb://
0x0C
nfs://
0x0D
ftp://
0x0E
dav://
0x0F
news:
0x10
telnet://
0x11
imap:
0x12
rtsp://
0x13
urn:
0x14
pop:
0x15
sip:
0x16
sips:
0x17
tftp:
0x18
btspp://
0x19
btl2cap://
0x1A
btgoep://
0x1B
tcpobex://
0x1C
irdaobex://
0x1D
file://
Estas URIs se pueden escribir en los tags con el lector/escritor que instalamos en el post anterior o con cualquier otro. El software necesario puede ser basado en libnfc, pero en este caso usaremos un script modificado del proyecto nfcpy. Se puede modificar el script helloworld.py, ignorando las líneas que no son importantes e incluyendo estas otras, siendo “message” la URI que queremos introducir (podéis descargarlo aquí, pero no está muy testeado, cuidadín! :p):

 uri = nfc.ndef.Uri.UriRecord(myURI) // Creación del registro URI
 uri._data = '\x00'+
myURI // El tipo 0x00 acepta cualquier URI
 message = nfc.ndef.Message(uri) // Creamos el mensaje NDEF
 tag.ndef.message = message.tostring() // Escribiendo en el tag...

Se han hecho diferentes pruebas con las diferentes URIs disponibles en un Samsung Galaxy Nexus con Android 4.0 (Ice Cream Sandwich). Además también se han incluido otras URIs asociadas a aplicaciones como Facebook, Skype y GTalk. En la gran mayoría de ellas no se reconocía la URI, en otras se reconocía pero no se generaba ninguna acción. Este es el caso de “tel:” (llamada de teléfono), “sms:” (envío de SMS), “mailto:” (envío de correo electrónico), “file://” (navegación de archivos locales), “fb://” (URI de Facebook) y “skype:” (URI de Skype).

  
  

Sólo en uno de los casos, en el que se incluye una URI para visitar un sitio web, el teléfono móvil realizaba una acción de forma automática: lanzaba el navegador y se dirigía a la página especificada. Es importante remarcar que no es necesario instalar ninguna aplicación para obtener este comportamiento ya que el responsable es el lector NFC incluído por defecto en Android. En el siguiente vídeo se puede ver una simple prueba, usando NXP TagWriter para escribir la URL en el tag:

Esto puede ser una característica útil desde el punto de vista comercial. De hecho, se están realizado pilotos en ciudades como Tokyo, donde se han colocado tags NFC con URLs en los agarramanos del metro. En cambio, desde el punto de vista de la seguridad, y teniendo en cuenta que los exploits en plataformas móviles como Android están a la orden del día, el hecho de que al leer un tag NFC el teléfono visite, automáticamente y sin acción del usuario, un sitio web puede ser un poco peligroso. Ahora mismo me acuerdo de un ejemplo claro, con una redirección a un exploit de Webkit tras leer un QR-Code. Se podría hacer spoofing del tag legítimo para redirigir a los usuarios a un sitio de nuestra elección, por ejemplo.

Aparte de incluir URIs simples en los tags se puede hacer uso del formato SmartPoster para incluir el mismo contenido pero añadiendo ciertos metadatos. Entre estos metadatos se incluye un campo action que indica al lector del SmartPoster si debe realizar la acción automáticamente, abrir para editar o salvar el contenido para un uso posterior. Afortunadamente, por lo menos en el caso del teléfono testeado, no se hace caso de este parámetro, ya que sería un claro descuido de seguridad: llamadas, SMS, Facebook, Skype, etc.

Como comentaba Collin Mulliner en su investigación sobre el tema, anteriormente también era posible incluir saltos de línea y diferentes codificaciones en las URIs para hacer spoofing y engañar al usuario, mostrándole una URI de confianza falsa. Tras algunas pruebas rápidas no se ha visto que se pueda hacer nada relacionado con este tema en el Samsung Galaxy Nexus, aunque podría ser un tema sobre el que seguir investigando. Espero que este post os anime a trastear con NFC y nos comentéis vuestros resultados ;)

 

Nota I: Muchas gracias a Mikel (el del libro) por prestarme su móvil y demás ayudas logísticas ;) 

Nota II: Publicado originalmente en el blog de S21sec