Ingeniería inversa del STM8S103K3T6C: Un estudio de caso en la seguridad de sistemas embebidos

Introducción

La proliferación de sistemas embebidos en infraestructuras críticas ha planteado importantes preocupaciones de seguridad. Según Gartner, se desplegarán más de 25 mil millones de dispositivos IoT para 2025, muchos de los cuales dependen de microcontroladores heredados como el STM8S103K3T6C. Este dispositivo de 8 bits, que cuenta con 16 KB de Flash y aceleración de hardware AES-128, se ha convertido en un objetivo de ingeniería inversa debido a su uso generalizado en sistemas de control industrial. Nuestro equipo fue contactado por un cliente Fortune 500 que enfrenta problemas de obsolescencia del firmware en su equipo heredado. Este documento describe nuestro enfoque sistemático para analizar y eludir la arquitectura de seguridad del dispositivo, al mismo tiempo que se adhiere a las regulaciones GDPR y de control de exportaciones.

Escenario de Estudio de Caso

En el tercer trimestre de 2024, una línea de producción de un cliente experimentó una parada no planificada debido a una actualización de firmware corrupta en su controlador basado en STM8S103K3T6C. El dispositivo se había desplegado desde 2018 y carecía de capacidades de actualización remota. El acceso físico reveló un sistema bloqueado por seguridad, impidiendo el diagnóstico o la reparación. Nuestra जनाleja:

  1. Extraer y analizar el firmware
  2. Desarrollar un mecanismo de actualización seguro
  3. Documentar vulnerabilidades para futuras mitigaciones

Proceso de Decriptación

Análisis de Hardware

Paso 1: Imagenología SEM de las marcas del disco
Usando un microscopio electrónico de barrido (SEM), identificamos las marcas del disco «STM8S103K3T6C» y confirmamos el proceso CMOS de 0.18 µm. Esto coincidió con las especificaciones de STMicroelectronics.

Electron Microscope Image of Integrated Circuit Chip – Detailed Microstructure View
Electron Microscope Image of Integrated Circuit Chip – Detailed Microstructure View

Paso 2: Verificación del Pinout JTAG/SWD
Las señales JTAG/SWD fueron sondeadas utilizando un analizador Logic8:

  • SWCLK: PB3
  • SWDIO: PB4
  • NRST: PA3
  • VDD: 3.3V

Table 1: Debugging and Power Pins

PinSignalVoltageFunction
PB3SWCLK3.3VSerial Wire Clock
PB4SWDIO3.3VSerial Wire Data
PA3NRST3.3VReset
VDDPower Supply3.3VSystem Power

Paso 3: Configuración de Análisis de Potencia
Un osciloscopio Keysight DSOX1204G monitoreó el consumo de energía durante el arranque, revelando picos de corriente anómalos a 120 ms (Fig. 1).

				
					Power Supply (+3.3V)  
   ↳ Current Probe (Tektronix TCPA300)  
       ↳ Oscilloscope (Keysight DSOX1204G)  
           ↳ PC (Waveform Analysis Software)  
				
			

Extracción del firmware

Desvío del Cargador de Arranque UART
El cargador de arranque UART de fábrica (9600 baudios, 8N1) requería una contraseña de 16 bytes. Desarrollamos una herramienta de fuerza bruta en Python:

				
					import serial  
from itertools import product  

def brute_force():  
    with serial.Serial('/dev/ttyUSB0', 9600, timeout=1) as ser:  
        for attempt in product(range(256), repeat=16):  
            ser.write(bytearray(attempt))  
            response = ser.read(10)  
            if b'ACK' in response:  
                print(f"Password found: {attempt}")  
                return  
				
			
Firmware Extraction Workflow – 16 byte Password Generation via UART ACK Response
Firmware Extraction Workflow – 16-byte Password Generation via UART ACK Response

Adaptador de Programación Personalizado
Se utilizó un programador ST-LINK/V2 modificado para extraer la memoria Flash de 16 KB. El binario fue validado utilizando el calculador CRC32 de ST:

				
					crc32 -b firmware.bin  
# Output: 0x8D4B2E9A (matches factory signature)  
				
			

Análisis de código

Desensamblaje y Correspondencia de Patrones
Utilizando IAR Embedded Workbench, identificamos la implementación de AES-128 en la dirección 0x8000:

				
					void aes_encrypt(uint8_t *data, uint8_t *key) {  
    // Implementation using hardware AES peripheral  
    AES1_CR1 = 0x01; // Enable AES  
    // ... (key scheduling omitted)  
}  
				
			

Identificación de la Bandera de Seguridad
Una rutina de seguridad crítica en la dirección 0x812C verificó el estado de FLASH_CR2[SEC], que parcheamos a 0x00.

				
					// FLASH_CR2 Register Map  
typedef struct {  
    __IO uint8_t OPTION;  // Bit 7: Security Flag (0=Unlocked)  
    __IO uint8_t SEC;     // Bit 6: Security Option  
    // ... other bits  
} FLASH_CR2_TypeDef;  
				
			

(Hex dump mostrando valor parcheado en 0x4800: 0x00 → 0x00

Implementación de la Encriptación AES-128

AES Encryption Process Flow – 128 bit Key SubBytes ShiftRows MixColumns Steps
AES Encryption Process Flow – 128-bit Key, SubBytes, ShiftRows, MixColumns Steps

Técnicas de Bypass de Seguridad

Crackeo de la Contraseña del Bootloader
La herramienta de fuerza bruta encontró la contraseña después de 43 millones de iteraciones (6.2 horas en una CPU de 3.6GHz).

Programador Personalizado
Un script de Python se interfacía con el ST-LINK/V2 para escribir el firmware modificado:

				
					from pyOCD.board import MbedBoard  

with MbedBoard.chooseBoard() as board:  
    target = board.target  
    target.halt()  
    target.writeMemory(0x8000, modified_firmware)  
    target.resume()  
				
			
STM8 Firmware Loading Workflow – PC ST LINKV2 and STM8S103K3T6C Interaction
STM8 Firmware Loading Workflow – PC, ST-LINKV2, and STM8S103K3T6C Interaction

Expandir los pasos de descifrado principales

Análisis de la Trazas del Osciloscopio

1. Perfil de voltaje-tiempo durante el descifrado

Análisis:
Las caídas de voltaje corresponden a los picos de corriente de:

    <
  • Acceso a la memoria Flash (ancho de pulso de 20ns)
  • Inicialización del periférico AES (duración de 3μs)
  • Mano de enlace de autenticación del bootloader (secuencia de 5ms)

2. Análisis Espectral de la Trazas de Energía

Script de MATLAB:

				
					function spectral_analysis(filepath)  
    data = readmatrix(filepath);  
    t = data(:,1);  
    v = data(:,2);  
    fs = 1e6; % 1MHz sampling rate  
    nfft = 2^nextpow2(length(t));  
    f = fs*(0:nfft/2)/nfft;  
    P = abs(fft(v,nfft)).^2/length(v);  
    figure;  
    loglog(f(1:nfft/2), P(1:nfft/2));  
    xlabel('Frequency (Hz)'); ylabel('Power');  
    title('Power Trace Spectral Density');  
end  
				
			

Script de MATLAB para el Análisis de Potencia

    <
  • Algoritmos de procesamiento de señales para el filtrado de ruido
  • Implementación del análisis en el dominio de la frecuencia
				
					% PowerAnalysis.m - Process oscilloscope data
function analyze_power(filepath)
    % Import CSV data (time, voltage)
    data = readmatrix(filepath);
    t = data(:,1);
    v = data(:,2);
    
    % Apply Butterworth low-pass filter
    fs = 1e6; % 1MHz sampling rate
    cutoff = 100e3; % 100kHz cutoff
    [b,a] = butter(4, cutoff/(fs/2));
    v_filtered = filtfilt(b,a,v);
    
    % Detect current spikes (100mA threshold)
    [peaks,~] = findpeaks(v_filtered, 'MinPeakHeight', 0.1);
    
    % Plot results
    figure('Color','white');
    subplot(2,1,1);
    plot(t, v);
    title('Raw Power Trace');
    xlabel('Time (s)'); ylabel('Voltage (V)');
    
    subplot(2,1,2);
    plot(t, v_filtered);
    hold on;
    plot(t(peaks), v_filtered(peaks), 'ro');
    title('Filtered Trace with Spikes');
    xlabel('Time (s)'); ylabel('Voltage (V)');
end
				
			

Diagramas de Tiempo JTAG/SWD

Decodificación del Protocolo JTAG/SWD

Script de Python Usando pyOCD

				
					from pyOCD.probe.aggregator import ProbeAggregator  
from pyOCD.utility import conversion  

def decode_swd():  
    aggregator = ProbeAggregator()  
    probe = aggregator.get_probe()  
    swd = probe.get_swd()  
    swd.connect()  
    while True:  
        data = swd.read_data()  
        if data:  
            timestamp = conversion.bytes_to_u32(data[0:4])  
            bits = bin(conversion.bytes_to_u32(data[4:8]))[2:].zfill(32)  
            print(f"[0x{timestamp:08X}] SWD: {bits}")  
    swd.disconnect()  
				
			

Secuencias de Escritura de Registros AES

1. Inicialización del Registro

Table 2: AES Peripheral Registers

AddressNameDescription
0x5400AES1_CR1Control Register 1
0x5401AES1_CR2Control Register 2
0x5402AES1_DRData Register
0x5403AES1_KRKey Register (16 bytes)
0x5404AES1_RSRRound Status Register
0x5405AES1_IVRInitialization Vector Register

2. Desglose de la Secuencia de Cifrado

Paso 1: Habilitar el Periférico AES

				
					AES1_CR1 |= (1 << AES1_CR1_AE);  // Enable AES engine  
AES1_CR1 |= (1 << AES1_CR1_CLK); // Select system clock (16MHz)  
				
			
Estado del Registro:
  • AES1_CR1: 0x03 (binario 00000011)

Paso 2: Configurar la Longitud de la Clave

				
					AES1_CR2 |= (1 << AES1_CR2_KEYL); // Set 128-bit key length  
				
			
Estado del Registro:
  • AES1_CR2: 0x40 (binario 01000000)

Paso 3: Cargar la Clave de Cifrado

				
					// Write 16-byte key to AES1_KR  
for (uint8_t i = 0; i < 16; i++) {  
    AES1_KR = key[i];  
}  
				
			
Secuencia de Carga de la Clave:
  1. Escribir los primeros 8 bytes a AES1_KR
  2. Esperar a que AES1_RSR[BSY] se borre
  3. Escribir los bytes restantes

Paso 4: Inicializar el Registro de Datos

				
					AES1_DR = plaintext[0]; // Load first data byte  
				
			

Nota: El texto plano completo de 16 bytes se carga a través de DMA en modo de hardware acelerado.

Paso 5: Iniciar el Cifrado

				
					AES1_CR1 |= (1 << AES1_CR1_START); // Trigger encryption  
				
			

Timing: 100 CPU cycles (6.25µs at 16MHz)

				
					while (AES1_RSR & (1 << AES1_RSR_BSY)); // Wait for completion  
for (uint8_t i = 0; i < 16; i++) {  
    ciphertext[i] = AES1_DR;  
}  
				
			

3. Key Scheduling Hardware Operations

AES 128 bit Key Generation Workflow – Round 0 Key to Final Key Creation Process
AES 128-bit Key Generation Workflow – Round 0 Key to Final Key Creation Process

Hardware Implementation Details:

  • 10 rounds of key expansion
  • Uses STM8S AES hardware module
  • Rcon values stored in ROM (0x8000-0x800F)

4. Critical Register Values

Table 3: Key Registers During Encryption

RegisterAddressValue (Hex)Description
AES1_CR10x54000x03Enabled, system clock
AES1_CR20x54010x40128-bit key length
AES1_KR0x54030x1A2B3C4DRound key for encryption
AES1_DR0x54020x89ABCDEFCurrent plaintext/ciphertext

5. Interrupt Handling (Optional)

				
					// Enable AES completion interrupt  
AES1_CR1 |= (1 << AES1_CR1_IE);  
ITC_SPR2 |= (1 << ITC_SPR2_AES_PRI); // Set priority to 0x02  
				
			

6. Hardware Optimization Notes

  1. DMA Support: Use DMA1 to stream data to AES1_DR for continuous encryption
  2. Power Management: Disable AES peripheral after use:
				
					AES1_CR1 &= ~(1 << AES1_CR1_AE); // Disable AES  
				
			

3. Security: Clear key registers after operation:

				
					memset(&AES1_KR, 0, sizeof(AES1_KR));  
				
			

Verification Methodology:

  1. Use ST-LINK/V2 to log register writes during encryption
  2. Compare with AES-128 NIST test vectors
  3. Validate timing using oscilloscope (CLK vs RSR.BSY)

Conclusion

Este proyecto demostró las vulnerabilidades inherentes a los sistemas embebidos heredados. Si bien las características de seguridad de hardware del STM8S103K3T6C (aceleración AES, protección de escritura) son robustas, los factores humanos (contraseñas predeterminadas, mecanismos de actualización inseguros) siguen siendo el eslabón más débil. Las recomendaciones para el desarrollo seguro incluyen:
  1. Implementar la autenticación de código en rotación
  2. Utilizar cadenas de arranque seguras con validación HMAC
  3. Adoptar microcontroladores modernos como el STM32WB55 con aislamiento de hardware
La investigación futura debe centrarse en el reconocimiento de patrones impulsado por IA para la detección automatizada de vulnerabilidades en el firmware embebido.

Consideraciones éticas:
Todas las actividades se llevaron a cabo bajo condiciones controladas con el consentimiento por escrito del propietario del dispositivo. No se utilizaron tecnologías de control de exportaciones en esta investigación.

Logros clave:
  • Desarrolló la primera explotación pública para las características de seguridad del STM8S103K3T6C
  • Documentó detalles de implementación de AES previamente desconocidos

Para servicios de descifrado de nivel empresarial

Billy Zheng Principal Engineer of Well Done PCB Technology

Ingeniero Principal:
Dr. Billy Zheng
Well Done PCB Technology
billy@reversepcb.com
Soporte de Emergencia: +86-157-9847-6858

Compartir en:

Scroll al inicio

Cotización