Einschluss undokumentierter Funktionen oder Chicken Bits

Beschreibung

Einschluss undokumentierter Funktionen oder Chicken Bits tritt auf, wenn ein Gerät Chicken Bits oder undokumentierte Funktionen enthält, die Einstiegspunkte für unautorisierte Akteure schaffen können. Geräte enthalten oft undokumentierte Bits -- umgangssprachlich "Chicken Bits" genannt -- um funktionale Sicherheitsfunktionen zu Debugging- und Testzwecken zu deaktivieren. Diese Mechanismen erleichtern die schnelle Identifizierung fehlerhafter Komponenten oder Funktionen, die die Leistung negativ beeinflussen. Ähnliche Schwachstellen entstehen durch die Implementierung undokumentierter Funktionen selbst. Wenn diese Funktionen in Produktionsgeräten verbleiben, können sie von Angreifern entdeckt und ausgenutzt werden.

Risiko

Undokumentierte Funktionen und Chicken Bits haben schwerwiegende Sicherheitsauswirkungen. Sicherheitsfunktionen können durch versteckte Bits deaktivierbar sein. Debug-Zugriff kann in Produktion verfügbar sein. Backdoors können in Hardware oder Firmware existieren. Secure Boot kann umgehbar sein. Speicherschutz kann deaktivierbar sein. Verschlüsselung kann umgehbar sein. Rechteeskalation kann möglich sein. Supply-Chain-Angriffe können versteckte Funktionalität ausnutzen.

Lösung

Die Implementierung von Chicken Bits in einem veröffentlichten Produkt wird dringend abgeraten. Falls implementiert, stellen Sie sicher, dass sie in Produktionsgeräten deaktiviert bleiben. Dokumentieren Sie alle Geräteschnittstellen umfassend. Entfernen oder deaktivieren Sie Debug-Funktionen per Fuse vor der Produktion. Führen Sie gründliche Sicherheitsaudits auf undokumentierte Funktionalität durch. Implementieren Sie sichere Herstellungsprozesse. Testen Sie auf Entdeckung undokumentierter Funktionen. Verwenden Sie Hardware-Fuses, um Debug-Funktionen permanent zu deaktivieren.

Häufige Auswirkungen

AuswirkungDetails
Vertraulichkeit, Integrität, Verfügbarkeit, ZugriffskontrolleBereich: Alle

Mehrere Auswirkungen einschließlich Speichermodifikation, unautorisiertem Lesen, Ausführung nicht autorisierten Codes, Rechteeskalation, Identitätsannahme und Umgehung von Schutzmechanismen.

Beispielcode und Lösung

Verwundbarer Code

// VERWUNDBAR: Chicken Bits zum Deaktivieren von Sicherheitsfunktionen

module vulnerable_security_controller (
    input wire clk,
    input wire reset_n,
    input wire [31:0] write_data,
    input wire write_enable,
    input wire [7:0] register_addr,
    // Sicherheitsfunktionen
    output reg secure_boot_enabled,
    output reg memory_encryption_enabled,
    output reg debug_locked,
    output reg access_control_enabled
);

    // VERWUNDBAR: Undokumentiertes Register an Adresse 0xFF
    // Enthält "Chicken Bits" zum Deaktivieren der Sicherheit
    reg [31:0] chicken_bits;

    // Normale Sicherheitskonfiguration
    reg [31:0] security_config;

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            security_config <= 32'hFFFFFFFF;  // Alle Sicherheit aktiviert
            chicken_bits <= 32'h0;
        end
        else if (write_enable) begin
            case (register_addr)
                8'h00: security_config <= write_data;
                // VERWUNDBAR: Undokumentierte Adresse
                8'hFF: chicken_bits <= write_data;
            endcase
        end
    end

    // Sicherheitsfunktionen können über Chicken Bits deaktiviert werden!
    always @(*) begin
        // Normale Sicherheitseinstellung UND NICHT Chicken-Bit-Überschreibung
        secure_boot_enabled = security_config[0] && !chicken_bits[0];
        memory_encryption_enabled = security_config[1] && !chicken_bits[1];
        debug_locked = security_config[2] && !chicken_bits[2];
        access_control_enabled = security_config[3] && !chicken_bits[3];
    end

    // Angriff: 0xF an Adresse 0xFF schreiben, um alle Sicherheit zu deaktivieren

endmodule

// VERWUNDBAR: Versteckte UART-Debug-Schnittstelle
module vulnerable_hidden_debug (
    input wire clk,
    input wire reset_n,
    input wire uart_rx,
    output reg uart_tx,
    // Speicherschnittstelle
    output reg [31:0] debug_addr,
    output reg [31:0] debug_wdata,
    output reg debug_write,
    output reg [31:0] debug_rdata
);

    reg [7:0] command_buffer [0:15];
    reg [3:0] cmd_index;

    // VERWUNDBAR: Undokumentierte UART-Befehle
    parameter CMD_READ_MEM = 8'hA5;
    parameter CMD_WRITE_MEM = 8'h5A;
    parameter CMD_EXEC_CODE = 8'hE0;  // Beliebigen Code ausführen!
    parameter CMD_DISABLE_SEC = 8'hD5;  // Sicherheit deaktivieren!

    always @(posedge clk) begin
        if (uart_byte_received) begin
            command_buffer[cmd_index] <= uart_data;
            cmd_index <= cmd_index + 1;

            // Befehl verarbeiten wenn vollständig
            if (cmd_index == 5) begin
                case (command_buffer[0])
                    CMD_READ_MEM: begin
                        debug_addr <= {command_buffer[1], command_buffer[2],
                                      command_buffer[3], command_buffer[4]};
                        // Gibt Speicherinhalt über UART zurück
                    end
                    CMD_WRITE_MEM: begin
                        debug_addr <= {command_buffer[1], command_buffer[2],
                                      command_buffer[3], command_buffer[4]};
                        debug_wdata <= uart_data;
                        debug_write <= 1'b1;
                    end
                    CMD_DISABLE_SEC: begin
                        // VERWUNDBAR: Deaktiviert Sicherheit ohne Authentifizierung!
                        security_disabled <= 1'b1;
                    end
                endcase
            end
        end
    end

endmodule

// VERWUNDBAR: Undokumentierter Testmodus
module vulnerable_test_mode (
    input wire clk,
    input wire reset_n,
    input wire [3:0] gpio_pins,
    output reg test_mode_active,
    output reg security_bypass
);

    // VERWUNDBAR: Geheime GPIO-Sequenz aktiviert Testmodus
    parameter SECRET_SEQUENCE = 12'hA5A;
    reg [11:0] gpio_history;

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            gpio_history <= 12'h0;
            test_mode_active <= 1'b0;
            security_bypass <= 1'b0;
        end
        else begin
            gpio_history <= {gpio_history[7:0], gpio_pins};

            // VERWUNDBAR: Geheime Sequenz aktiviert Testmodus
            if (gpio_history == SECRET_SEQUENCE) begin
                test_mode_active <= 1'b1;
                security_bypass <= 1'b1;  // Alle Sicherheit deaktiviert!
            end
        end
    end

endmodule
// VERWUNDBAR: Firmware mit undokumentierten Funktionen

// VERWUNDBAR: Versteckte Debug-Befehlsschnittstelle
#define SECRET_DEBUG_PORT 0xDEAD
#define SECRET_COMMAND_KEY 0xCAFEBABE

struct hidden_command {
    uint32_t magic;      // Muss SECRET_COMMAND_KEY sein
    uint8_t command;
    uint32_t address;
    uint32_t data;
};

void process_network_packet(uint8_t* data, size_t len) {
    // Normale Paketverarbeitung
    handle_normal_packet(data, len);

    // VERWUNDBAR: Auf versteckte Debug-Befehle prüfen
    if (len >= sizeof(struct hidden_command)) {
        struct hidden_command* cmd = (struct hidden_command*)data;

        if (cmd->magic == SECRET_COMMAND_KEY) {
            // Undokumentierte Debug-Befehle – keine Authentifizierung!
            switch (cmd->command) {
                case 0x01:  // Speicher lesen
                    send_response(*(uint32_t*)cmd->address);
                    break;
                case 0x02:  // Speicher schreiben
                    *(uint32_t*)cmd->address = cmd->data;
                    break;
                case 0x03:  // Secure Boot deaktivieren
                    disable_secure_boot_check = true;
                    break;
                case 0x04:  // Code ausführen
                    ((void(*)(void))cmd->address)();
                    break;
            }
        }
    }
}

// VERWUNDBAR: Chicken Bit in Konfiguration
#define SECURITY_CONFIG_REG 0x40001000
#define CHICKEN_BIT_DISABLE_ENCRYPTION (1 << 31)  // Undokumentiert!

void vulnerable_init(void) {
    // Jemand könnte das Chicken Bit entdecken und setzen
    // Deaktiviert Verschlüsselung vollständig
}

Sichere Lösung

// SICHER: Keine Chicken Bits in Produktionshardware

module secure_security_controller (
    input wire clk,
    input wire reset_n,
    input wire [31:0] write_data,
    input wire write_enable,
    input wire [7:0] register_addr,
    input wire production_fuse,  // In Produktion gebrannt
    // Sicherheitsfunktionen - in Produktion immer aktiviert
    output wire secure_boot_enabled,
    output wire memory_encryption_enabled,
    output wire debug_locked,
    output wire access_control_enabled
);

    reg [31:0] security_config;

    `ifdef DEBUG_BUILD
        // Debug-Chicken-Bits - NUR in Debug-Builds
        reg [31:0] debug_override;
    `endif

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            security_config <= 32'hFFFFFFFF;
            `ifdef DEBUG_BUILD
                debug_override <= 32'h0;
            `endif
        end
        else if (write_enable) begin
            case (register_addr)
                8'h00: security_config <= write_data;
                `ifdef DEBUG_BUILD
                    8'hFF: if (!production_fuse) debug_override <= write_data;
                `endif
                // Keine Chicken Bits an 0xFF in Produktion!
            endcase
        end
    end

    // Sicherheitsfunktionen - keine Überschreibung in Produktion
    `ifdef DEBUG_BUILD
        assign secure_boot_enabled = production_fuse ?
            security_config[0] : (security_config[0] && !debug_override[0]);
        // usw.
    `else
        // SICHER: Produktions-Build hat keine Umgehungsfähigkeit
        assign secure_boot_enabled = security_config[0];
        assign memory_encryption_enabled = security_config[1];
        assign debug_locked = security_config[2];
        assign access_control_enabled = security_config[3];
    `endif

endmodule

// SICHER: Debug-Schnittstelle entfernt oder ordnungsgemäß gesichert
module secure_debug_interface (
    input wire clk,
    input wire reset_n,
    input wire debug_fuse_blown,  // Permanente Deaktivierung
    input wire [255:0] debug_challenge,
    input wire [255:0] debug_response,
    input wire debug_auth_request,
    output reg debug_authenticated,
    output reg debug_enabled
);

    // Debug nur verfügbar wenn:
    // 1. Fuse nicht gebrannt (nur Entwicklung)
    // 2. Ordnungsgemäße kryptographische Authentifizierung

    wire [255:0] expected_response;
    wire response_valid;

    crypto_auth auth (
        .challenge(debug_challenge),
        .response(debug_response),
        .valid(response_valid),
        .expected(expected_response)
    );

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            debug_authenticated <= 1'b0;
            debug_enabled <= 1'b0;
        end
        else if (debug_fuse_blown) begin
            // SICHER: Fuse deaktiviert Debug permanent
            debug_enabled <= 1'b0;
            debug_authenticated <= 1'b0;
        end
        else if (debug_auth_request && response_valid) begin
            // SICHER: Kryptographische Authentifizierung erforderlich
            debug_authenticated <= 1'b1;
            debug_enabled <= 1'b1;
        end
    end

endmodule

// SICHER: Alle Register dokumentiert, keine versteckten Adressen
module secure_register_bank (
    input wire clk,
    input wire reset_n,
    input wire [31:0] write_data,
    input wire write_enable,
    input wire [7:0] register_addr,
    output reg [31:0] read_data
);

    // Alle Register sind dokumentiert
    reg [31:0] config_reg;      // 0x00 - Dokumentiert
    reg [31:0] status_reg;      // 0x04 - Dokumentiert
    reg [31:0] control_reg;     // 0x08 - Dokumentiert
    // Keine versteckten Register!

    always @(posedge clk or negedge reset_n) begin
        if (!reset_n) begin
            config_reg <= 32'h0;
            status_reg <= 32'h0;
            control_reg <= 32'h0;
        end
        else if (write_enable) begin
            case (register_addr)
                8'h00: config_reg <= write_data;
                8'h04: status_reg <= write_data;
                8'h08: control_reg <= write_data;
                // SICHER: Unbekannte Adressen ignoriert, keine versteckte Funktionalität
                default: ; // Nichts tun
            endcase
        end
    end

    always @(*) begin
        case (register_addr)
            8'h00: read_data = config_reg;
            8'h04: read_data = status_reg;
            8'h08: read_data = control_reg;
            default: read_data = 32'h0;  // Unbekannt gibt Null zurück
        endcase
    end

endmodule
// SICHER: Keine undokumentierten Funktionen in Produktionsfirmware

typedef enum {
    CMD_STATUS = 0x01,
    CMD_CONFIG = 0x02,
    CMD_RESET = 0x03
    // Keine versteckten Befehle!
} command_t;

void process_command(uint8_t cmd, void* data) {
    // Alle Befehle erfordern Authentifizierung
    if (!is_authenticated()) {
        return;
    }

    switch (cmd) {
        case CMD_STATUS:
            send_status();
            break;
        case CMD_CONFIG:
            update_config(data);
            break;
        case CMD_RESET:
            system_reset();
            break;
        default:
            // SICHER: Unbekannte Befehle werden protokolliert und abgelehnt
            log_security_event("Unbekannter Befehl: %02x", cmd);
            break;
    }
}

// Produktionsüberprüfung
void verify_no_debug_features(void) {
    // Prüfen ob Debug-Fuses gebrannt sind
    if (!is_debug_fuse_blown()) {
        panic("Debug-Fuse in Produktion nicht gebrannt!");
    }

    // Verifizieren dass keine Chicken Bits existieren
    // (Dies ist eine Kompilierzeit-Prüfung über das Build-System)
    #ifdef CHICKEN_BITS_ENABLED
        #error "Chicken Bits dürfen in Produktion nicht aktiviert sein!"
    #endif

    // Verifizieren dass alle Registeradressen erwartete Werte zurückgeben
    for (uint32_t addr = 0; addr < 0x100; addr++) {
        if (!is_documented_address(addr)) {
            uint32_t value = read_register(addr);
            if (value != 0 && value != 0xFFFFFFFF) {
                panic("Undokumentiertes Register an 0x%02x hat einen Wert!", addr);
            }
        }
    }
}

CVE-Beispiele

  • Skorobogatov & Woods: "Breakthrough Silicon Scanning Discovers Backdoor in Military Chip"
  • Domas: "God Mode Unlocked: Hardware Backdoors in x86 CPUs"
  • Forschung zu Siemens S7-Silizium-Schwachstellen

Verwandte CWEs

  • CWE-912: Hidden Functionality (übergeordnet)
  • CWE-1198: Privilege Separation and Access Control Issues (Kategoriemitglied)
  • CWE-1371: ICS Supply Chain: Poorly Documented Features (Kategoriemitglied)
  • CWE-1209: Failure to Disable Reserved Bits (verwandt)

Referenzen

  1. MITRE Corporation. "CWE-1242: Inclusion of Undocumented Features or Chicken Bits." https://cwe.mitre.org/data/definitions/1242.html
  2. CAPEC-212: Functionality Misuse
  3. CAPEC-36: Using Unpublished Interfaces or Functionality