Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Einreichen
ToolsExploitsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
vsock_poc — Untersuchung des Fehlers hinter CVE-2021-26708 | Kitploit
Tools/GitHubGitHub/jordan9001/vsock_poc
SchwachstellenanalyseExploitationDebuggerPapers & ForschungLernen & BildungBinary-Exploitation
GitHubjordan9001/vsock_poc

vsock_poc

Untersuchung des Fehlers hinter CVE-2021-26708

Repository anzeigen
28210vor 5 JahrenVon Kitploit geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

vsock_poc

Untersuchung des Fehlers hinter CVE-2021-26708


Dieses Repository enthält eine kleine Zusammenfassung über CVE-2021-26708 und wie dieser Fehler in eine Use-After-Free-Schreibprimitive umgewandelt werden kann. Der PoC hier ist kein vollständiger Exploit, sondern nur meine Testumgebung, die ich bei der Untersuchung dieses Fehlers verwendet habe. Er kann erfolgreich einen Eintrag aus dem kmalloc-64-Cache nach dessen Freigabe nutzen, enthält aber keinen Code zum Grooming des Speichers und zum Platzieren von etwas Interessantem in dem Slot.

Dies ist ein lustiger Fehler, gemeldet von @a13xp0p0v. Er fiel mir auf, weil der Patch so einfach war: Er verhindert lediglich, dass außerhalb der Sperre an 5 verschiedenen Stellen ein Verweis auf vsk->transport erlangt wird. https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c518adafa39f37858697ac9309c6cf1805581446

Im Folgenden finden Sie eine kurze Schritt-für-Schritt-Anleitung, wie man vom Patch zu einer Use-After-Free-Primitive gelangt, die für die Ausnutzung verwendet werden könnte. Die Anleitung sollte anderen helfen, die diesen Fehler untersuchen möchten.

Umgebungseinrichtung

Ich habe den Linux-Kernel 5.10.13 heruntergeladen und den oben gezeigten Patch manuell rückgängig gemacht. Weitere Informationen zum Erstellen und Ausführen des Kernels finden Sie in der folgenden Referenz.

https://fedoraproject.org/wiki/Building_a_custom_kernel

Ich habe auch die Boot-Parameter geändert, um das Debuggen des Kernels mit kgdb zu ermöglichen. Mit gdb und der vmlinux-Datei, die ich zuvor erstellt hatte, hatte ich alle Kernel-Symbole für den Hauptkernel, aber nicht für ladbare Kernelmodule. Der mit der Sicherheitslücke verbundene Code wurde standardmäßig nicht geladen, sondern würde in den Kernel geladen, wenn die Familie PF_VSOCK verwendet wird (abhängig davon, wie Sie Ihren Kernel erstellt haben).

Um die Symbole in kgdb für geladene Module zu erhalten, habe ich sichergestellt, dass ich den vsock-Socket mindestens einmal benutzt habe, dann habe ich sudo cat /proc/modules | grep vsock verwendet, um die Basisadressen der zugehörigen Module zu erhalten. In gdb habe ich dann so etwas wie (gdb) add-symbol-file ./net/vmw_vsock/vsock.ko 0xffffffffc0567000 eingegeben, um gdb mitzuteilen, wo im Speicher die Symbole dieser ko-Datei sind. vsock.ko und vmw_vsock_virtio_transport_common.ko waren die beiden relevantesten.

Jagd nach der Primitive

Es macht Spaß, rückwärts von Patches zu arbeiten, denn anders als bei vielen Sicherheitslücken-Suchen weiß man bereits mit Sicherheit, dass man an der richtigen Stelle sucht. In diesem Fall wissen wir aus dem Patch, dass ein Verweis auf den Transport gespeichert wird, bevor die sock_lock erlangt wird. Wir können sicher erwarten, dass die Sicherheitslücke auf den Wechsel des Transports zurückzuführen ist, aber der alte Verweis verwendet wird.

In einem solchen Szenario würden wir hoffen, dass der Transport selbst ein dynamisch alloziertes Objekt ist, das zwischen dem Erhalten des Verweises und dem Halten der Sperre freigegeben und durch ein anderes Objekt ersetzt werden kann. Leider scheinen die von den anderen Modulen implementierten relevanten Transporte alle im globalen Speicher zu liegen. Also werden wir eine Ebene tiefer nach Elementen suchen, die verwendet werden, wenn sie außerhalb des Gültigkeitsbereichs liegen.

Der Free Teil 1

In af_vsock.c finden wir zwei Stellen, an denen vsk->transport geändert wird. In vsock_assign_transport und vsock_deassign_transport. In vsock_assign_transport sehen wir, dass, wenn es einen anderen vorhandenen Transport gibt, vsock_deassign_transport aufgerufen wird, bevor der neue Transport platziert wird.

Wenn wir uns die Möglichkeiten für den Aufruf vsk->transport->destruct(vsk) hier ansehen, sehen wir, dass sowohl der Loopback- als auch der Virtio-Transport einfach vsk->trans per kfree freigeben hier. Bingo! Wenn wir (1) einen Pfad zu diesem Aufruf finden können, der mit (2) einer verwundbaren Funktion konkurrieren kann, die einen Transportverweis von vor der Zerstörung verwendet, um auf vsk->trans zuzugreifen, dann haben wir unsere Primitive.

Auf der Suche nach einem Pfad zu vsock_deassign_transport sehen wir, dass es von vsock_sk_destruct oder vsock_assign_transport aufgerufen wird. vsock_sk_destruct ist als die Funktion sock->destruct gesetzt, daher können Aufrufe von __sys_close oder anderen verfügbaren Aufrufen entlang des Zerstörungspfads wie sock_put, sock_close oder vsock_release hier landen.

Der relevanteste Pfad zu vsock_assign_transport führt über vsock_stream_connect, erfordert jedoch, dass sich der Socket in einigen bestimmten Zuständen befindet, und ruft vsock_deassign_transport nur auf, wenn sich der Transport ändert. Und es würde den Parameter vsk->trans ersetzen, wenn wir keinen NULL-neuen Transport erhalten.

Die Nutzung

Bevor wir zu weit gehen, um den richtigen Pfad zur Freigabe zu finden, wollen wir sicherstellen, dass es einen gültigen Pfad gibt, der das Mitglied vsk->trans mit einem ungültigen Verweis auf einen zerstörten Transport verwendet. Wir können methodisch jede Stelle überprüfen, an der der Transport mit einem möglicherweise ungültigen Verweis verwendet wird. Wenn wir diese Lücken verfolgen, können wir Stellen finden, an denen vsk->trans verwendet wird. Der beste Pfad scheint über vsock_stream_setsockopt hier zu führen, wenn transport->notify_buffer_size in einen Offset innerhalb von vsk->trans für Loopback- und Virtio-Transports schreibt genau hier. Wenn trans bereits freigegeben ist, wenn es dort verwendet wird, erhalten wir einen schönen Schreibvorgang eines u32 auf einen Offset von 0x28 in einer kmalloc-64-Allokation.

Das Rennen

Die Verwendung von vsock_stream_setsockopt als Primitive hängt von einem Rennen (Race) ab, bei dem zwischen dem Erhalten des Verweises auf den Transport und dem Erhalten der sock_lock eine kleine Zeitspanne liegt. Das ist ein kleines Fenster, und es gibt viele Anweisungen, um dorthin zu gelangen. Hier können wir eine coole Funktion in Linux namens userfaultfd nutzen, um unsere Chancen zu verbessern. Dieser Mechanismus ermöglicht es uns, Seitenfehler im Benutzermodus nach Belieben zu behandeln. Siehe https://man7.org/linux/man-pages/man2/ioctl_userfaultfd.2.html und https://man7.org/linux/man-pages/man2/userfaultfd.2.html.

Damit können wir einen Thread (den Gater) haben, der die sock_lock erlangt und dann auf einige Benutzerspeicher zugreift und einen Seitenfehler verursacht. Wir können diesen Thread (mit noch gehaltener Sperre) so lange pausieren, wie wir wollen. Andere Threads, die versuchen, diese Sperre zu erlangen, bleiben dort, bis wir den Gater gehen lassen und die Sperre freigeben. Wir können unseren Thread, der die Zerstörung durchführen wird, und unseren Thread, der den ungültigen Verweis verwenden wird, aufstellen. Beide werden auf die sock_lock warten, und jetzt haben wir eine großartige Chance, das Rennen zu gewinnen. Wenn der Thread, der die Zerstörung durchführt, als Nächstes die Sperre erhält, wird unser setsockopt-Aufruf danach abgeschlossen. Er wird den Zeiger vsk->trans verwenden, nachdem er freigegeben (und ersetzt) wurde.

Wenn stattdessen der setsockopt-Aufruf zuerst kommt, verlieren wir das Rennen, können aber den gesamten Vorgang sicher erneut versuchen.

Tool herunterladen