Nicht vertrauenswürdiger Suchpfad
Beschreibung
Nicht vertrauenswürdiger Suchpfad tritt auf, wenn ein Produkt kritische Ressourcen wie Bibliotheken oder ausführbare Dateien über einen extern bereitgestellten Suchpfad sucht, der auf Ressourcen zeigen kann, die nicht unter der direkten Kontrolle des Produkts stehen. Angreifer können den Suchpfad manipulieren oder bösartige Ressourcen an Orten platzieren, die vor den legitimen Ressourcen-Standorten durchsucht werden. Wenn das Produkt diese bösartigen Ressourcen lädt, führt es angreifergesteuerten Code mit den Privilegien der anfälligen Anwendung aus. Dies wird häufig durch DLL-Hijacking unter Windows ausgenutzt, wo Anwendungen bösartige DLLs aus dem aktuellen Verzeichnis oder anderen angreifergesteuerten Standorten laden.
Risiko
Schwachstellen durch nicht vertrauenswürdige Suchpfade ermöglichen Privilegieneskalation und beliebige Codeausführung. CVE-2025-12793 in ASUS ASCI ermöglicht lokalen Angreifern die Codeausführung durch Platzierung bösartiger DLLs in Pfaden, die von AsusSoftwareManagerAgent durchsucht werden. CVE-2024-6769 kombiniert Drive-Remapping mit Activation-Context-Poisoning für Windows DLL-Hijacking. CVE-2024-14012 in Revenera InstallShield ermöglicht Privilegieneskalation durch MPR.dll-Hijacking. Auch FortiClient Windows ist betroffen. Diese Angriffe sind besonders gefährlich, weil sie von niedrig-privilegiertem lokalem Zugriff auf SYSTEM-Level-Codeausführung eskalieren können und manchmal remote über SMB- oder WebDAV-Shares ausgelöst werden können.
Lösung
Verwenden Sie immer vollqualifizierte Pfade beim Laden von Bibliotheken, ausführbaren Dateien oder anderen Ressourcen. Entfernen Sie das aktuelle Verzeichnis aus dem DLL-Suchpfad mit SetDllDirectory("") unter Windows. Verwenden Sie sichere Bibliothekslade-Flags wie LOAD_LIBRARY_SEARCH_SYSTEM32. Hardcodieren Sie Suchpfade auf bekannte sichere Systemverzeichnisse. Validieren Sie, dass geladene Ressourcen von erwarteten Standorten stammen. Implementieren Sie ordnungsgemäße ACLs, um unbefugte Benutzer am Schreiben in Verzeichnisse im Suchpfad zu hindern. Verwenden Sie Anwendungsmanifeste, um exakte DLL-Versionen und -Standorte anzugeben.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Zugriffskontrolle | Umfang: Codeausführung Angreifer führen beliebigen Code aus, wenn ihre bösartige Ressource von der anfälligen Anwendung geladen wird. |
| Integrität | Umfang: Privilegieneskalation Code läuft mit den Privilegien der anfälligen Anwendung, oft SYSTEM- oder Administrator-Level. |
| Vertraulichkeit | Umfang: Systemkompromittierung Erfolgreiche Ausnutzung bietet persistenten Zugriff und Möglichkeit, auf sensible Daten zuzugreifen. |
Beispielcode
Anfälliger Code
// ANFÄLLIG: DLL ohne vollständigen Pfad laden
#include <windows.h>
void load_plugin() {
// Windows sucht: App-Verzeichnis, aktuelles Verzeichnis, Systemverzeichnis, etc.
// Angreifer kann bösartige helper.dll im aktuellen Verzeichnis platzieren
HMODULE hLib = LoadLibrary("helper.dll");
if (hLib) {
// Jetzt läuft Angreifers Code mit App-Privilegien!
typedef void (*InitFunc)();
InitFunc init = (InitFunc)GetProcAddress(hLib, "Initialize");
if (init) init();
}
}
// ANFÄLLIG: Programm ohne vollständigen Pfad ausführen
#include <cstdlib>
void run_utility() {
// system() verwendet PATH-Umgebungsvariable
// Angreifer kann PATH modifizieren oder bösartige Utility in durchsuchtem Verzeichnis platzieren
system("utility.exe --process");
}
// ANFÄLLIG: Python-Modulladen
// Wenn PYTHONPATH angreifergesteuert ist, können bösartige Module geladen werden
import helper // Könnte Angreifers helper.py laden
// ANFÄLLIG: Native Bibliothek ohne vollständigen Pfad laden
public class NativeWrapper {
static {
// Java durchsucht java.library.path, der Angreiferpfade enthalten kann
System.loadLibrary("nativehelper"); // Lädt nativehelper.dll
}
public native void processData(byte[] data);
}
Korrigierter Code
// SICHER: DLL mit vollständigem Pfad und sicheren Flags laden
#include <windows.h>
#include <libloaderapi.h>
#include <shlwapi.h>
HMODULE load_library_safely(const char* dllName) {
// Aktuelles Verzeichnis aus DLL-Suchpfad entfernen
SetDllDirectory("");
// Vollständigen Pfad zum Systemverzeichnis bauen
char systemPath[MAX_PATH];
GetSystemDirectory(systemPath, MAX_PATH);
PathAppend(systemPath, dllName);
// Nur aus Systemverzeichnis laden
HMODULE hLib = LoadLibraryEx(
systemPath,
NULL,
LOAD_LIBRARY_SEARCH_SYSTEM32 // Nur system32 durchsuchen
);
return hLib;
}
// SICHER: Anwendungs-DLL mit explizitem Pfad laden
HMODULE load_app_library(const char* dllName) {
char appPath[MAX_PATH];
// Anwendungsverzeichnis abrufen
GetModuleFileName(NULL, appPath, MAX_PATH);
PathRemoveFileSpec(appPath);
PathAppend(appPath, dllName);
// Pfad ist im erwarteten Verzeichnis verifizieren (kein Traversal)
if (!path_is_trusted(appPath)) {
return NULL;
}
return LoadLibraryEx(appPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
}
int path_is_trusted(const char* path) {
// Pfad beginnt mit erwartetem Anwendungsverzeichnis verifizieren
char expectedBase[MAX_PATH];
GetModuleFileName(NULL, expectedBase, MAX_PATH);
PathRemoveFileSpec(expectedBase);
// Pfade normalisieren und vergleichen
char normalizedPath[MAX_PATH];
GetFullPathName(path, MAX_PATH, normalizedPath, NULL);
return strncmp(normalizedPath, expectedBase, strlen(expectedBase)) == 0;
}
// SICHER: Programme mit vollständigen Pfaden ausführen
#include <windows.h>
#include <string>
void run_utility_safely() {
// Vollständigen Pfad zur Utility bauen
char systemPath[MAX_PATH];
GetSystemDirectory(systemPath, MAX_PATH);
std::string fullPath = std::string(systemPath) + "\\utility.exe";
// CreateProcess statt system() für mehr Kontrolle verwenden
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
CreateProcess(
fullPath.c_str(),
NULL, // Befehlszeile
NULL, // Prozess-Sicherheit
NULL, // Thread-Sicherheit
FALSE, // Handles vererben
0, // Erstellungs-Flags
NULL, // Umgebung (vom Parent verwenden)
NULL, // Aktuelles Verzeichnis (vom Parent verwenden)
&si,
&pi
);
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
// SICHER: Python mit expliziten Modulpfaden
// PYTHONPATH explizit im kontrollierten Startskript setzen
// importlib mit expliziten Pfaden verwenden
import importlib.util
import os
def load_trusted_module(module_name, expected_dir):
module_path = os.path.join(expected_dir, f"{module_name}.py")
# Modul ist am erwarteten Ort verifizieren
real_path = os.path.realpath(module_path)
if not real_path.startswith(os.path.realpath(expected_dir)):
raise SecurityError(f"Modul-Pfad-Traversal erkannt: {module_path}")
spec = importlib.util.spec_from_file_location(module_name, module_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
// SICHER: Native Bibliothek mit vollständigem Pfad laden
public class SecureNativeWrapper {
static {
String libPath;
// Plattformspezifischen Bibliotheksnamen und -ort bestimmen
String osName = System.getProperty("os.name").toLowerCase();
if (osName.contains("win")) {
libPath = System.getenv("ProgramFiles") +
"\\MyApp\\lib\\nativehelper.dll";
} else {
libPath = "/usr/lib/myapp/libnativehelper.so";
}
// Pfad ist im erwarteten Verzeichnis verifizieren
File libFile = new File(libPath);
try {
String canonicalPath = libFile.getCanonicalPath();
if (!canonicalPath.startsWith(getExpectedLibDir())) {
throw new SecurityException("Bibliothekspfad außerhalb erwartetem Verzeichnis");
}
} catch (IOException e) {
throw new RuntimeException("Bibliothekspfad kann nicht verifiziert werden", e);
}
// Mit explizitem vollständigem Pfad laden
System.load(libPath);
}
private static String getExpectedLibDir() {
// Erwartetes Basisverzeichnis für native Bibliotheken zurückgeben
return System.getenv("ProgramFiles") + File.separator + "MyApp";
}
public native void processData(byte[] data);
}
Ausgenutzt in der Praxis
ASUS Software Manager Agent (ASUS, 2025)
CVE-2025-12793 in ASUS ASCI AsusSoftwareManagerAgent ermöglicht lokalen Angreifern die Ausführung beliebigen Codes durch Platzierung bösartiger DLLs in Pfaden, die von der anfälligen Komponente durchsucht werden, betrifft Versionen vor v3.1.49.0.
Windows Drive-Remapping-Angriff (Microsoft, 2024)
CVE-2024-6769 kombiniert Drive-Remapping mit Activation-Context-Poisoning, um DLL-Hijacking auf Windows-Systemen zu erreichen, demonstriert ausgeklügelte Ausnutzung nicht vertrauenswürdiger Suchpfade.
Revenera InstallShield (Revenera, 2024)
CVE-2024-14012 in InstallShield 2023 R1 ermöglicht Privilegieneskalation, wenn Setup.exe MPR.dll aus einem unsicheren Verzeichnis lädt, wodurch lokale Administratoren höhere Privilegien erlangen können.
Tools zum Testen/Ausnutzen
-
Procmon — Dateisystemaktivität überwachen, um DLL-Suchreihenfolge zu identifizieren.
-
DLL Hijack Auditor — DLL-Hijacking-Möglichkeiten identifizieren.
-
Robber — DLL-Hijacking-Schwachstellen-Scanner.
CVE-Beispiele
-
CVE-2025-12793 — ASUS ASCI DLL-Hijacking.
-
CVE-2024-6769 — Windows Drive-Remapping DLL-Hijack.
-
CVE-2024-14012 — Revenera InstallShield Privilegieneskalation.
Referenzen
-
MITRE. "CWE-426: Untrusted Search Path." https://cwe.mitre.org/data/definitions/426.html
-
Microsoft. "Dynamic-Link Library Security." https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-security