Unsachgemäße Beschränkung von Software-Schnittstellen zu Hardware-Funktionen
Beschreibung
Unsachgemäße Beschränkung von Software-Schnittstellen zu Hardware-Funktionen tritt auf, wenn ein Produkt Software-Kontrolle über Gerätefunktionalität wie Strom- und Taktverwaltung erlaubt, ohne den Zugriff ordnungsgemäß einzuschränken. Dies kann Angreifern ermöglichen, Hardware-Speicher/Register zu modifizieren oder physische Seitenkanale auszunutzen, ohne physischen Gerätezugriff zu benötigen. Moderne Chipsätze enthalten software-zugängliche Strom- und Frequenzskalierung für mobile Geräte, aber diese Funktionen schaffen Sicherheitsrisiken einschließlich Fault-Injection-Angriffen und Seitenkanal-Analyse unter Verwendung eingebauter Strommessung.
Risiko
Uneingeschränkte Hardware-Schnittstellen haben schwerwiegende Sicherheitsauswirkungen. Spannungsmanipulation ermöglicht Fault Injection (Plundervolt). Strommessung ermöglicht Seitenkanal-Angriffe (PLATYPUS). Rowhammer-Angriffe verursachen Speicher-Bit-Flips. CPU-Frequenzmanipulation stört Timing. Thermische Kontrollen können Instabilität verursachen. Debug-Schnittstellen können zugänglich sein. Sicherheitsenklaven können kompromittiert werden. Privilege Escalation wird durch Hardware-Manipulation möglich.
Lösung
Stellen Sie sicher, dass geeignete Zugriffskontrollmechanismen software-steuerbare Funktionen schützen, die physische Betriebsbedingungen wie Taktfrequenz und Spannung ändern. Beschränken Sie den Zugriff auf DVFS-Schnittstellen. Begrenzen Sie die Genauigkeit der Strommessung. Implementieren Sie Kontrollen für Speicher-Refresh-Raten. Erfordern Sie Privilegien für Hardware-Kontrollschnittstellen. Überwachen Sie auf abnormale Hardware-Manipulation. Implementieren Sie Ratenbegrenzung für Hardware-Kontrolloperationen. Verwenden Sie Hardware-Sicherheitsmodule für sensible Operationen.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Integrität | Umfang: Integrität Speicher modifizieren; Anwendungsdaten modifizieren - Hardware-Manipulation kann Speicherbeschädigung durch Techniken wie Rowhammer verursachen. |
| Integrität | Umfang: Integrität Schutzmechanismus umgehen - Fault Injection kann Sicherheitsprüfungen einschließlich kryptografischer Operationen umgehen. |
| Vertraulichkeit | Umfang: Vertraulichkeit Speicher lesen - Power-Seitenkanal-Angriffe können kryptografische Schlüssel und sensible Daten extrahieren. |
Beispielcode und Lösung
Verwundbarer Code
// VERWUNDBAR: Uneingeschränkter Zugriff auf Spannungssteuerung
#include <stdint.h>
// Plundervolt-artiger Angriffsvektor
#define MSR_VOLTAGE_CONTROL 0x150
void vulnerable_voltage_interface(void) {
// VERWUNDBAR: Jeder Prozess kann Spannungs-MSR lesen/schreiben
// Keine Berechtigungsprüfung oder Zugriffsbeschränkung
uint64_t voltage = rdmsr(MSR_VOLTAGE_CONTROL);
// Angreifer kann unterspannen, um Fehler zu verursachen
wrmsr(MSR_VOLTAGE_CONTROL, voltage - 0x100);
// Sicherheitskritische Operation während Unterspannung ausführen
// Fehler kann falsche Berechnung/Umgehung verursachen
}
// VERWUNDBAR: Uneingeschränkter RAPL- (Strommessungs-) Zugriff
#define MSR_RAPL_POWER_UNIT 0x606
#define MSR_PKG_ENERGY_STATUS 0x611
void vulnerable_rapl_access(void) {
// VERWUNDBAR: Hochpräzise Stromablesungen verfügbar
// Können für Power-Seitenkanal-Angriffe verwendet werden (PLATYPUS)
uint64_t energy_before = rdmsr(MSR_PKG_ENERGY_STATUS);
// Zieloperation (z.B. AES-Verschlüsselung)
perform_crypto_operation();
uint64_t energy_after = rdmsr(MSR_PKG_ENERGY_STATUS);
// VERWUNDBAR: Energiedifferenz offenbart Operationsdetails
uint64_t energy_consumed = energy_after - energy_before;
// Angreifer korreliert Strom mit Schlüssel-Bits
}
// VERWUNDBAR: Uneingeschränkter Cache-Flush
void vulnerable_cache_control(void) {
// VERWUNDBAR: CLFLUSH verfügbar für unprivilegierten Code
// Ermöglicht Rowhammer-Angriffe und Cache-Timing-Angriffe
volatile char* target = (volatile char*)0x12340000;
while (1) {
// Wiederholt leeren und zugreifen, um Bit-Flips zu verursachen
_mm_clflush((void*)target);
*target;
_mm_clflush((void*)(target + 4096));
*(target + 4096);
// VERWUNDBAR: Kann DRAM-Bit-Flips verursachen (Rowhammer)
}
}
// VERWUNDBAR: Uneingeschränkte Frequenzskalierung
void vulnerable_frequency_control(void) {
// VERWUNDBAR: Software kann CPU-Frequenz ändern
// Kann für Timing-Angriffe oder Fault Injection verwendet werden
// Maximale Frequenz anfordern
write_freq_request(MAX_FREQ);
// Oder Minimum anfordern, um Sicherheitsprüfungen zu verlangsamen
write_freq_request(MIN_FREQ);
// Schnelles Umschalten kann Instabilität verursachen
}
// VERWUNDBAR: Hardware mit uneingeschränkten Kontrollschnittstellen
module vulnerable_power_controller (
input wire clk,
input wire reset_n,
// VERWUNDBAR: Keine Berechtigungsprüfung
input wire [7:0] voltage_request,
input wire [7:0] frequency_request,
input wire control_valid,
output reg [7:0] voltage_setting,
output reg [7:0] frequency_setting
);
// VERWUNDBAR: Direkte Kontrolle ohne Einschränkungen
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
voltage_setting <= 8'd128; // Nennspannung
frequency_setting <= 8'd128; // Nennfrequenz
end
else if (control_valid) begin
// VERWUNDBAR: Jede Spannung/Frequenz ohne Prüfung akzeptieren
// - Keine Mindest-/Höchstgrenzen
// - Keine Berechtigungsüberprüfung
// - Keine Ratenbegrenzung
voltage_setting <= voltage_request;
frequency_setting <= frequency_request;
end
end
// Keine Überwachung auf Fault-Injection-Muster
// Kein Schutz gegen schnelle Änderungen
endmodule
// VERWUNDBAR: Uneingeschränkte Strommessung
module vulnerable_power_meter (
input wire clk,
input wire reset_n,
input wire [15:0] power_sense,
input wire read_request,
output reg [31:0] energy_counter,
output reg [15:0] power_reading
);
// VERWUNDBAR: Hochauflösende Stromablesungen zugänglich
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
energy_counter <= 32'h0;
power_reading <= 16'h0;
end
else begin
// Hochauflösende Energie akkumulieren
energy_counter <= energy_counter + power_sense;
// VERWUNDBAR: Präzise Stromablesung zurückgeben
if (read_request) begin
power_reading <= power_sense;
end
end
end
// Keine Zugriffskontrolle
// Keine Auflösungsbegrenzung
// Ermöglicht Power-Seitenkanal-Angriffe
endmodule
Sichere Lösung
// SICHER: Eingeschränkter Zugriff auf Hardware-Kontrollschnittstellen
#include <stdint.h>
// SICHER: Spannungssteuerung mit Einschränkungen
int secure_voltage_interface(uint64_t new_voltage, int privilege_level) {
// SICHER: Erhöhte Privilegien erforderlich
if (privilege_level < PRIVILEGE_KERNEL) {
return -EPERM;
}
// SICHER: Spannungsbereich validieren
if (new_voltage < VOLTAGE_MIN || new_voltage > VOLTAGE_MAX) {
return -EINVAL;
}
// SICHER: Ratenbegrenzung
static uint64_t last_change_time = 0;
uint64_t current_time = get_current_time();
if (current_time - last_change_time < VOLTAGE_CHANGE_COOLDOWN) {
return -EAGAIN;
}
// SICHER: Spannungsänderung protokollieren
audit_log("Spannungsänderung: %llx durch Privileg %d", new_voltage, privilege_level);
// Kontrollierte Spannungsänderung durchführen
wrmsr(MSR_VOLTAGE_CONTROL, new_voltage);
last_change_time = current_time;
return 0;
}
// SICHER: Eingeschränkter RAPL-Zugriff
int secure_rapl_access(uint64_t* energy, int privilege_level) {
// SICHER: Erhöhte Privilegien für präzise Ablesungen erforderlich
if (privilege_level < PRIVILEGE_ADMIN) {
return -EPERM;
}
uint64_t raw_energy = rdmsr(MSR_PKG_ENERGY_STATUS);
// SICHER: Auflösung reduzieren, um Seitenkanal-Angriffe zu verhindern
// Auf nächstes 1mJ runden statt Mikrojoule-Präzision
*energy = (raw_energy / 1000) * 1000;
// SICHER: Rauschen zu Ablesungen hinzufügen
*energy += get_random() % 1000;
return 0;
}
// SICHER: Eingeschränkte Cache-Kontrolle
int secure_cache_flush(void* addr, size_t size, int privilege_level) {
// SICHER: Kernel-Privileg für Cache-Flush erforderlich
if (privilege_level < PRIVILEGE_KERNEL) {
return -EPERM;
}
// SICHER: Adressbereich validieren
if (!is_valid_kernel_address(addr, size)) {
return -EFAULT;
}
// SICHER: Ratenbegrenzung zur Verhinderung von Rowhammer
static int flush_count = 0;
static uint64_t window_start = 0;
uint64_t current_time = get_current_time();
if (current_time - window_start > RATE_LIMIT_WINDOW) {
flush_count = 0;
window_start = current_time;
}
if (++flush_count > MAX_FLUSHES_PER_WINDOW) {
audit_log("Cache-Flush-Ratenlimit überschritten");
return -EBUSY;
}
// Cache-Flush durchführen
for (size_t i = 0; i < size; i += CACHE_LINE_SIZE) {
_mm_clflush((char*)addr + i);
}
return 0;
}
// SICHER: Sichere Frequenzsteuerung
int secure_frequency_control(uint64_t requested_freq, int privilege_level) {
// SICHER: Erhöhte Privilegien erforderlich
if (privilege_level < PRIVILEGE_ADMIN) {
return -EPERM;
}
// SICHER: Frequenzbereich validieren
if (requested_freq < FREQ_MIN || requested_freq > FREQ_MAX) {
return -EINVAL;
}
// SICHER: Nur schrittweise Frequenzänderungen
uint64_t current_freq = read_current_frequency();
uint64_t max_step = FREQ_MAX_STEP;
if (abs(requested_freq - current_freq) > max_step) {
// Schrittweise ändern, um Fault Injection zu verhindern
requested_freq = current_freq +
(requested_freq > current_freq ? max_step : -max_step);
}
write_freq_request(requested_freq);
return 0;
}
// SICHER: Hardware mit sicheren Kontrollschnittstellen
module secure_power_controller (
input wire clk,
input wire reset_n,
input wire [1:0] privilege_level, // 0=Benutzer, 1=Kernel, 2=Sicher
input wire [7:0] voltage_request,
input wire [7:0] frequency_request,
input wire control_valid,
output reg [7:0] voltage_setting,
output reg [7:0] frequency_setting,
output reg access_denied,
output reg rate_limit_exceeded
);
// SICHER: Erforderliche Berechtigungsstufe für Hardware-Kontrolle
parameter REQUIRED_PRIVILEGE = 2'd2; // Nur sicherer Modus
// SICHER: Gültige Spannungs-/Frequenzbereiche
parameter VOLTAGE_MIN = 8'd96; // ~75% Nennwert
parameter VOLTAGE_MAX = 8'd160; // ~125% Nennwert
parameter FREQ_MIN = 8'd32;
parameter FREQ_MAX = 8'd224;
// SICHER: Ratenbegrenzung
reg [15:0] change_cooldown;
parameter COOLDOWN_CYCLES = 16'd10000;
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
voltage_setting <= 8'd128;
frequency_setting <= 8'd128;
access_denied <= 1'b0;
rate_limit_exceeded <= 1'b0;
change_cooldown <= 16'h0;
end
else begin
// Abkühlung dekrementieren
if (change_cooldown > 0) begin
change_cooldown <= change_cooldown - 1;
end
access_denied <= 1'b0;
rate_limit_exceeded <= 1'b0;
if (control_valid) begin
// SICHER: Berechtigungsstufe prüfen
if (privilege_level < REQUIRED_PRIVILEGE) begin
access_denied <= 1'b1;
end
// SICHER: Ratenlimit prüfen
else if (change_cooldown > 0) begin
rate_limit_exceeded <= 1'b1;
end
// SICHER: Spannungsbereich validieren
else if (voltage_request < VOLTAGE_MIN ||
voltage_request > VOLTAGE_MAX) begin
access_denied <= 1'b1;
end
// SICHER: Frequenzbereich validieren
else if (frequency_request < FREQ_MIN ||
frequency_request > FREQ_MAX) begin
access_denied <= 1'b1;
end
else begin
// SICHER: Kontrollierte Änderung anwenden
voltage_setting <= voltage_request;
frequency_setting <= frequency_request;
change_cooldown <= COOLDOWN_CYCLES;
end
end
end
end
endmodule
// SICHER: Sichere Strommessung mit reduzierter Präzision
module secure_power_meter (
input wire clk,
input wire reset_n,
input wire [15:0] power_sense,
input wire read_request,
input wire [1:0] privilege_level,
input wire [7:0] random_noise, // Externer TRNG
output reg [31:0] energy_counter,
output reg [15:0] power_reading,
output reg access_denied
);
parameter REQUIRED_PRIVILEGE = 2'd1; // Kernel erforderlich
// Interner hochauflösender Zähler
reg [47:0] internal_energy;
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
internal_energy <= 48'h0;
energy_counter <= 32'h0;
power_reading <= 16'h0;
access_denied <= 1'b0;
end
else begin
// Immer akkumulieren (intern)
internal_energy <= internal_energy + power_sense;
access_denied <= 1'b0;
if (read_request) begin
// SICHER: Berechtigung prüfen
if (privilege_level < REQUIRED_PRIVILEGE) begin
access_denied <= 1'b1;
power_reading <= 16'h0;
energy_counter <= 32'h0;
end
else begin
// SICHER: Präzision reduzieren (obere 32 von 48 Bits)
// SICHER: Rauschen hinzufügen, um Seitenkanal zu verhindern
energy_counter <= internal_energy[47:16] +
{24'h0, random_noise};
// SICHER: Nur grobe Stromablesung
power_reading <= {power_sense[15:8], 8'h00} +
{8'h0, random_noise};
end
end
end
end
endmodule
CVE-Beispiele
- CVE-2019-11157 (Plundervolt): Intel-Prozessor-Spannungseinstellungs-Schwachstelle ermöglicht Privilege Escalation und Sicherheitsenklaven-Umgehung
- CVE-2020-8694/8695 (PLATYPUS): RAPL-Schnittstellen-Zugriffskontrollprobleme ermöglichen Power-Seitenkanal-Angriffe
- CVE-2015-0565: NaCl erlaubte CLFLUSH-Instruktion und ermöglichte Rowhammer-Angriffe
Verwandte CWEs
- CWE-285: Unsachgemäße Autorisierung (übergeordnet)
- CWE-1300: Unsachgemäßer Schutz physischer Seitenkanale (verwandt)
- CWE-1247: Unsachgemäßer Schutz gegen Spannungs- und Taktglitches (verwandt)
- CAPEC-624: Hardware Fault Injection (Angriffsmuster)
- CAPEC-625: Mobile Device Fault Injection (Angriffsmuster)
Referenzen
- MITRE Corporation. "CWE-1256: Improper Restriction of Software Interfaces to Hardware Features." https://cwe.mitre.org/data/definitions/1256.html
- Plundervolt: Software-based Fault Injection Attacks against Intel SGX
- PLATYPUS: Software-based Power Side-Channel Attacks on x86
- Rowhammer: Flipping Bits in Memory Without Accessing Them