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
- Extrair e analisar o firmware
- Desenvolver um mecanismo de atualização seguro
- 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.

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
| Pin | Signal | Voltage | Function |
|---|---|---|---|
| PB3 | SWCLK | 3.3V | Serial Wire Clock |
| PB4 | SWDIO | 3.3V | Serial Wire Data |
| PA3 | NRST | 3.3V | Reset |
| VDD | Power Supply | 3.3V | System 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

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

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

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
| Address | Name | Description |
|---|---|---|
| 0x5400 | AES1_CR1 | Control Register 1 |
| 0x5401 | AES1_CR2 | Control Register 2 |
| 0x5402 | AES1_DR | Data Register |
| 0x5403 | AES1_KR | Key Register (16 bytes) |
| 0x5404 | AES1_RSR | Round Status Register |
| 0x5405 | AES1_IVR | Initialization 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)
AES1_CR1: 0x03 (binário 00000011)
Etapa 2: Configurar o comprimento da chave
AES1_CR2 |= (1 << AES1_CR2_KEYL); // Set 128-bit key length
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];
}
- Grave os primeiros 8 bytes em
AES1_KR - Aguarde
AES1_RSR[BSY]para limpar - 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

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
| Register | Address | Value (Hex) | Description |
|---|---|---|---|
| AES1_CR1 | 0x5400 | 0x03 | Enabled, system clock |
| AES1_CR2 | 0x5401 | 0x40 | 128-bit key length |
| AES1_KR | 0x5403 | 0x1A2B3C4D | Round key for encryption |
| AES1_DR | 0x5402 | 0x89ABCDEF | Current 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
- Suporte DMA: Use DMA1 para transmitir dados para
AES1_DRpara criptografia contínua - 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:
- Use ST-LINK/V2 para registrar as gravações no registro durante a criptografia
- Compare com os vetores de teste AES-128 NIST
- Valide o tempo usando um osciloscópio (CLK vs RSR.BSY)
Conclusão
- Implementar autenticação por código rolante
- Usar cadeias de inicialização seguras com validação HMAC
- Adotar MCUs modernos como o STM32WB55 com isolamento de hardware
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.
- 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:

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




