Unsachgemäßes Management sensibler Trace-Daten

Beschreibung

Unsachgemäßes Management sensibler Trace-Daten tritt auf, wenn die Hardware-Unterstützung für das Tracing oder Debuggen Mechanismen enthält, die zur Laufzeit sensible Daten generieren, aber unzureichende oder nicht vorhandene Fähigkeiten zum Einschränken oder Deaktivieren des Zugriffs auf diese potenziell sensiblen Informationen bieten. Hardware-Trace-Mechanismen wie JTAG, Debug-Ports und Performance-Counter können interne Zustände, kryptografische Schlüssel, Speicherinhalte oder andere sensible Informationen offenlegen. Wenn diese Debug-Schnittstellen in Produktionshardware zugänglich bleiben, können Angreifer sie nutzen, um sensible Daten zu extrahieren oder Sicherheitsmaßnahmen zu umgehen.

Risiko

Ungeschützte Trace-Daten haben verschiedene Sicherheitsimplikationen. Angreifer können Debug-Schnittstellen verwenden, um kryptografische Schlüssel zu extrahieren. Trace-Mechanismen können sensiblen Speicherinhalt offenlegen. Debug-Ports können zur Umgehung von Sicherheitsstartketten verwendet werden. Performance-Counter können Timing-Informationen für Seitenkanalangriffe offenlegen.

Lösung

Implementieren Sie ordnungsgemäße Zugriffskontrollen für Debug- und Trace-Schnittstellen. Deaktivieren Sie Debug-Ports in Produktionshardware. Verwenden Sie Sicherungsbits, um Debug-Schnittstellen dauerhaft zu deaktivieren. Implementieren Sie Authentifizierung für Debug-Zugriff. Stellen Sie sicher, dass Trace-Daten sensible Informationen nicht preisgeben.

Häufige Auswirkungen

AuswirkungDetails
VertraulichkeitBereich: Vertraulichkeit

Zugang zur Ablesung von Anwendungsdaten über ungeschützte Debug-Schnittstellen.
ZugriffskontrolleBereich: Zugriffskontrolle

Umgehung von Sicherheitskontrollen durch Trace- und Debug-Mechanismen.

Beispielcode und Lösung

Verwundbarer Code

// Verwundbar: Ungeschützte Debug-Schnittstelle in Firmware
// VERWUNDBAR: Debug-Port immer aktiviert
#define DEBUG_PORT_AKTIVIERT 1

void debug_init(void) {
    // VERWUNDBAR: Keine Authentifizierung für Debug-Zugriff
    if (DEBUG_PORT_AKTIVIERT) {
        aktiviere_jtag();
        aktiviere_uart_debug();
    }
}

// VERWUNDBAR: Sensible Daten in Debug-Ausgabe preisgegeben
void debug_status(void) {
    printf("AES-Schlüssel: ");
    for (int i = 0; i < 16; i++) {
        printf("%02x", aes_schlüssel[i]);  // Schlüssel wird preisgegeben!
    }
    printf("\n");
}

// VERWUNDBAR: Speicher über Debug-Schnittstelle lesbar
uint32_t debug_speicher_lesen(uint32_t adresse) {
    // Keine Zugriffsprüfungen - kann sensiblen Speicher lesen
    return *(volatile uint32_t*)adresse;
}
// Verwundbar: Verilog-Modul mit ungeschütztem Debug
module verwundbar_debug (
    input clk,
    input debug_anfrage,
    input [31:0] debug_adresse,
    output [31:0] debug_daten
);

    // VERWUNDBAR: Keine Zugriffskontrolle für Debug-Lesungen
    // Jeder Debug-Zugriff wird gewährt
    assign debug_daten = speicher[debug_adresse];

    // VERWUNDBAR: Sensible Register für Debug preisgegeben
    // einschließlich kryptografischer Schlüssel
    wire [255:0] crypto_schlüssel = crypto_modul.geheimer_schlüssel;

endmodule

Sichere Lösung

// Sicher: Geschützte Debug-Schnittstelle
// Sicher: Debug kann über Sicherungsbit permanent deaktiviert werden
static bool debug_permanent_deaktiviert = false;

void debug_init(void) {
    // Sicher: Prüfe Sicherungsbit
    if (lese_sicherungsbit(DEBUG_DEAKTIVIERT_SICHERUNG)) {
        debug_permanent_deaktiviert = true;
        deaktiviere_jtag_permanent();
        return;
    }

    // Sicher: Authentifizierung erforderlich
    if (!debug_authentifizieren()) {
        deaktiviere_debug_schnittstellen();
        return;
    }

    // Sicher: Debug nur in Entwicklungs-Builds aktiviert
    #ifdef ENTWICKLUNGS_BUILD
    aktiviere_eingeschraenktes_debug();
    #endif
}

// Sicher: Debug-Ausgabe schließt sensible Daten aus
void debug_status(void) {
    printf("System-Status: %s\n", status_string);
    // Sicher: Keine Schlüssel oder sensible Daten in Ausgabe
}

// Sicher: Speicherzugriff mit Bereichsprüfungen
uint32_t debug_speicher_lesen(uint32_t adresse) {
    // Sicher: Nur erlaubte Speicherbereiche zugänglich
    if (!ist_debug_zugriff_erlaubt(adresse)) {
        return 0xDEADBEEF;  // Zugriff verweigert
    }

    // Sicher: Sensible Regionen sind ausgeschlossen
    if (ist_sensible_region(adresse)) {
        return 0;
    }

    return *(volatile uint32_t*)adresse;
}

// Sicher: Authentifizierung für Debug-Zugriff
bool debug_authentifizieren(void) {
    // Sicher: Challenge-Response-Authentifizierung
    uint8_t challenge[32];
    generiere_zufällige_challenge(challenge);

    uint8_t antwort[32];
    empfange_debug_antwort(antwort);

    return verifiziere_debug_antwort(challenge, antwort);
}
// Sicher: Verilog-Modul mit geschütztem Debug
module sicheres_debug (
    input clk,
    input rst,
    input debug_anfrage,
    input debug_authentifiziert,
    input [31:0] debug_adresse,
    output reg [31:0] debug_daten,
    output reg debug_zugriff_verweigert
);

    // Sicher: Debug-Deaktivierungs-Sicherungsbit
    wire debug_permanent_deaktiviert;
    sicherungs_leser debug_sicherung (.wert(debug_permanent_deaktiviert));

    // Sicher: Adressbereichsprüfung
    wire ist_sensible_adresse = (debug_adresse >= SENSIBEL_START) &&
                                 (debug_adresse <= SENSIBEL_ENDE);

    always @(posedge clk) begin
        if (rst) begin
            debug_daten <= 32'h0;
            debug_zugriff_verweigert <= 1'b0;
        end else if (debug_anfrage) begin
            // Sicher: Mehrere Schutzebenen
            if (debug_permanent_deaktiviert) begin
                debug_daten <= 32'h0;
                debug_zugriff_verweigert <= 1'b1;
            end else if (!debug_authentifiziert) begin
                debug_daten <= 32'h0;
                debug_zugriff_verweigert <= 1'b1;
            end else if (ist_sensible_adresse) begin
                // Sicher: Sensible Bereiche immer geschützt
                debug_daten <= 32'h0;
                debug_zugriff_verweigert <= 1'b1;
            end else begin
                debug_daten <= speicher[debug_adresse];
                debug_zugriff_verweigert <= 1'b0;
            end
        end
    end

endmodule

Ausgenutzt in der Praxis

JTAG-Extraktion von Firmware-Geheimnissen

Sicherheitsforscher haben gezeigt, dass ungeschützte JTAG-Schnittstellen auf IoT-Geräten es ermöglichen, Firmware und kryptografische Schlüssel direkt aus dem Speicher zu extrahieren.

Debug-Port-Umgehung bei Smartphones

Angreifer nutzten aktivierte Debug-Schnittstellen auf Produktions-Smartphones, um Bildschirmsperren zu umgehen und auf geschützte Daten zuzugreifen.


Tools zum Testen und Ausnutzen

  • OpenOCD - Open-Source-Tool für On-Chip-Debugging.

  • JTAGulator - Open-Source-Hardware zur Identifizierung von JTAG-Pins.

  • Bus Pirate - Universelles Bus-Schnittstellen-Tool.


CVE-Beispiele

  • CVE-2017-18344 - Linux-Kernel leckt Timer-Informationen, die für Seitenkanalangriffe verwendet werden können.

  • CVE-2019-1649 - Cisco Trust Anchor-Modul erlaubt Debug-Zugriff, der nicht hätte verfügbar sein sollen.


Referenzen

  1. MITRE Corporation. "CWE-1323: Improper Management of Sensitive Trace Data." https://cwe.mitre.org/data/definitions/1323.html

  2. ARM. "Debug and Trace Security." https://developer.arm.com/documentation/

  3. NIST. "Guidelines for Hardware Security." https://csrc.nist.gov/