Produkt in Nicht-Release-Konfiguration ausgeliefert
Beschreibung
Produkt in Nicht-Release-Konfiguration ausgeliefert tritt auf, wenn ein Produkt in einer Vorproduktions- oder Fertigungskonfiguration statt in einem finalisierten Release-Zustand auf den Markt kommt. Vorproduktions- und Fertigungsphasen beinhalten umfangreiche Debug-Fahigkeiten, die Sicherheitslücken schaffen, einschließlich der Fahigkeit, kryptografische Prüfungen zu umgehen (Authentifizierung, Autorisierung, Integritat), Zugriff zum Lesen/Schreiben/Ändern des internen Zustands (Register, Speicher), Fahigkeiten zur Änderung der Systemkonfiguration und versteckte Befehle, die geistiges Eigentum freilegen. Wenn der "Manufacturing Complete"-Marker vor der Auslieferung nicht aktiviert wird, bleibt das System verwundbar.
Risiko
Nicht-Release-Konfiguration hat schwerwiegende Sicherheitsauswirkungen. Debug-Schnittstellen bleiben zuganglich. Authentifizierung kann umgangen werden. Speicher kann frei gelesen und geschrieben werden. Interner Zustand kann modifiziert werden. Kryptografische Prüfungen können deaktiviert werden. Geistiges Eigentum kann freigelegt werden. Systemkonfiguration kann geändert werden. Unbefugter Code kann ausgeführt werden. Vollständige Systemkompromittierung ist möglich.
Lösung
Etablieren Sie einen Manufacturing-Complete-Marker. Stellen Sie sicher, dass der Marker bei Fertigungsabschluss durch Mechanismen wie Fuse-Aktivierung aktualisiert wird. Verifizieren Sie die Release-Konfiguration vor der Auslieferung. Implementieren Sie Prüfungen, die den Produktionsmodus erzwingen. Testen Sie, dass Debug-Funktionen im Release ordnungsgemäß deaktiviert sind. Dokumentieren und befolgen Sie sichere Fertigungsverfahren.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Vertraulichkeit | Umfang: Vertraulichkeit Speicher lesen - Fertigungsmodus erlaubt uneingeschrankten Speicherzugriff einschließlich Geheimnissen. |
| Integritat | Umfang: Integritat Speicher modifizieren - Debug-Fahigkeiten erlauben beliebige Speicheränderungen. |
| Zugriffskontrolle | Umfang: Zugriffskontrolle Schutzmechanismus umgehen - Sicherheitsprüfungen können im Fertigungsmodus umgangen werden. |
| Authentifizierung | Umfang: Authentifizierung Authentifizierung umgehen - Authentifizierung kann im Fertigungsmodus deaktiviert sein. |
Beispielcode und Lösung
Verwundbarer Code
// VERWUNDBAR: Gerat ohne Manufacturing-Complete-Prüfung
module vulnerable_security_controller (
input wire clk,
input wire reset_n,
// Debug-Schnittstelle
input wire debug_request,
input wire [31:0] debug_addr,
input wire [31:0] debug_data,
input wire debug_write,
output reg [31:0] debug_read_data,
output reg debug_granted,
// Fertigungs-Fuse
input wire manufacturing_complete_fuse,
// Secure Boot
input wire boot_request,
output reg boot_allowed
);
// VERWUNDBAR: Manufacturing-Complete-Fuse wird NICHT geprüft
// Produkt wird mit nicht gebrannter Fuse ausgeliefert (manufacturing_complete_fuse = 0)
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
debug_granted <= 1'b0;
boot_allowed <= 1'b0;
end
else begin
// VERWUNDBAR: Debug immer gewahrt - keine Fuse-Prüfung
if (debug_request) begin
debug_granted <= 1'b1;
// Uneingeschrankter Speicherzugriff
if (debug_write) begin
memory[debug_addr] <= debug_data;
end
else begin
debug_read_data <= memory[debug_addr];
end
end
// VERWUNDBAR: Secure Boot kann umgangen werden
if (boot_request) begin
boot_allowed <= 1'b1; // Immer erlaubt!
end
end
end
endmodule
// VERWUNDBAR: UART-Debug im Produktionsmodus aktiviert
module vulnerable_uart_debug (
input wire clk,
input wire reset_n,
input wire uart_rx,
output wire uart_tx,
// Fertigungsmodus
input wire mfg_mode_fuse
);
// VERWUNDBAR: Fertigungsmodus-Fuse nicht gebrannt
// mfg_mode_fuse = 0 bedeutet Fertigungsmodus aktiv
// Verfügbare Debug-Befehle
parameter CMD_READ_MEM = 8'h01;
parameter CMD_WRITE_MEM = 8'h02;
parameter CMD_DUMP_SECRETS = 8'h03;
parameter CMD_BYPASS_AUTH = 8'h04;
reg [7:0] command;
reg [31:0] address;
reg [31:0] data;
always @(posedge clk) begin
// VERWUNDBAR: Keine Prüfung auf Produktionsmodus
// Diese Befehle funktionieren auch nach Auslieferung
case (command)
CMD_READ_MEM: begin
// Beliebige Speicherstelle lesen
uart_send(memory[address]);
end
CMD_WRITE_MEM: begin
// Beliebige Speicherstelle schreiben
memory[address] <= data;
end
CMD_DUMP_SECRETS: begin
// VERWUNDBAR: Alle Geheimnisse ausgeben
uart_send(encryption_key);
uart_send(private_key);
end
CMD_BYPASS_AUTH: begin
// VERWUNDBAR: Authentifizierung überspringen
authenticated <= 1'b1;
end
endcase
end
endmodule
// VERWUNDBAR: Software ohne Fertigungsprüfung
#include <stdint.h>
#define FUSE_REG_ADDR 0x40000000
#define MFG_COMPLETE_BIT 0
// VERWUNDBAR: Manufacturing-Complete-Fuse nicht geprüft
bool is_manufacturing_mode(void) {
uint32_t fuse_value = *(volatile uint32_t*)FUSE_REG_ADDR;
return (fuse_value & (1 << MFG_COMPLETE_BIT)) == 0;
}
void vulnerable_boot(void) {
// VERWUNDBAR: Debug unabhängig vom Fertigungsstatus aktiviert
enable_debug_uart();
enable_jtag();
// VERWUNDBAR: Signaturprüfung im Fertigungsmodus uberspringen
if (is_manufacturing_mode()) {
// Dieser Codepfad sollte im ausgelieferten Produkt nicht existieren!
execute_unsigned_firmware();
}
else {
if (verify_signature()) {
execute_firmware();
}
else {
halt();
}
}
// Problem: Produkt mit nicht gebrannter Fuse ausgeliefert
// is_manufacturing_mode() gibt true zurück
// Angreifer kann unsignierte Firmware ausführen!
}
void vulnerable_handle_debug_command(uint8_t cmd, uint32_t* args) {
// VERWUNDBAR: Keine Fertigungsmodus-Prüfung
// Diese Befehle funktionieren auf ausgelieferten Produkten
switch (cmd) {
case DEBUG_CMD_READ_MEM:
// Beliebigen Speicher lesen
uart_send(*(volatile uint32_t*)args[0]);
break;
case DEBUG_CMD_WRITE_MEM:
// Beliebigen Speicher schreiben
*(volatile uint32_t*)args[0] = args[1];
break;
case DEBUG_CMD_EXTRACT_KEY:
// VERWUNDBAR: Kryptographischen Schlüssel extrahieren
uart_send_buffer(crypto_key, 32);
break;
case DEBUG_CMD_DISABLE_SECURITY:
// VERWUNDBAR: Gesamte Sicherheit deaktivieren
security_enabled = false;
break;
}
}
Sichere Lösung
// SICHER: Gerat mit ordnungsgemäßer Manufacturing-Complete-Durchsetzung
module secure_security_controller (
input wire clk,
input wire reset_n,
input wire debug_request,
input wire [31:0] debug_addr,
input wire [31:0] debug_data,
input wire debug_write,
output reg [31:0] debug_read_data,
output reg debug_granted,
output reg debug_denied,
input wire manufacturing_complete_fuse,
input wire boot_request,
input wire signature_valid,
output reg boot_allowed,
output reg boot_denied
);
// SICHER: Produktions- vs. Fertigungsmodus bestimmen
wire is_production = manufacturing_complete_fuse;
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
debug_granted <= 1'b0;
debug_denied <= 1'b0;
boot_allowed <= 1'b0;
boot_denied <= 1'b0;
end
else begin
debug_granted <= 1'b0;
debug_denied <= 1'b0;
boot_denied <= 1'b0;
// SICHER: Debug nur im Fertigungsmodus verfügbar
if (debug_request) begin
if (!is_production) begin
// Fertigungsmodus - Debug erlaubt
debug_granted <= 1'b1;
end
else begin
// SICHER: Produktionsmodus - Debug abgelehnt
debug_denied <= 1'b1;
debug_read_data <= 32'hDEADBEEF;
end
end
// SICHER: Secure Boot im Produktionsmodus erzwungen
if (boot_request) begin
if (is_production) begin
if (signature_valid) begin
boot_allowed <= 1'b1;
end
else begin
boot_denied <= 1'b1;
end
end
else begin
boot_allowed <= 1'b1;
end
end
end
end
endmodule
// SICHER: UART mit Fertigungsmodus-Durchsetzung
module secure_uart_debug (
input wire clk,
input wire reset_n,
input wire uart_rx,
output wire uart_tx,
input wire mfg_mode_fuse, // 1 = Produktion, 0 = Fertigung
output reg mfg_mode_violation
);
wire is_production = mfg_mode_fuse;
reg [7:0] command;
reg command_valid;
// SICHER: Debug-Befehlsbehandlung mit Modus-Prüfung
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
mfg_mode_violation <= 1'b0;
end
else if (command_valid) begin
mfg_mode_violation <= 1'b0;
// SICHER: Alle Debug-Befehle im Produktionsmodus blockieren
if (is_production) begin
// Verletzungsversuch protokollieren
mfg_mode_violation <= 1'b1;
// Fehler an UART zurückgeben
uart_send_error();
end
else begin
// Fertigungsmodus - Befehle erlaubt
case (command)
CMD_READ_MEM: uart_send(memory[address]);
CMD_WRITE_MEM: memory[address] <= data;
// Hinweis: Sensible Befehle können weiterhin eingeschränkt sein
CMD_DUMP_SECRETS: begin
// Auch im Fertigungsmodus zusätzliche Auth erfordern
if (mfg_authenticated) begin
// Erlaubt
end
else begin
uart_send_error();
end
end
endcase
end
end
end
endmodule
// SICHER: Manufacturing-Complete-Verifizierung
module mfg_complete_checker (
input wire clk,
input wire reset_n,
input wire mfg_fuse,
input wire check_enable,
output reg mfg_complete,
output reg check_failed
);
// SICHER: Verifizieren dass Fuse ordnungsgemäß gebrannt ist
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
mfg_complete <= 1'b0;
check_failed <= 1'b0;
end
else if (check_enable) begin
// Fuse mehrfach lesen um Zuverlässigkeit sicherzustellen
if (mfg_fuse && mfg_fuse && mfg_fuse) begin
mfg_complete <= 1'b1;
check_failed <= 1'b0;
end
else if (!mfg_fuse && !mfg_fuse && !mfg_fuse) begin
mfg_complete <= 1'b0;
check_failed <= 1'b0;
end
else begin
// Inkonsistente Lesevorgänge - mögliche Manipulation
check_failed <= 1'b1;
end
end
end
endmodule
// SICHER: Software mit ordnungsgemäßer Fertigungsmodus-Behandlung
#include <stdint.h>
#include <stdbool.h>
#define FUSE_REG_ADDR 0x40000000
#define MFG_COMPLETE_BIT 0
// SICHER: Umfassende Fertigungsmodus-Prüfung
static bool is_manufacturing_mode(void) {
volatile uint32_t* fuse_reg = (volatile uint32_t*)FUSE_REG_ADDR;
// SICHER: Mehrfach lesen um Glitching zu verhindern
uint32_t read1 = *fuse_reg;
uint32_t read2 = *fuse_reg;
uint32_t read3 = *fuse_reg;
// Alle Lesevorgange müssen übereinstimmen
if (read1 != read2 || read2 != read3) {
// Inkonsistent - Produktionsmodus annehmen (sicherer Standard)
log_security_event("Fuse-Leseinkonsistenz - nehme Produktionsmodus an");
return false;
}
return (read1 & (1 << MFG_COMPLETE_BIT)) == 0;
}
void secure_boot(void) {
bool mfg_mode = is_manufacturing_mode();
if (mfg_mode) {
log_info("Fertigungsmodus aktiv");
enable_debug_uart();
enable_jtag();
}
else {
// SICHER: Produktionsmodus - Debug deaktivieren
disable_debug_uart();
disable_jtag();
lock_debug_interface(); // Reaktivierung verhindern
}
// SICHER: Secure Boot im Produktionsmodus immer erforderlich
if (!mfg_mode) {
if (!verify_signature()) {
log_error("Signaturverifizierung fehlgeschlagen");
enter_secure_halt();
return;
}
}
execute_firmware();
}
// SICHER: Debug-Befehle nur im Fertigungsmodus
int secure_handle_debug_command(uint8_t cmd, uint32_t* args) {
// SICHER: Fertigungsmodus für jeden Befehl prüfen
if (!is_manufacturing_mode()) {
log_security_event("Debug-Befehl im Produktionsmodus blockiert");
return -EPERM;
}
// Zusätzliche Authentifizierung auch im Fertigungsmodus
if (!is_debug_authenticated()) {
log_security_event("Debug-Authentifizierung erforderlich");
return -EAUTH;
}
switch (cmd) {
case DEBUG_CMD_READ_MEM:
// Eingeschränktes Lesen im Fertigungsmodus
if (!is_address_debug_readable(args[0])) {
return -EACCES;
}
uart_send(*(volatile uint32_t*)args[0]);
break;
case DEBUG_CMD_WRITE_MEM:
if (!is_address_debug_writable(args[0])) {
return -EACCES;
}
*(volatile uint32_t*)args[0] = args[1];
break;
case DEBUG_CMD_EXTRACT_KEY:
// SICHER: Schlüsselextraktion niemals erlauben, auch nicht im Fertigungsmodus
log_security_event("Schlüsselextraktionsversuch");
return -EPERM;
default:
return -EINVAL;
}
return 0;
}
// SICHER: Fertigungsabschluss-Prozedur
int finalize_manufacturing(void) {
// Verifizieren dass Gerat für Produktion bereit ist
if (!run_self_tests()) {
return -EFAULT;
}
// SICHER: Manufacturing-Complete-Fuse brennen
if (blow_mfg_complete_fuse() != 0) {
log_error("Brennen der Manufacturing-Complete-Fuse fehlgeschlagen");
return -EIO;
}
// SICHER: Verifizieren dass Fuse gebrannt ist
if (is_manufacturing_mode()) {
log_error("Fertigungsmodus nach Fuse-Brennen noch aktiv");
return -EFAULT;
}
// SICHER: Verifizieren dass Debug deaktiviert ist
if (is_debug_accessible()) {
log_error("Debug nach Finalisierung noch zuganglich");
return -EFAULT;
}
log_info("Fertigungsfinalisierung abgeschlossen");
return 0;
}
CVE-Beispiele
- CVE-2019-13945: SIMATIC S7-1200/S7-200 Fertigungszugriffsmodus aktivierte Diagnose über UART
- CVE-2018-4251: Intel-Chipsatz-Laptops im Manufacturing Mode mit aktivierten Debug-Fahigkeiten entdeckt
Verwandte CWEs
- CWE-693: Versagen des Schutzmechanismus (ubergeordnet)
- CWE-1191: On-Chip Debug-/Test-Schnittstelle mit unzureichender Zugriffskontrolle (verwandt)
- CWE-489: Aktiver Debug-Code (verwandt)
- CAPEC-439: Manipulation während der Verteilung (Angriffsmuster)
Referenzen
- MITRE Corporation. "CWE-1269: Product Released in Non-Release Configuration." https://cwe.mitre.org/data/definitions/1269.html
- Intel. "Manufacturing Mode Documentation"
- Siemens. "Industrial Control System Security Advisories"