Ataques de hardware a microcontroladores usando ChipWhisperer y métodos de protección contra ellos


Los ataques de hardware representan una gran amenaza para todos los dispositivos con microcontroladores (en adelante, MK), ya que pueden eludir varios mecanismos de seguridad. Es difícil defenderse de tales ataques usando software o hardware. Por ejemplo, puede leer un artículo de STMicroelectronics sobre varios tipos de ataques de hardware y métodos para proteger MK.
Nosotros, el equipo de Raccoon Security, estamos interesados ​​en este tema, ya que una de las áreas de actividad de nuestra empresa es el desarrollo de dispositivos integrados, incluidos los que contienen mecanismos de protección de la información. En su mayor parte, estamos interesados ​​en los ataques de falla, ya que le permiten pasar las instrucciones MK ejecutables. Esta es una seria amenaza para la información confidencial contenida en MK, y la consecuencia más peligrosa de tales ataques es leer el firmware cerrado, sin pasar por los mecanismos de seguridad proporcionados por los desarrolladores de MK.


En Hardwear.io 2018 en La Haya y EmbeddedWorld 2019 en Nuremberg, NewAE demostró el dispositivo ChipWhisperer, que permite la implementación de esa parte de los ataques de hardware no invasivos que no requieren un conocimiento profundo de la nanoelectrónica y la disponibilidad de equipos específicos. Usando este dispositivo, estudiamos la seguridad de los dispositivos integrados y descubrimos cómo minimizar el resultado de tales ataques. Debajo del corte, lo que hicimos.


Chipwhisperer


El kit ChipWhisperer es un kit de herramientas de código abierto para analizar la seguridad de los MK más populares (STM, Xmega, Intel D2000, SAM, LPC, MSP, 78K y otros) y FPGA. El proyecto comenzó el 27 de febrero de 2015 en Kickstarter . Por el momento, hay diferentes versiones de ChipWhisperer (todas las opciones se pueden encontrar en el catálogo ). Tienen un conjunto diferente de herramientas, pero generalmente están orientados a los siguientes tipos de ataques de hardware:


• ataques de canal lateral (SCA);


• ataques de falla.


Para un análisis más detallado, elegimos ChipWhisperer-Pro (CW1200), que es el modelo ChipWhisperer más antiguo en este momento y tiene una amplia funcionalidad y un gran paquete:



Kit ChipWhisperer (CW1200)


A bordo, el CW1200 tiene un osciloscopio, que consiste en un amplificador ajustable y un ADC con una muestra de 105 MSPS. Este conjunto de herramientas le permite registrar el nivel de señal en centésimas de milivoltios y obtener una buena base de tiempo. También en el CW1200 hay puertos para organizar CLK-glitch y Vcc-glitch, puertos GPIO que pueden asignarse como disparadores de entrada para rastrear el origen de un evento (solicitud de ingreso de contraseña, estado de descarga, etc.). El CW1200 se conecta a una PC a través de USB y tiene dos protocolos de comunicación con MK: UART y SPI.


Para trabajar con ChipWhisperer, debe instalar controladores, descargar bibliotecas de Python y ejemplos de trabajo de GitHub, o descargar la imagen preparada de una máquina virtual en Linux, en la que todas las bibliotecas y ejemplos de trabajo están preinstalados. Estas bibliotecas abiertas contienen:


• protocolo de comunicación con ChipWhisperer;


• algoritmos matemáticos para procesar ataques en métodos de encriptación populares;


• protocolos para comunicarse con los gestores de arranque de MK populares;


• firmware preparado para el entrenamiento en las placas con MK, incluido en el kit.


Decidimos revisar todos los tutoriales en el antiguo sitio web de NewAE. Ahora se está desarrollando otro recurso , donde se presenta información más relevante y hay un foro .


En este artículo, presentaremos solo algunos ejemplos de guías de los desarrolladores de ChipWhisperer y las implementaremos no en las placas con MK que se incluyen en el paquete, sino en el STM32F103RBT6:



Junta STM32F103RBT6


También escribimos código idéntico a sus ejemplos preparados, pero con bibliotecas HAL generadas a partir de CubeMX. Todas estas acciones son necesarias para confirmar que los ataques con ChipWhisperer se pueden implementar en cualquier dispositivo aleatorio, y no solo en las placas presentes en el kit.


A continuación, ofrecemos una breve descripción general y ejemplos de ataques SCA y ataques de falla.


Análisis SCA


La base de los ataques SCA es rastrear los cambios en los factores externos del estado de la MC (consumo actual de la MC, temperatura, campo electromagnético) durante el desarrollo de varias instrucciones. ChipWhisperer implementa canales para monitorear la energía usando un ADC y un campo electromagnético usando una antena.


El análisis SCA es efectivo para detectar contraseñas, claves de cifrado, etc. El sitio web de NewAE presenta muchas características diferentes
Pautas útiles para encontrar claves de cifrado y para ataques SCA , pero daremos solo un ejemplo de análisis SCA, ya que los ataques de falla son de gran interés para nosotros.


Ejemplo de ataques SCA: análisis de firma de potencia


Esta guía muestra un tipo de ataque SCA: el seguimiento de la entrada de contraseña carácter por carácter mediante el monitoreo de las firmas en el canal de alimentación. Al repetir las firmas de energía, es posible identificar el desarrollo de varias instrucciones de programa dentro del MK. El ejemplo anterior demuestra el desarrollo de la entrada de contraseña MK mediante el seguimiento de la firma de la operación de break .


Comencemos la preparación. En primer lugar, debe hacer las conexiones de acuerdo con la figura:



Conexión MC para análisis SCA


El diagrama tacha componentes que no necesitan estar conectados (a diferencia de la conexión MK estándar). Las flechas indican los puntos de conexión de ChipWhisperer, y las firmas indican sus pines.


Prepare el firmware MK. La siguiente función está en el ciclo principal while while(1) :


 028 void password_check() { 029 char passwd[32]; 030 char correct_passwd[] = "Vulkan"; 031 HAL_Delay(10); 032 uart_send("WARNING: UNAUTHORIZED ACCESS WILL BE PUNISHED\n"); 033 led_off(); 034 035 //Get password 036 uart_send("Please enter password to continue: "); 037 uart_receive(passwd, 32); 038 039 uint8_t passbad = 0; 040 041 led_on(); 042 043 for(uint8_t i = 0; i < sizeof(correct_passwd); i++) 044 { 045 if (correct_passwd[i] != passwd[i]) 046 { 047 passbad = 1; 048 break; 049 } 050 } 051 052 if (passbad) 053 { 054 //Stop them fancy timing attacks 055 int wait = rand() % 100000; 056 for(volatile int i = 0; i < wait; i++) 057 { 058 ; 059 } 060 HAL_Delay(4); 061 uart_send("PASSWORD FAIL\n"); 062 } 063 else 064 { 065 uart_send("Access granted, Welcome!\n"); 066 } 067 while(1) 068 { 069 ; 070 } 071 } 

La línea 030 establece la contraseña para la entrada: Vulkan. Luego, el LED se enciende
led_on() y se envía un mensaje UART sobre la solicitud de contraseña. La función led_on() activa el pin GPIO de PA12 MK y notifica un evento con respecto al cual ChipWhisperer comenzará a acumular formas de onda. Es a este pin que CW_TRIG debe estar conectado. Todo esto se "sintetiza" por conveniencia, pero en casos reales la diferencia será insignificante, ya que puede ingresar un retraso de tiempo en la cantidad de ciclos de reloj RELOJ en relación con cualquier evento al que esté conectado CW_TRIG. Por ejemplo, puede ser el inicio de la descarga de MK, la recepción / transmisión de mensajes, la inclusión de un LED, etc.


Además, MK espera a que se ingrese una contraseña, que verificará carácter por carácter. Si algún carácter de la cola no coincide, por ejemplo, tres caracteres son correctos y el cuarto no, entonces debe salir del bucle for con la instrucción break e informar la contraseña incorrecta. En las líneas 055–059, se implementa un generador de retardo aleatorio. Este diseño se usa con mayor frecuencia para complicar la realización de ataques temporales (es decir, rastrear cambios en el tiempo de respuesta de todo el sistema). Este diseño se incluye para comprender que no seleccionamos una contraseña utilizando el método de ataque temporal.


El código tutorial de Jupyter Python está alojado en el recurso correspondiente. La siguiente figura muestra un ejemplo de introducción de una contraseña con la salida de la forma de onda de la fuente de alimentación del MK con cada nuevo símbolo correcto. Tenga en cuenta que con el ingreso de caracteres de la contraseña correcta (la contraseña a ingresar se muestra en la parte superior de la figura), la firma de la operación de break se desplaza a la línea 046 (resaltada en naranja en la figura a continuación). Esta es la "debilidad" de la interrupción por la operación de break cuando se verifica la contraseña por contraseña.



Oscilogramas de contraseña


Como resultado de la familiarización con esta guía, descubrimos lo fácil que es eludir la protección con contraseña con este enfoque para verificarlo mediante el análisis SCA. Es suficiente comentar la operación de break en la línea 048 en este firmware y, en general, la verificación de contraseña será tan exitosa, pero el procesamiento del seguimiento de firmas se volverá más complicado. Por lo tanto, para reducir la efectividad de tales ataques, debe evitar la operación de interrupción inmediata de los ciclos de exploración.


La complejidad de este análisis radica en encontrar las firmas necesarias. Por lo tanto, realizar tales ataques puede complicar significativamente la introducción de construcciones temporales de rand() en el momento de la verificación de la contraseña, agregar cálculos adicionales o agregar ruido a otros componentes.


Ataques de falla


Los ataques de falla se llevan a cabo mediante una serie de impulsos a corto plazo en un momento exacto según un determinado método de influencia. Los métodos más populares son: reloj (falla CLK), potencia (falla Vcc) y campo electromagnético. El campo electromagnético es generado por una chispa de alto voltaje cerca del MC. Para esto, NewAE utiliza equipos ChipSHOUTER . No lo compramos, por lo que solo realizamos los ataques CLK-glitch y Vcc-glitch.


Los ataques de falla se llevan a cabo agregando un pulso de voltaje: para falla de CLK - a la señal de RELOJ externa del MK (de un cuarzo o generador externo), para falla de Vcc - en potencia.


En general, los ataques de falla le permiten omitir cualquier instrucción MK, por ejemplo, ingresar una contraseña, solicitud de acceso, acuerdo de licencia, etc. Los ataques de falla son más complejos, laboriosos y lentos. Además, es necesario repetir repetidamente el ataque de falla, ya que su éxito es de naturaleza probabilística y depende de los parámetros del pulso. Las siguientes son opciones de falla:


• scope.glitch.width - ancho de pulso en porcentaje relativo a CLOCK;


• scope.glitch.offset: desplazamiento de impulso en porcentaje relativo a CLOCK;


• scope.glitch.repeat: el número de repeticiones de pulsos de ataque;


• scope.glitch.ext_offset: el número de medidas omitidas después del desencadenante del evento.


Las asignaciones de glitch para CLK-glitch y Vcc-glitch se muestran en los diagramas de tiempos:



Diagrama de tiempos para CLK-glitch



Diagrama de tiempos para Vcc-glitch


Todos los parámetros del pulso de falla se seleccionan para que el núcleo MK funcione en un modo inestable (debido a que se omiten las instrucciones).


Según los resultados de los ataques fallidos, se reveló que si el valor del parámetro scope.glitch.repeat es demasiado pequeño, no se produce el "deslizamiento" de las instrucciones. Si establece un valor grande, puede omitir no solo las instrucciones necesarias, sino también todas las posteriores. En la mayoría de los casos, buscar scope.glitch.repeat en la región de 5–25 es suficiente. Con respecto a otros parámetros, todo depende del tipo de ataque y las condiciones de conexión.


Falla de CLK


Los ataques de falla CLK se llevan a cabo agregando pulsos de menor duración a la señal CLOCK MK. Por lo tanto, CLOCK debe estar desconectado del MK y alimentarlo desde ChipWhisperer ya con un ataque de falla CLK.


Primero necesitas conectar ChipWhisperer a MK:



Diagrama de conexión para CLK-glitch


Todo el código Python y una descripción detallada del manual se presentan en el recurso . Luego, en STM32F103RBT6, "llene" el firmware, donde se agrega la siguiente función al while(1) principal while(1) :


 075 void glitch_password(void) 076 { 077 char inp[16]; 078 char c = 'A'; 079 unsigned char cnt = 0; 080 uart_send("Password:"); 081 082 while((c != '\n') & (cnt < 16)) 083 { 084 c = getch(); 085 inp[cnt] = c; 086 cnt++; 087 } 088 089 char passwd[] = "Vulkan"; 090 char passok = 1; 091 092 led_on(); 093 led_off(); 094 095 //Simple test - doesn't check for too-long password! 096 for(cnt = 0; cnt < 5; cnt++) 097 { 098 if (inp[cnt] != passwd[cnt]) 099 { 100 passok = 0; 101 } 102 } 103 if (!passok){ 104 uart_send("Denied\n"); 105 } 106 else 107 { 108 uart_send("Wow! Vulkan win!\n"); 109 } 110 } 

Nuestro objetivo es omitir la if en la línea 103 al ingresar la contraseña incorrecta y entrar en el caso else en la línea 106. Lo más importante en este ataque es verificar la variable passok en la línea 103. Para hacer esto, seleccione el parámetro scope.glitch.ext_offset. Esto es más fácil de hacer conectando el osciloscopio al UART y configurando la falla en la ubicación de la interferencia, ya que la falla se filtra a través de todo el MK:



Ubicación de falla


El código de ataque y la metodología están tomados de este manual (sección de bucle de ataque, bloques 9-10). Lo único que cambiamos en el código fue habilitar la salida de todos los mensajes de print(response) sin filtrar, ya que los eventos importantes a menudo se omiten debido a filtros configurados como:


 if need_response not in response: pass else: print ("!") 

Las siguientes figuras muestran ejemplos de un registro de salida de mensaje que aparece cuando un ataque de falla de CLK está cerca del éxito o está lejos de tener éxito. Al acercarse a los parámetros de falla correctos, comienzan a aparecer inestabilidades en la operación del MK (los mensajes se rompen, el MK se reinicia). Esto puede ser una pista al buscar.



Salida de mensaje durante un ataque de falla con parámetros que están lejos de ser exitosos (a) y cercanos al éxito (b)



El resultado de un exitoso ataque CLK-glitch


Como resultado de los ataques, se reveló que los parámetros del pulso de falla CLK pueden "flotar" dependiendo de la calidad de la conexión ChipWhisperer al CLOCK MK. Por ejemplo, al configurar la sonda del osciloscopio en el pin CLOCK, el parámetro scope.glitch.offset se volvió diferente para un ataque exitoso, ya que la sonda tiene sus propios parámetros capacitivos inductivos que corrigen la falla de alta frecuencia. Por lo tanto, la conexión a través de un cable largo sin blindaje puede traer sus sorpresas. De lo contrario, los ataques CLK-glitch pueden llamarse estables, como sus parámetros cambiaron ligeramente para varias instrucciones (si, para, mientras se verificaron).


El método de protección contra tales ataques es usar la señal interna CLOCK MK, pero tiene la peor estabilidad de temperatura y tiempo. Además, un método eficaz puede ser la introducción de un retraso de tiempo aleatorio antes y después de instrucciones importantes (verificación de contraseñas, datos personales, etc.), lo que puede complicar el golpe exacto del pulso de falla CLK en el momento adecuado.


Vcc-glitch


Vcc-glitch, como CLK-glitch, introduce interferencia de alta frecuencia en la operación del MK, solo haciendo un cortocircuito en la fuente de alimentación del MK a tierra. Al realizar ataques de falla Vcc, se debe tener en cuenta que los parámetros de un pulso exitoso dependen de muchos factores, tales como:


• características de diseño de la placa de circuito impreso para MK y la presencia de un flejado diverso;


• longitud del cable coaxial para la conexión MK y el puerto de falla de ChipWhisperer (cuanto más largo sea el cable, menos posibilidades de un ataque exitoso, la longitud óptima es de 10-15 cm);


• serie MK;


• instrucciones que se deben omitir;


• Optimización del compilador MK;


• tipo de transistor MOSFET (debido a la diferencia en los componentes de alta frecuencia de los parámetros S).


Por lo tanto, al realizar ataques, es necesario asegurarse de que estos parámetros no cambien.


Primero debes conectar ChipWhisperer a MK:



Esquema de conexión para ataques de falla Vcc


A continuación, "flasheamos" el firmware en MK, donde en el while(1) principal while(1) existe la siguiente función:


 115 void glitch_while() 116 { 117 volatile uint8_t infinity = 0; 118 uart_send(" Hello habr!"); 119 led_on(); 120 led_off(); 121 122 while(infinity != 2) 123 { 124 ; 125 } 126 uart_send("WOW!!! Vcc Glitch work!"); 127 while(1) 128 { 129 ; 130 } 131 } 

MK después de enviar el mensaje "¡Hola, habr!" Entra en un bucle sin fin en la línea 122. Nuestra tarea es eliminar MK de este bucle utilizando Vcc-glitch. En este bucle, la variable de volatile uint8_t infinity se usa como condición, que nunca será igual a dos cuando el programa se volatile uint8_t infinity normalmente. Si ponemos while(1) lugar de while(infinity != 2) , el compilador ignoraría el código a continuación, incluido nuestro mensaje que anuncia la salida del bucle infinito. Debido a una variable de tipo volatile compilador no podrá hacer esto. El while(1) línea 127 se agrega para que después del WOW !!! Vcc Glitch funciona! no hemos vuelto a mostrar Hola habr!


Utilizamos el código Python para controlar ChipWhisperer desde esta guía . Aquí están los mensajes de MK:



El resultado de un exitoso ataque Vcc-glitch


Como se puede ver en la figura, el ataque Vcc-glitch fue exitoso.


La dificultad para realizar un ataque de falla Vcc radica en la selección de los parámetros de pulso correctos. La implementación de este ataque tomó el tiempo más largo en comparación con los demás, ya que la implementación exitosa de los ataques de falla Vcc depende de los factores descritos anteriormente.


Un método de protección contra tales ataques también puede ser la introducción de un retraso de tiempo aleatorio antes de las instrucciones importantes y después de ellas (verificación de contraseñas, datos personales, etc.). Esto puede complicar el golpe exacto del pulso de falla Vcc en el momento adecuado. Un aumento en el acoplamiento capacitivo entre la alimentación y la tierra durante el cableado de la PCB también puede ayudar un poco.


Conclusiones


Los ataques realizados te permiten eludir las instrucciones en MK. Un ejemplo de un análisis SCA mostró que incluso el tipo más simple de tal ataque puede amenazar la seguridad de sus datos (contraseñas, claves de cifrado). Nos aseguramos de que los ataques de fallas eluden varias instrucciones y métodos de protección de software provistos en los dispositivos. El método universal de protección contra ataques en los manuales considerados puede ser la introducción de retrasos aleatorios al ejecutar instrucciones importantes en el MC.


Nuestro estudio de los ataques de hardware no termina ahí. En el futuro, planeamos explorar la posibilidad de omitir la verificación del byte de firmware del firmware MK utilizando ataques Vcc-glitch. El acceso al firmware de MK puede abrir grandes oportunidades para un atacante: desde la clonación de un dispositivo para reventa hasta el acceso completo a toda la información de propiedad y el control sobre MK.


En nuestros experimentos con Vcc-glitch, intentamos evitar la protección del firmware, y lo logramos. Nos aseguramos de que esto sea posible. En el próximo artículo presentaremos experimentos que demuestran la lectura del firmware oculto de MK.



Raccoon Security es un equipo especial de expertos en el Centro Científico y Técnico Volcano en el campo de la seguridad práctica de la información, la criptografía, los circuitos, la ingeniería inversa y la creación de software de bajo nivel.

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


All Articles