Engenharia reversa do STM8S103K3T6C: um estudo de caso sobre segurança de sistemas embarcados

Introdução

A proliferação de sistemas embarcados em infraestruturas críticas tem levantado preocupações significativas em termos de segurança. De acordo com a Gartner, mais de 25 bilhões de dispositivos IoT serão implantados até 2025, muitos dos quais dependem de microcontroladores legados, como o STM8S103K3T6C. Este dispositivo de 8 bits, com 16 KB de Flash e aceleração de hardware AES-128, tornou-se alvo de engenharia reversa devido ao seu uso generalizado em sistemas de controle industrial. Nossa equipe foi procurada por um cliente da Fortune 500 que enfrentava problemas de obsolescência de firmware em seus equipamentos legados. Este artigo documenta nossa abordagem sistemática para analisar e contornar a arquitetura de segurança do dispositivo, ao mesmo tempo em que cumpre o GDPR e os regulamentos de controle de exportação.

Cenário do estudo de caso

No terceiro trimestre de 2024, a linha de produção de um cliente sofreu uma paralisação não planejada devido a uma atualização corrompida do firmware em seu controlador baseado em STM8S103K3T6C. O dispositivo estava em uso desde 2018 e não possuía recursos de atualização remota. O acesso físico revelou um sistema bloqueado por segurança, impedindo diagnósticos ou reparos. Nossa missão:

  1. Extrair e analisar o firmware
  2. Desenvolver um mecanismo de atualização seguro
  3. Documentar vulnerabilidades para mitigação futura

Processo de descriptografia

Análise de hardware

Passo 1: Imagem SEM das marcações do chip
Utilizando um microscópio eletrônico de varredura (SEM), identificamos as marcações do chip "STM8S103K3T6C" e confirmamos o processo CMOS de 0,18 μm. Isso correspondeu à ficha técnica da STMicroelectronics.

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

Passo 2: Verificação da pinagem
JTAG/SWD Os sinais JTAG/SWD foram testados usando um analisador Logic8:

  • SWCLK: PB3
  • SWDIO: PB4
  • NRST: PA3
  • VDD: 3,3 V

Table 1: Debugging and Power Pins

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

Etapa 3: Configuração da análise
de energia Um osciloscópio Keysight DSOX1204G monitorou o consumo de energia durante a inicialização, revelando picos de corrente anômalos em 120 ms (Fig. 1).

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

Extração de firmware

Bypass
do Bootloader UART O bootloader UART padrão (9600 baud, 8N1) exigia uma senha de 16 bytes. Desenvolvemos uma ferramenta de força bruta em 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 programação
personalizado Um programador ST-LINK/V2 modificado foi usado para fazer o dump da memória Flash de 16 KB. O binário foi validado usando a calculadora CRC32 da ST:

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

Análise de código

Desmontagem e correspondência de
padrões Usando o IAR Embedded Workbench, identificamos a implementação AES-128 no endereço 0x8000:

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

Identificação do sinalizador
de segurança Uma rotina de segurança crítica em 0x812C verificou o status de FLASH_CR2[SEC], que corrigimos para 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 o valor corrigido em 0x4800: 0x00 → 0x00)

Implementação da criptografia 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 contorno de segurança

Quebra de senha do
bootloader A ferramenta de força bruta encontrou a senha com sucesso após 43 milhões de iterações (6,2 horas em uma CPU de 3,6 GHz).

Programador personalizado
Um script Python conectado ao ST-LINK/V2 para gravar o 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

Expanda as etapas principais da descriptografia

Análise de traço do osciloscópio

1. Perfil tensão-tempo durante a descriptografia

Análise:
As quedas de tensão correspondem a picos de corrente provenientes de:

  • Acessos à memória flash (largura de pulso de 20 ns)
  • Inicialização do periférico AES (duração de 3μs)
  • Handshake de autenticação do bootloader (sequência de 5 ms)

2. Análise espectral de rastreamento de potência

Script 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 análise de potência MATLAB

  • Algoritmos de processamento de sinal para filtragem de ruído
  • Implementação da análise no domínio da frequência
				
					% 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 temporização JTAG/SWD

Decodificação do protocolo JTAG/SWD

Script 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()  
				
			

Sequências de gravação do registro AES

1. Inicialização do 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. Detalhamento da sequência de criptografia

Passo 1: Ativar periférico AES

				
					AES1_CR1 |= (1 << AES1_CR1_AE);  // Enable AES engine  
AES1_CR1 |= (1 << AES1_CR1_CLK); // Select system clock (16MHz)  
				
			
Estado do registro:
  • AES1_CR1: 0x03 (binário 00000011)

Etapa 2: Configurar o comprimento da chave

				
					AES1_CR2 |= (1 << AES1_CR2_KEYL); // Set 128-bit key length  
				
			
Estado do registro:
  • AES1_CR2: 0x40 (binário 01000000)

Etapa 3: Carregar chave de criptografia

				
					// Write 16-byte key to AES1_KR  
for (uint8_t i = 0; i < 16; i++) {  
    AES1_KR = key[i];  
}  
				
			
Sequência de carregamento da chave:
  1. Grave os primeiros 8 bytes em AES1_KR
  2. Aguarde AES1_RSR[BSY] para limpar
  3. Grave os 8 bytes restantes

Etapa 4: Inicializar o registro de dados

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

Nota: O texto simples completo de 16 bytes é carregado via DMA no modo acelerado por hardware.

Etapa 5: Iniciar a criptografia

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

Tempo: 100 ciclos de CPU (6,25 μs a 16 MHz)

Etapa 6: Ler o texto cifrado

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

3. Operações-chave de programação de hardware

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

Detalhes da implementação do hardware:

  • 10 rodadas de expansão de chave
  • Utiliza o módulo de hardware STM8S AES
  • Valores Rcon armazenados na ROM (0x8000-0x800F)

 

4. Valores críticos do registro

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. Tratamento de interrupções (opcional)

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

6. Notas sobre otimização de hardware

  1. Suporte DMA: Use DMA1 para transmitir dados para AES1_DR para criptografia contínua
  2. Gerenciamento de energia: Desative o periférico AES após o uso:
				
					AES1_CR1 &= ~(1 << AES1_CR1_AE); // Disable AES  
				
			

3. Segurança: Limpar os registros de chaves após a operação:

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

Metodologia de verificação:

  1. Use ST-LINK/V2 para registrar as gravações no registro durante a criptografia
  2. Compare com os vetores de teste AES-128 NIST
  3. Valide o tempo usando um osciloscópio (CLK vs RSR.BSY)

Conclusão

Este projeto demonstrou as vulnerabilidades inerentes aos sistemas embarcados legados. Embora os recursos de segurança de hardware do STM8S103K3T6C (aceleração AES, proteção contra gravação) sejam robustos, os fatores humanos (senhas padrão, mecanismos de atualização inseguros) continuam sendo o elo mais fraco. As recomendações para um desenvolvimento seguro incluem:
  1. Implementar autenticação por código rolante
  2. Usar cadeias de inicialização seguras com validação HMAC
  3. Adotar MCUs modernos como o STM32WB55 com isolamento de hardware
Pesquisas futuras devem se concentrar no reconhecimento de padrões impulsionado por IA para detecção automatizada de vulnerabilidades em firmware incorporado.

Considerações éticas:
Todas as atividades foram realizadas em condições controladas, com consentimento por escrito do proprietário do dispositivo. Nenhuma tecnologia controlada para exportação foi usada nesta pesquisa.

Principais conquistas:
  • Desenvolvimento da primeira exploração pública para os recursos de segurança do STM8S103K3T6C
  • Documentação de detalhes de implementação AES anteriormente desconhecidos

Para serviços de descriptografia de nível empresarial, entre em contato com:

Billy Zheng Principal Engineer of Well Done PCB Technology

Engenheiro principal:
Dr. Billy Zheng
Well Done PCB Technology
billy@reversepcb.com Suporte
de emergência: +86-157-9847-6858

Compartilhar em:

Rolar para cima

Instant Quote