
Quellcode und Konfigurationsdateien zu unserem Artikel in MISC96
Dieses Repository ist eine Ergänzung zu dem im MISC Magazine #96 veröffentlichten Artikel.
Wir haben es geschafft, unsere Privilegien auf zuverlässige Weise zu erhöhen, auf unserer virtuellen Maschine mit SMEP / SMAP und KASLR aktiviert. Es sollte jedoch beachtet werden, dass das System in einem instabilen Zustand zurückgelassen wird und ein Oops sehr wahrscheinlich ist.
Im Ordner configs/ finden Sie Konfigurationsdateien für den Linux-Kernel und Busybox, die jeweils geringfügig von den Standardeinstellungen abweichen.
Der Ordner binaries/ enthält alle vorgebauten Binärdateien, die Sie benötigen, um unsere Testumgebung nachzubilden, wie z. B. ein komplettes Rootfs, das bereit für die Verwendung mit QEMU ist.
linux-stable ist ein Git-Submodul, das auf eine angreifbare Revision des Linux-Kernels verweist. Verwenden Sie git submodule update --recursive, um es abzurufen (wenn Sie mindestens 1 GB freien Speicherplatz auf Ihrem System haben...). Gleiches gilt für busybox.
Unsere Umgebung basiert auf einer x86-QEMU-Virtuellen Maschine mit einem Ordner, der über 9P mit dem Host geteilt wird. Eine anfällige Version des Kernels (ff33952e4d23) wird zusammen mit einer statisch gelinkten Version von Busybox kompiliert.
Unsere Konfiguration ist recht einfach, da wir keine exotischen Architekturen oder Hardware unterstützen müssen. Sie wurde durch Ausführen von make defconfig erstellt und einige Funktionen wurden aktiviert, um QEMUs Netzwerk und Ordnerfreigabe zu unterstützen:
CONFIG_BLK_MQ_VIRTIO=y
CONFIG_MEMORY_BALLOON=y
CONFIG_BALLOON_COMPACTION=y
CONFIG_NET_9P=y
CONFIG_NET_9P_VIRTIO=y
CONFIG_NET_9P_DEBUG=y
CONFIG_VIRTIO_BLK=y
CONFIG_VIRTIO_BLK_SCSI=y
CONFIG_VIRTIO_NET=y
CONFIG_HVC_DRIVER=y
CONFIG_VIRTIO_CONSOLE=y
CONFIG_HW_RANDOM_VIRTIO=y
CONFIG_VIRTIO=y
CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_PCI_LEGACY=y
CONFIG_VIRTIO_BALLOON=y
CONFIG_VIRTIO_INPUT=y
CONFIG_VIRTIO_MMIO=y
CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
CONFIG_9P_FS=y
CONFIG_9P_FS_POSIX_ACL=y
CONFIG_9P_FS_SECURITY=y
GDB-Skripte und Debugsymbole wurden ebenfalls hinzugefügt, um die Entwicklung der ersten PoCs zu erleichtern:
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_INFO_DWARF4=y
CONFIG_GDB_SCRIPTS=y
Bitte beachten Sie, dass in dieser Version KASLR standardmäßig auf x86 aktiviert ist. Da der Kernel nach jedem Neustart an einer anderen Adresse abgebildet wird, kann GDB die Symboldatei nicht zuordnen. Sie haben dann zwei Möglichkeiten: Tests ohne KASLR durchführen oder die Basisadresse des Kernels an symbol-file übergeben, wenn Sie die Symbole in GDB laden.
Nach dem Kompilieren finden Sie die bzImage in linux-stable/arch/x86/boot/bzImage.
Diese Datei ist in binaries/bzImage vorhanden und unsere Konfigurationsdatei in confifs/kernel.config. Um sie zu verwenden, müssen Sie sie nur als .config in linux-stable kopieren.
Wir haben die letzte stabile Version von Busybox, 1.28, verwendet. Die einzige Einstellung, die geändert werden muss, ist CONFIG_STATIC, setzen Sie diese auf y. Das Kompilieren sollte keine Probleme verursachen.
Unsere Konfigurationsdatei ist in configs/busybox.config verfügbar und eine statisch gelinkte Binärdatei in binaries/busybox. Wie bei Linux kopieren Sie sie einfach als .config in den Quellordner von Busybox.
Busybox implementiert bereits einen Init-Prozess, der versucht, /etc/init.d/rcS auszuführen. Normalerweise wird dies von Ihrer Distribution bereitgestellt (möglicherweise mit einem anderen Namen), aber hier müssen wir es selbst erledigen! Dieses Skript erstellt und mountet mehrere erforderliche Systemordner (proc, sys, dev), unseren mit dem Host geteilten Ordner und führt uns in eine unprivilegierte Shell:
for i in $(seq 1 9); do mknod /dev/tty$i c 4 1; done
mknod -m 0666 /dev/null c 1 3
mknod -m 0660 /dev/ttyS0 c 4 64
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devtmpfs none /dev
mkdir -p /mnt/share
mount -t 9p -o trans=virtio share /mnt/share/ -oversion=9p2000.L,posixacl,sync
chmod 777 /mnt/share/
export ENV=/etc/profile
setsid cttyhack setuidgid 1000 sh
umount /proc
umount /sys
umount /dev
poweroff -f
Die Datei /etc/profile ist nicht zwingend erforderlich, aber während unserer Tests recht nützlich, insbesondere als der Exploit nicht zuverlässig war und mehrere Versuche benötigte, um Root-Rechte zu erlangen.
Der Prozess hinter der Erstellung des Exploits ist in MISC 96 ausführlich dokumentiert: Wir verwenden unsafe_put_user, um den Speicher zu durchsuchen, bis wir die Basisadresse des Heaps finden. Dann lassen uns tausende Aufrufe von clone zahlreiche cred-Strukturen im Speicher verteilen. Während unserer Tests war ihre Position im Speicher viel „konstanter“ als bei Verwendung von fork, da es weniger Strukturen für die neue Aufgabe allokiert.
Das Beenden des Kindprozesses führt aufgrund einer fehlerhaften Paging-Anfrage zu einem Kernel-Oops; dies muss korrekt behandelt werden.
Wenn Sie die Zuverlässigkeit dieses Exploits verbessern oder die Dokumentation erweitern möchten, sind Beiträge willkommen! Möglicherweise haben wir auch Fehler oder Ungenauigkeiten bei einigen Konzepten gemacht; zögern Sie nicht, ein Issue zu eröffnen, wenn Sie glauben, dass etwas falsch ist.
Linux-Kernel
Ausnutzung