
CVE-2025-38352 Kernel-Exploit für LG webOS Smart TVs (ARM64). Erreicht persistenten Root auf echter Consumer-Hardware mit neuartigen Exploitation-Techniken. Verantwortungsvoll an LG offengelegt.
Kernel-Exploit für CVE-2025-38352 (POSIX-CPU-Timer-Race-Condition / Use-After-Free), das persistenten Root-Zugriff auf LG webOS Smart TVs mit Kernel 5.4.268 auf ARM64 ermöglicht. Verifiziert auf 4 TV-Modellen mit mehreren Firmware-Versionen. Verantwortungsvoll gegenüber LG's Security Researcher Program offengelegt (Februar 2026).
Basierend auf Chronomaly von farazsth98. Stufe-1-UAF-Race-Logik und Cross-Cache-Infrastruktur für ARM64 portiert und angepasst; Stufen 2–5 mit neuartigen Exploitation-Techniken und Lösungen für reale Hardware-Beschränkungen, die in emulierten Umgebungen nicht existieren, neu gestaltet. Entwickelt mit Unterstützung von Claude Opus 4.6.
Siehe VULNERABILITY_REPORT.md für die vollständige Schwachstellenanalyse, den Exploit-Chain-Walkthrough und empfohlene Gegenmaßnahmen.
prisoner-Benutzer (uid=5038)Dieser Exploit wurde im Rahmen verantwortungsvoller Sicherheitsforschung entwickelt und am 7. Februar 2026 an LG's Security Researcher Program gemeldet. Er wird nur zu Bildungszwecken veröffentlicht. Verwenden Sie ihn verantwortungsvoll und nur auf Geräten, die Ihnen gehören. Die Autoren übernehmen keine Haftung für Schäden, Bricking, Datenverlust oder Garantieverlust, die durch die Nutzung dieser Software entstehen. Diese Software wird ohne Gewährleistung bereitgestellt.
Das ursprüngliche willkürliche Dekrementieren ist langsam und laut: Es verteilt 1.000 struct cred-Objekte über forked-Prozesse und dekrementiert dann das EUID-Feld einer Ziel-cred N-mal. Jedes Dekrement ist ein separater Vorgang. In QEMU, wo das Timing nachsichtig ist, ist dies akzeptabel, aber auf echter Hardware unzuverlässig, wo interruptgesteuerte Seitenwiedergewinnung zwischen den Vorgängen Pipe-Buffer-Seiten stehlen kann.
Dies wurde durch einen einzelnen willkürlichen Schreibvorgang mittels list_del_init() ersetzt. Der Exploit überschreibt die list_head.next- und list_head.prev-Zeiger der UAF-sigqueue über den Pipe-Buffer. Wenn der Kernel das anstehende Signal aus der Warteschlange entfernt (collect_signal() → list_del_init()), führt er prev->next = next (schreibt die gefälschte Cred-Adresse in task_struct->cred) und next->prev = prev (kontrollierter Seiteneffektschreibvorgang) aus. Ein Schreibvorgang ersetzt den Cred-Zeiger des Prozesses durch einen Zeiger auf eine gefälschte Cred-Struktur, die uid/gid-Felder mit Null enthält. Kein Cred-Spray, keine forked-Prozesse, deterministisch.
peek_pipe() mittels tee() für nicht-destruktive LesevorgängeDas Original verwendet im gesamten Exploit destruktive read()-Aufrufe auf Pipe-Buffer. In QEMU funktioniert dies gut, da Seiten zwischen Vorgängen nicht gestohlen werden. Auf echter Hardware mit 4 physischen Kernen gibt die kernelweite Per-CPU-Seitenliste (pcplist) freigegebene Seiten aggressiv frei. Ein destruktives Lesen gibt die zugrunde liegende Seite des Pipe-Buffers frei, die sofort von einem Hardware-Interrupt gestohlen werden kann, bevor der Exploit sie neu zuweisen kann.
Die Lösung ist eine nicht-destruktive Pipe-Lese-Primitive mittels tee(). Der tee()-Syscall dupliziert Pipe-Daten zwischen zwei Pipes, ohne sie zu verbrauchen, und hält so die zugrunde liegende Seite des ursprünglichen Pipe-Buffers fixiert. Dadurch kann der Exploit wiederholt Kernel-Daten aus dem Cross-Cache-Pipe-Buffer lesen, ohne das Risiko eines Seitenverlusts. Dies war für die Zuverlässigkeit auf echter Hardware entscheidend.
Das Original verteilt Cred-Objekte und hofft, eines an einer vorhersagbaren Position zu platzieren. Diese Version konstruiert die gefälschte Cred-Struktur an einer bekannten Adresse durch einen zweiten Cross-Cache: eine neue Sigqueue mittels tkill(SIGRTMIN+1) zuweisen, ihre Adresse aus dem Heap-Leak des ersten Pipe-Buffers erfahren, dann die Slab-Seite dieser Sigqueue in einen zweiten Pipe-Buffer cross-cachen. Die gefälschte Cred wird in den zweiten Pipe-Buffer an der exakten Seiten-Offset der geleakten Sigqueue-Adresse geschrieben. Das Ergebnis ist eine gefälschte Cred an einer deterministischen Kernel-Adresse ohne Rätselraten.
Das Original entfernt SIGUSR2 früh in Stufe 2 aus der Warteschlange, um die Adresse der UAF-Sigqueue zu leaken. Dies verbraucht das Signal, sodass das Original einen anderen Mechanismus für den finalen Schreibvorgang benötigt. Diese Version benötigt niemals die eigene Adresse der UAF-Sigqueue (der Heap-Leak stammt von benachbarten Sigqueue-Zeigern im Pipe-Buffer). SIGUSR2 bleibt über alle fünf Stufen anstehend und seine Entfernung aus der Warteschlange wird als finaler willkürlicher Schreib-Trigger verwendet. Das Signal, das die UAF erzeugt hat, ist dasselbe Signal, dessen Aus der Warteschlange sie ausnutzt.
modprobe_path + socket(44)-EskalationDie gefälschte Cred-Struktur hat NULL-user_ns-, user- und group_info-Zeiger (da der Pipe-Buffer über die uid/gid-Felder hinaus nullinitialisiert ist). Aufrufe von setresuid(), fork() oder exec() würden diese NULL-Zeiger dereferenzieren und einen Kernel-Panic auslösen. Das Original vermeidet dies, da sein Cred-Spray echte Cred-Objekte mit gültigen Zeigern verwendet.
Die Lösung: /proc/sys/kernel/modprobe überschreiben, um auf ein Payload-Skript (/tmp/pwn) zu verweisen, dann call_usermodehelper mittels socket(44, SOCK_STREAM, 0) auslösen (Anfrage einer nicht existierenden Protokollfamilie). Der Kernel führt den Modprobe-Helfer mit init_cred (den eigenen Root-Anmeldedaten des Kernels, vollständig gültig) aus und umgeht so die beschädigte Cred vollständig. Das Payload wird als vollwertiger Root ausgeführt und kann beliebige Operationen durchführen.
Das kritische Fenster in Stufe 4 (Schreiben bösartiger Zeiger in den Pipe-Buffer, dann Auslösen des Signal-Dequeue) ist anfällig für Hardware-Interrupts, die die Pipe-Buffer-Seite aus der Per-CPU-Seitenliste stehlen. Dies passiert in QEMU nicht. Auf echter Hardware wird dieses Fenster mit SCHED_FIFO-Priorität (sofern verfügbar) und sched_yield() geschützt, um anstehende Arbeiten auf der CPU vor dem Eintritt in den kritischen Abschnitt abzuschließen, plus vorbereitete Pufferinhalte, um die Zeit zwischen Schreibvorgang und Auslösung zu minimieren. Der Exploit fällt auch elegant zurück, wenn SCHED_FIFO nicht verfügbar ist (wie auf webOS, wo der prisoner-Benutzer nicht über CAP_SYS_NICE verfügt).
task_struct-Offset Reverse EngineeringDer willkürliche Schreibvorgang zielt auf task_struct->cred, was die Kenntnis des Byte-Offsets von task_struct->pending (dessen Adresse aus dem Pipe-Buffer geleakt wird) zu task_struct->cred erfordert. Dieser Offset ist kernel-konfigurationsabhängig. Der Offset von 0x80 (128 Byte) wurde manuell aus dem LG webOS-Kernel-Quellcode berechnet, unter Berücksichtigung von CONFIG_KEYS=y, CONFIG_SYSVIPC=y und ARM64-spezifischem Struktur-Layout und Alignment. Der x86_64-Offset im Original unterscheidet sich aufgrund unterschiedlicher Struktur-Packing und Konfigurationsoptionen.