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

AuswirkungDetails
VertraulichkeitUmfang: Vertraulichkeit

Speicher lesen - Fertigungsmodus erlaubt uneingeschrankten Speicherzugriff einschließlich Geheimnissen.
IntegritatUmfang: Integritat

Speicher modifizieren - Debug-Fahigkeiten erlauben beliebige Speicheränderungen.
ZugriffskontrolleUmfang: Zugriffskontrolle

Schutzmechanismus umgehen - Sicherheitsprüfungen können im Fertigungsmodus umgangen werden.
AuthentifizierungUmfang: 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

  1. MITRE Corporation. "CWE-1269: Product Released in Non-Release Configuration." https://cwe.mitre.org/data/definitions/1269.html
  2. Intel. "Manufacturing Mode Documentation"
  3. Siemens. "Industrial Control System Security Advisories"