2019/03/24

Jugando con los rayos 2: obteniendo el firmware via spi


Circunstancias

Un rayo me ha dejado afuera de un router, más detalles en [1] o el índice.

Motivación y objetivos

La lectura por serial usando el monitor de U-boot además de ser lenta, quizás no sea fidedigna, pueden haber partes no accesibles o que estén en un orden distinto [2].

Para la escritura la situación es peor.

Lo que deseo es leer el firmware que hay en la memoria flash por medio de la interfaz SPI, preferentemente usando una EDU-CIAA-NXP [3] y/o CIAA-NXP [4] ya que no quiero gastar plata en un programador ni seguir juntando cosas de uso poco frecuente ni tener que usar programas ajenos.

Tambien ejercitar el ingenio y adiestrarme en hardware hacking.

La síntesis de todo esto sería desarrollar o adaptar el software y la configuración para poder leer y escribir mediante la EDU-CIAA-NXP o CIAA-NXP y poder repetirlo con sencillez en otras placas.

Arriba a la izquierda, EDU-CIAA-NXP haciendo de conversor USB-serial.

Eso azul abajo a la derecha es un pela naranjas, muy muy bueno para abrir los gabinetes.


Identificación de componentes y pines

Se trata de un chip winbond 25q64f




Verificación de conexión a soic8


Que haya contacto y que no hayan cortos. Para lo último hay que probar que no haya continuidad entre pines adyacentes.

Para ello primero hay que buscar pistas de referencia:

A la derecha el conector serial: Vcc, GND, Rx, Tx.




Resultado:


Cuesta bastante que haga el contacto correcto, hubiese sido más fácil soldar en las pistas de referencia, quizás cuando llegue el momento de escribir sea buena idea.


Pinza soic8 a protoboard

Verificación de actividad y voltaje



Prender y ver que traza deja en el analizador lógico y/u osciloscopio.

Resultado:





Hay actividad en
  • /CS: SI
  • DO (IO1): SI
  • WP (IO2): SI
  • /Hold (IO3): SI
  • DI (IO0): SI
  • CLK: SI
Desde mi profundo desconocimiento pero habiendo leido la datasheet, intuyo que está usando el modo en el cual ejecuta código directo desde la flash, pues está usando todos los pines, probablement Quad SPI.


Planificación de acceso

 


Si no va a ser desoldado el chip, el resto de la placa va a ser energizada, ya sea normalmente o por alimentar el chip.

En el segundo caso hay que ver que no deje la misma traza que en la verificación anterior.

Si la hubiera, o sea, si se estuviera activando la CPU, habría que ver la manera de activarle el reset, que obviamente no es el botón de reset, si así fuera no diría cosas como "press and hold WPS/Reset Button during powering on until WPS LED turns on" [5].

Resultado:


Al alimentar no parece arrancar la CPU pues no hay actividad en el puerto serial y aunque /CS se va para arriba, no tiene actividad posterior.


Al centro a la derecha, con el cable blanco se puede apreciar el adaptar 5v -> 3.3 v de un protoboard.



Reflexión


Habiendo llegado tan lejos, en este momento debería retroceder un poco e intentar capturar el comando de cambio de modo, pero me supera.

Prueba de concepto: Implementación lectura con GPIO

Enviar el comando SPI Read Data (03h) y una dirección de 24 bits. Leer 7 bytes para ver si coinciden con el texot "TP-LINK" esperado. La escritura del comando mediante la placa, detectar la lectura con el analizador lógico u osciloscopio.

La dirección debe ser 0x000000000004 para saltear valores menores a 32 en las posiciones 0 a 3 que no se pueden ver en la terminal.




Dificultad elegida a fines didácticos: no puedo usar código ajeno.

Segunda dificultad con los mismos fines: no puedo usar la interfaz SPI que tiene la EDU-CIAA-NXP.



Para leer datos:

The Standard/Dual/Quad SPI instruction set of the W25Q64FV consists of thirty six basic instructions that are fully controlled through the SPI bus. Instructions are initiated with the falling edge of Chip Select (/CS). The first byte of data clocked into the DI input provides the instruction code. Data on the DI input is sampled on the rising edge of clock with most significant bit (MSB) first.

Data on all four IO pins are sampled on the rising edge of clock with most significant bit (MSB) first.

Instructions are completed with the rising edge of edge /CS.

En particular:

The Read Data instruction allows one or more data bytes to be sequentially read from the memory. The instruction is initiated by driving the /CS pin low and then shifting the instruction code “03h” followed by a 24-bit address (A23-A0) into the DI pin. The code and address bits are latched on the rising edge of the CLK pin. After the address is received, the data byte of the addressed memory location will be shifted out on the DO pin at the falling edge of CLK with most significant bit (MSB) first. The address is automatically incremented to the next higher address after each byte of data is shifted out allowing for a continuous stream of data. This means that the entire memory can be accessed with a single instruction as long as the clock continues. The instruction is completed by driving /CS high.



Necesito que mi programa adaptador USB<->serial crezca, que entienda si le envío una orden y la ejecute utilizando GPIO.



Resultado:


Conecté desde GPIO00 a GPIO06  pares a /CS, CLK, DO y DI respectivamente, modifiqué el programa adaptador para que interprete los caracteres '#' y '$' como órdenes y tras muchas idas y vueltas revisando el mapeo en el programa, ajustando que los cambios y lecturas en DI y DO fueran entre flancos de CLK y ajustando la pinza (ya dije por ahí que voy a soldarle cables, no?) en el osciloscopio se vé bastante bien.


Se vé en amarillo /CS que baja y sube, en cyan está CLK, en azul DI y en magenta DO, la respuesta.

Se pueden ver el 0x03 del read y el 0x000000000004 de la dirección en DI del comando '#'.



Traza completa para dirección 0x000000000004


En DO (magenta) se ve la respuesta



Traza completa para dirección 0x000000000006

El comando '$' es la dirección 0x000000000006, fijate que hay dos pulsitos azules en el segundo grupo.

En otras muestras CLK no tiene esos escalones, sospecho que tienen que ver un problema eléctrico, de hecho si no está conectado el osciloscopio

Y acá está la ejecución de '#$$'

Feedback por terminal USB a la PC

Se puede apreciar que hay un desplazamiento de dos, coherente con que pedimos la 0x6 ( que es igual a 0x4 + 2). Tambien que el mismo comando dá la misma respuesta.

Lo que no me cierra es que yo esperaba algo como lo amarillo.


xxd -b "wdr3600v1_en_3_14_3_up_boot(150518).bin"

Lo que tampoco me cierra es que a veces aparece eso, otras todo FFFF, otras todo 0000, es muy inestable, tengo dos caminos, usar la interfaz SPI o reemplazar la pinza por alguna intervención más permanente.



Prueba de concepto, implementación lectura con SPI


Voy a basarme en el ejemplo de escritura de SD de la sAPI, estoy usando Firmware_V2 [6], copio acá el diagrama de conexión:

Gracias Éric

 

Puedo empezar a morder del ejemplo de escritura de SD de la sAPI, que llama a spiConfig(). Tras un git grep spiConfig llegamos a modules/lpc4337_m4/sapi/inc/sapi_spi.h que es tan sencillo como:


bool_t spiConfig( spiMap_t spi );
bool_t spiRead( spiMap_t spi, uint8_t* buffer, uint32_t bufferSize );
bool_t spiWrite( spiMap_t spi, uint8_t* buffer, uint32_t bufferSize);



No sé para qué me metí a hacerlo con GPIO. Igual le desconfío, por lo que tengo entendido hasta ahora, ¿qué pasa si uno no llama inmediatamente spiWrite() tras spiRead()? Es que según el dibujito:

A la izquierda arriba se vé lo del Mode 0/3
en el flanco ascendente del pulso 31 de CLK  se lee el LSB del último byte de dirección y en el descendente ya empieza a transmitir por DO.

Me imagino que lo que hace spiWrite()es dejar CLK arriba, pues en las tablas de valores la frecuencia mínima es DC:

...y los tiempos mínimos están en ns, mil veces más rápido que lo que estoy manejando


y no es así, los bloques de la derecha supuestamente son los de lectura.

Se puede apreciar que hay bloques de 8 pulsos




Cancelación prematura


Intentando eliminar el factor pinza soic8 berreta, mientras soldaba y probaba hallé una elevada conductividad entre Vcc y GND. Buscando el calor, llegué al chip atheros ar8327 7 port low power managed/layer3 gigabit switch with hardware nat, que supera los 100°c. Puede ser que terminara de morir por si mismo, no olvidemos que por ahí pasó un rayo o que hay algún corto en otro lado producto de mi intervención, nunca lo sabré.

Quizás, quizás no fui yo, pues antes de intervenir dejé de recibir el patrón que aunque no era el que esperaba, era siempre el mismo.

Es una pena el momento, pues he puesto unos cables muy bonito.

El paso siguiente era calar el costado del gabinete y asomar el conector por ahí para poder seguir jugando con aquel armado.


Le puedo poner un jumper para elegir alimentar la flash desde el router o externamente.

Conectando 14-16, es la alimentación externa, 15-16 interna.






Planes de contingencia




Supongo que la memoria está ok aún, pero no la estoy pudiendo leer onboard probablemente por la falla del chip del switch. Tengo dos caminos:

Desoldar el chip de memoria


Pros

  • Es muy fácil y disminuyen los factores desconocidos sobre las fallas de acceso.

Contras

  • Lo leo, lo escribo, fin del camino, tiro el router al cajón del futuro.

Desoldar el chip del switch

 

Contras

  • Veo bastante difícil que pueda desoldar el chip sin hacer un desastre.

Pros

  • Si fallara, puedo ir por el otro plan.
  • Si lo hiciera bien y no hubiera otra falla, probablemente podría seguir usando el router.

Como se puede ver de como estructuré el texto previo, espero que no hayan dudas acerca del camino.

Extracción del chip del switch

En otro experimiento relacionado a reemplazar el lpc4337 del la EDU-CIAA-NXP por un lpc43s37, que tiene en lugar de un M0 como dual core un "acelerador criptográfico", extraje el chip de la placa, con resultados no muy buenos, me llevé algunas pistas conmigo debido a falta de paciencia.

Esta es una segunda oportunidad, por un lado un poco más difícil pues los pines son más chicos. Por el otro mejor, pues sólo estoy arriesgando componentes que ya doy por perdidos.


Resultado

Falla monumental no catastrófica, la EDU-CIAA-NXP sigue funcionando y he descubierto varias cosas:

Es imposible con mis herramientas sacar el chip del switch, al menos en una sola pieza, con daños colaterales de efectos imprevisibles.

No había contado antes que al desoldar la patita de Vcc de la flash había arrancado la pista, evidentemente tiré antes de tiempo. Luego, ya en retirada, cuando desoldé mis lindos cables, la patita terminó de cortarse, con lo cual se me dificulta inmensamente poder conectar la flash al entorno planeado.

Doy por terminada esta parte de la experiencia, luego pensaré como retomar, ya sea leyendo esta FLASH u otra en otro dispositivo y la posterior transferencia, por serial o vía una memoria SD.

El router yace en el cajón del futuro.



Todo el código, en github, https://github.com/cpantel/Flash-via-SPI



[1] https://seguridad-agile.blogspot.com/2019/03/jugando-con-los-rayos-0-intro.html
[2] https://seguridad-agile.blogspot.com/2019/03/jugando-con-los-rayos-1-obteniendo-el.html
[3] http://www.proyecto-ciaa.com.ar/index_comprar_educiaanxp.html
[4] http://www.proyecto-ciaa.com.ar/index_comprar_ciaanxp.html
[5] https://openwrt.org/toh/tp-link/tl-wdr3600#tftp_auto_recovery_in_revision_15
[6] https://github.com/ciaa/firmware_v2/tree/master/sapi_examples/edu-ciaa-nxp/bare_metal/spi_01_sdCard_fatFileSystem/



No hay comentarios:

Publicar un comentario