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/



2019/03/20

Jugando con los rayos 1: obteniendo el firmware via serial


Al contexto de esto se llega por el índice.

Los pasos son escribir "tpl" para acceder al monitor y con

md offset length

ir bajando la memoria. Si oprimís enter tiene autoincremento.

Comencé poniendo un peso en la tecla pero no escala, no no. Así que a recordar expect:

#!/usr/bin/expect --
spawn /usr/bin/miniterm.py /dev/ttyUSB1 115200
expect {
  "Autobooting in 1 seconds*" {
    send "tpl\n"
    expect {
      "db12x> " {
         send "md
9f020000 20\n"
         while 1 {
           expect "db12x> " {
             send "\n"
           }
         }
      }
    }
  }
}



y su invocación:

expect capture.tcl > 9f020000.hex

Tras limpiar un poquito con grep, lo convertimos a binario:

grep ":" 9f020000.hex | xxd -r > 9f020000.bin

y ese binario le corremos binwalk:

binwalk -e 9f020000.bin





Te preguntarás de dónde salió la elección de la dirección 9f020000.

db12x> printenv
 

bootargs=console=ttyS0,115200 root=31:02 rootfstype=squashfs init=/sbin/init mtdparts=ath-nor0:256k(u-boot),64k(u-boot-env),6336k(rootfs),1408k(uImage),64k(mib0),64k(ART)
 

bootcmd=bootm 0x9f020000

De paso nos queda este muy útil script, para no tener que estar tipeando "tpl" a gran velocidad:

#!/usr/bin/expect --
spawn /usr/bin/miniterm.py /dev/ttyUSB1 115200
expect {
  "Autobooting in 1 seconds*" {
    send "tpl\n"
    expect {
      "db12x> " {
         interact
         }
      }
    }
  }
}


binwalk obtiene todo excelentemente de las imágenes de firwmare bajadas de tplink, pero de estos volcados no.

La idea seguiente es buscar el firmware.bin en los volcados:

sudo apt install yara



yara es una herramienta para investigar malware, que tiene la capacidad de buscar patrones de datos en archivos, lo cual me viene muy bien para lo que necesito que es hallar el firmware en el dump de memoria de un router dañado por un rayo, si es que es posible.


Mediante acceso al puerto serial del router puedo hacer dumps de la memoria si arranco el monitor que tiene. El router es un TP-LINK WDR3600n.

Tengo la esperanza de que parte de ese dump corresponda a la memoria flash así no tengo que conseguir o armar la pinza soic8 y programar la lectura de la flash, otra nota aparte.

Por el otro tengo varios firmwares, asi que la idea es buscar en dump los firmwares hasta ver si coinciden.


¿Qué hay que buscar? 



Las letritas en hexadecimal.

¿Cómo buscarlo?



sudo apt install yara

ok?

Y crear las reglas, por ejemplo, en yara/rule-firmware.yara

rule Firmware
{
  strings:
    $hex_string = {

      01 00 00 00 54 50 2d 4c  49 4e 4b 20 54 65 63 68
    }

  condition:
    $hex_string
}


Luego ejecutar

yara yara/rule-firmware.yara capture

Sería conveniente que en la carpeta capture sólo estén los binarios, pues yara busca en todo.

Ah, antes, para controlar que todo esté funcionando, podemos buscar algo que sabemos que vamos a encontrar, no olvidemos que nunca antes hemos usado yara y no tenemos idea de que trae ni vamos a leer el manual hasta que nos trabemos:




Acá hemos obtenido unos hexa () que hemos puesto en la regla yara/rule-control.yara y buscado en capture/00000000.bin


Volviendo, tras ejecutar la búsqueda, lo hemos hallado en capture/9f020000.bin, pero no sabemos cual de los tres firmwares es y nos sería útil saber en que punto difieren los firmwares, un poco de bash y listo:




tenemos que hacer una regla para cada firmware tal que llegue hasta un poco más hallá de la diferencia, tipo hasta 0x4f, ok?

Tenemos entonces un archivo de reglas para los tres firmwares que bajamos:


rule Firmware_1
{
  strings:
    $hex_string = {
      01 00 00 00 54 50 2d 4c  49 4e 4b 20 54 65 63 68
      6e 6f 6c 6f 67 69 65 73  00 00 00 00 76 65 72 2e
      20 31 2e 30 00 00 00 00  00 00 00 00 00 00 00 00
      00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
      36 00 00 01 00 00 00 01  00 00 00 00 f1 63 1c 98
    }
 

  condition:
    $hex_string
}
rule Firmware_2
{
  strings:
    $hex_string = {
      01 00 00 00 54 50 2d 4c  49 4e 4b 20 54 65 63 68
      6e 6f 6c 6f 67 69 65 73  00 00 00 00 76 65 72 2e
      20 31 2e 30 00 00 00 00  00 00 00 00 00 00 00 00
      00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
      36 00 00 01 00 00 00 01  00 00 00 00 fd 6a 69 c2
    }

  condition:
    $hex_string
}
rule Firmware_3
{
  strings:
    $hex_string = {
      01 00 00 00 54 50 2d 4c  49 4e 4b 20 54 65 63 68
      6e 6f 6c 6f 67 69 65 73  00 00 00 00 76 65 72 2e
      20 31 2e 30 00 00 00 00  00 00 00 00 00 00 00 00
      00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
      36 00 00 01 00 00 00 01  00 00 00 00 19 2d 99 29
    }

  condition:
    $hex_string
}


Ufa!! no encuentra ninguno, achiquemos... quitándole la quinta linea coincide, eso significa que el firmware que tenemos no es el que bajamos. Vamos a tener que tomar otro camino mientras.

Si recordamos que el objetivo es bajar el firmware en el router, tendríamos que verificar tomando entre el match de la regla y la longitud del firmware si es un firmware.




Si en capture/9f020000.bin, antes de 9F7F0200 (9f020000 + 7d0200) tenemos unos pocos bytes distintos de cero y luego todos ceros y luego todos 0xff, podríamos sospechar que es lo que buscamos. De un modo un otro, tomando el segmento 9f020000 .. 9F7F0200 como si fuera un firmware y ejecutándole binwalk, deberíamos obtener algo parecido a lo que se obtiene de cualquier otro firmware.

Mirando para atras, nos pudimos haber arreglado sin yara. De hecho, no he podido obtener el desplazamiento del match en el archivo y tuve que buscar con grep en el .hex. Pero claro, eso lo sé ahora.

Procedimiento completo


  1. expect capture.tcl | tee 9f020000.hexdump.noisy
  2. grep -P \
    '^[0-9a-f]{8}:( [0-9a-f]{8}){4}    .{16}' \ 9f020000.hexdump.noisy > 9f020000.hexdump
  3. dos2unix 9f020000.hexdump
  4. cut -b 11-45 9f020000.hexdump > 9f020000.hex
  5. xxd 9f020000.hex -r -p > 9f020000.bin
  6. binwalk -e  9f020000.bin

 

Explicaciones


  1. El script capture.tcl invoca el monitor y le pide que haga dump indefinidamente, hasta que uno decida cortar. Para eso está el tee, que va salvando en el archivo mientras muestra en pantalla.
  2. El grep limpia el ruido de todo el diálogo, sólo deja el volcado.
  3. El dos2unix arregla los saltos de linea.
  4. El cut quita las direcciones y el render para que no le molesta a...
  5. El xxd convierte de notación hexadecimal a binario.
  6. El binwalk extrae lo que haya dentro del binario.

Y luego hacemos

cat _9f020000.bin.extracted/squashfs-root/etc/shadow 

que nos da...

root:$1$GTN.gpri$DlSyKvZKMR9A9Uj9e9wR3/:15502:0:99999:7:::

que es lo mismo que teníamos en los otros firmwares, fallamos, no hemos podido ingresar al linux funcionando

Solo nos resta averiguar que firmware es, ¿no?

Un recurso sería buscar el md5 del volcado y los firmwares, pero aunque los archivos comprimidos están, los descomprimidos no. Comprimir el volcado no debería servir, pues debería haberse aplicado exactamente la misma compresión, mmhhh, probemos igual.

for level in {1..9} ; do
   zip firmware$level.zip -"$level" ../capture3/9f020000.bin
done

Lástima que no puedo saber cual es el nombre del archivo original, que forma parte del .zip o sea que influye al hash, dead end.

Dejo acá los hashes de los firmares que tengo...


768584458745f2a5e2ed24cb77ba3d8c  wdr3600v1_en_3_14_1_up_boot(141022).bin
25f0d01aaa74a00a929330d75887a200  wdr3600v1_en_3_14_1_up_boot(150302).bin
faf0c2b2128141c587f06a27d7fabe6a  wdr3600v1_en_3_14_3_up_boot(150518).bin


y del que obtuve:



20b3566386a50ea3afb7fb8330736edb  9f020000.bin


Estos son los que se obtienen en el sitio oficial


7e21d127116d48d0a05e54fc78636ebc  TL-WDR3600_V1_141022.zip
56cf77919b60c32cc6bb49b991881baa  TL-WDR3600_v1_150302.zip
efbdeebd5c85fdb857d23e17d22c4970  TL-WDR3600_V1_150518.zip


No me alcanza, quiero saber que está pasando... dirdiff es mi nueva esperanza.

Esto es dirdiff contra el último oficial, TL-WDR3600_V1_150518:


Primero no veia nada, cuando activé "options -> show files that are identical" me apareció así. Lo comparé con los anteriores y se mantuvo idéntico, sólo cambiando la fecha de modificación. Quedan dos archivos más:


200.7z
7E3C60.7z

que en el los firmwares oficiales tienen otro nombre:

20400.7z
3E60.7z

0328325baa82949c0c063df84b8b6718 _wdr3600v1_en_3_14_3_up_boot(150518)/20400.7z
9f92aa0eaa3d4ebe53660aba5d1d78e5 _wdr3600v1_en_3_14_3_up_boot(150518)/3E60.7z


3d1b44907feb914380a05eb4ccdd2d13 _wdr3600v1_en_3_14_1_up_boot(141022)/20400.7z
f6c55acfa5a2beacf86bccea88ef7be7 _wdr3600v1_en_3_14_1_up_boot(141022)/3E60.7z


c4220429117cbd64cb4372fed422c858 _wdr3600v1_en_3_14_1_up_boot(150302)/20400.7z
ea8a66b8071a63b5ab04bc649b09f8ba _wdr3600v1_en_3_14_1_up_boot(150302)/3E60.7z


348c14f63d8947f43c8d11d6afd0ed38  _wdr3600v1_en_3_14_3_up_boot(150518)/20400
eef72299e5c46f3796cb4c6ce63cf936  _9f020000/7E3C60



Los filesystems son idénticos:

da91975154424bd4e088a8a3f5b808d6 v1_en_3_14_3_up_boot(150518)/120200.squashfs
da91975154424bd4e088a8a3f5b808d6 _9f020000.bin.extracted/100000.squashfs

Esto amerita mucho más investigación, pero como se rompió el router, por ahora no puedo avanzar más.








Jugando con los rayos 0: intro

En mi cuadra cayó un rayo y entre otras cosas se llevó parte del router, un TP-Link WDR3600n, que había elegido por que tiene USB, se puede cambiar con sencillez el firmware y otras tantas virtudes que nunca tuve tiempo de aprovechar... hasta ahora.

Normalmente comparto mis éxitos y errores, este es un caso de fracaso sin responsabilidad, puro aprendizaje.

Tras varios días de trabajo me dí cuenta que esto forma parte de la investigación en curso que vengo haciendo iniciada en la conversación[1]. Tiene tantas ramificaciones que he decido ir haciendo notas independientes, en parte para que la nota principal no sea tan larga y en parte por el MVP, si no tengo una inmensa nota que nunca termino pese a tener un montón de notitas útiles terminadas embebidas.


Me han dicho por ahí que nunca prenda un equipo que emite RF sin las antenas puestas, así que a diferencia de algún video que se puede ver por ahí, las antenas están puestas aunque el equipo esté despanzurrado.



Crónica


Un poco editado el orden pues si no es un interminable amasijo de idas y vueltas.

A la historia completa se accede por el índice.

El primer paso fue obtener una terminal serial, ayudado por [2]. Al igual que en [3], uso una edu-ciaa-nxp como adaptador USB/serial, tras haber controlado que el voltaje fuera el apropiado, 3.3v.



Mi esperanza es ver mensajes de error, ver como reacciona al conectarle y desconectarle cosas y así.

Todo arranca de maravillas, no hay errores evidentes, ni tampoco acceso a root, pues la clave que ronda por Internet no sirve.

Merodeando por ahí, hice algunas pruebas:

USB


Funcion, uno de estos días adunto evidencia, creeme, se ve en dmesg.


Ethernet

Aunque en los mensajes booteo no dice nada, roto, muy roto, tanto LAN como WAN. Algún día intentaré reemplazar los terminadores estos.




Luego los chips ...., pero antes, me han dado la pista que podría haberse roto un chip de alimentación. Es que las resistencias son sólo de LAN y si WAN tambien está rota, un elemento común sería ese.




Firmware

 

Podría continuar los pasos de [2] pues con el nuevo firmware, tendría el root que necesito, salvo que para cambiar el firmware necesito que funcione la red local...mmhhh.

Me bajé entonces el firmware oficial [4] a ver si podía hallar el password. Para esto necesito localizar /etc/shadow, lo cual implica tener que "desarmar" el archivo de boot. Mirando por encima [5] hallé que binwalk es la herramienta que necesitaba. En parte mirando los mensaje de error y en parte mirando https://github.com/ReFirmLabs/binwalk/blob/master/INSTALL.md...


sudo apt install binwalk
sudo apt install squashfs-tools


sudo apt-get install zlib1g-dev liblzma-dev liblzo2-dev
git clone https://github.com/devttys0/sasquatch
cd sasquatch
./build.sh

no me gustó para nada que ./build.sh tenga un sudo adentro, pues yo pensaba instalarlo en otro lado...

binwalk -e imagen.bin


me dejó el shadow tal como necesitaba, con password sohoadmin, que era el que había por todos lados [6] pero no funciona.



tpl


Si lográs escribir bien rápido "tpl" cuando dice "Autobooting in 1 seconds" te beneficiás con acceder al menu de boot [6].




Planes



Plan A - boot options - FAIL


Iniciar el S.O. en runlevel 1 a ver si no me pide la clave, usando la info de [7]

Parece que simplemente no está tomando bootargs, ni lo que yo modifico ni lo presente previamente, pues el kernel dice usar otra cosa.

Hay una entrada en u-boot [1] que aunque dice ser específica a ARM, quizás lo explique, no deben tener un seguimiento de lo que hace cada fabricante.





Lo que hay:
...:256k(u-boot),64k(u-boot-env),6336k(rootfs),1408k(uImage),64k(mib0),...
Lo que le pido:
...:256k(u-boot),64k(u-boot-env),6336k(rootfs),1408k(uImage),64k(mib0),...single

Lo que se usa:
...:128k(u-boot),1024k(kernel),6848k(rootfs),128k(config),... mem=128M

Hay una entrada en u-boot [8] que aunque dice ser específica a ARM, quizás lo explique, no deben tener un seguimiento de lo que hace cada fabricante.



Plan B - leer /etc/shadow actual


Obtener /etc/shadow y de allí la clave de root.


Plan B.1 - dump online via serial - FAIL


Volcar la memoria con lo que ofrece el monitor, a ver si la memoria flash es accesible por acá.

Esto lo desarrollé en la parte 1 y no funcionó. O sea, en el File System la clave es sohoadmin, pero no funciona!

Lo interesante es que lo que se puede bajar parece corresponder al último firmware, pero desordenado. Esto me lleva a tener que aprender más, voy a tener que intentar esto mismo en otros dispositivos.


Plan B.2 - dump offline via lectura de la memoria flash - FAIL


Leer la memoria flash. Habiendo fallado exitosamente el plan B.1 pues lo que se puede bajar aparentemente está desordenado, este es el camino para C.1.

Resultados [en construcción]

Plan C - nueva clave


Si no pudiera hallar la clave, siempre puedo reemplazarla



Plan C.1 - patch


Bajar el firmware, modificar /etc/shadow y volverlo a subir. Depende de B y de aprender a regenerar los checksums que entiendo que hay por ahí.

Plan C.2 - pisar


Subir un nuevo firmware pero pierdo el análisis forense que me permitiría contestar:

¿Por qué no tengo el password del firmware oficial si yo no cambié el firmware?

Resto de aventuras en el índice.



 

[1] Propuesta abierta de actividad ingeniería reversa
https://groups.google.com/forum/#!topic/embebidos32/V9vCEPplgC4

[2] Bricked TP-Link WDR4300 Router Recovery Using UART Serial Converter Part #1

[3]  Serial en Parallella paradumbs: trabajando más cómodo 

[4] Firmware oficial

[5] https://www.secforce.com/blog/2014/04/reverse-engineer-router-firmware-part-1/

[6] https://openwrt.org/toh/tp-link/tl-wdr3600#serie_u-boot

[7] http://redsymbol.net/linux-kernel-boot-parameters/2.6.31/

[8] https://www.denx.de/wiki/view/DULG/LinuxKernelIgnoresMyBootargs