
Stack-basierter Pufferüberlauf in R 3.4.4. Vollständige Exploitation auf x86, aber auf x64 nur RIP-Kontrolle mit Gadget-Analyse aufgrund von Programmbeschränkungen. Dieselbe Schwachstelle auf zwei Architekturen führt zu unterschiedlichen Exploitationspfaden.
Stack-basierter Pufferüberlauf in R 3.4.4. Vollständige Ausnutzung auf x86, aber nur RIP-Kontrolle mit Gadget-Analyse auf x64 aufgrund von Programmrestriktionen. Dieselbe Schwachstelle auf zwei Architekturen, die zu unterschiedlichen Ausnutzungspfaden führt.
Dieses Repository ist Teil des Materials, das ich beim Unterrichten von Memory-Corruption-Exploitation verwende (zusätzlich zu meiner regulären Arbeit unterrichte ich auch in verschiedenen Cybersicherheitskursen, wo ich helfe, die nächste Generation von Reverse Engineers auszubilden).
CVE-2019-25485 ist der Fall, den ich verwende, wenn ich möchte, dass Studenten dieselbe Schwachstelle auf zwei verschiedenen Architekturen durcharbeiten und aus erster Hand sehen, was sich zwischen ihnen ändert. R 3.4.4 wird sowohl in x86- als auch in x64-Versionen ausgeliefert, und in beiden existiert exakt derselbe Überlauf, dasselbe GUI-Feld, derselbe Eingabe-Handler, derselbe Absturz. Beide sind hier als separate Übungen dokumentiert und ausgenutzt:
R 3.4.4 ist eine statistische Rechenanwendung, kein Netzwerkdienst und kein Browser. Der Überlauf wird über ein Desktop-GUI-Feld ausgelöst, was bedeutet, dass die Angriffsfläche völlig anders ist als bei jedem anderen Fall, den ich unterrichte. Was diesen Fall für den Unterricht nützlich macht:
R ist eine statistische Rechen- und Grafikumgebung, die für Windows, macOS und Linux verfügbar ist. Die Schwachstelle befindet sich im GUI-Präferenzen-Dialog, genauer gesagt im Feld Sprache für Menüs und Meldungen, das Benutzereingaben ohne Längenprüfung in einen Stack-Puffer fester Größe kopiert.
Wichtige technische Details:
R 3.4.4 verarbeitet das Feld Sprache für Menüs und Meldungen, indem es die bereitgestellte Zeichenfolge ohne Längenprüfung in einen Stack-Puffer fester Größe kopiert. Eine vereinfachte Version der verwundbaren Logik sieht wie folgt aus:
char language_buffer[256];
strcpy(language_buffer, user_input);
Das Senden einer ausreichend langen Zeichenfolge führt dazu, dass die Kopie über das Ende des Puffers hinausschreibt und den Stack korrumpiert, bis die gespeicherte Rücksprungadresse überschrieben wird. Wenn die Funktion zurückkehrt, lädt die CPU den vom Angreifer kontrollierten Wert vom Stack in RIP und versucht, dorthin zu springen.
Auf x64 erzwingt Windows die Validierung kanonischer Adressen, bevor ein Sprung stattfindet. Ein nicht-kanonischer Wert wie 0x4141414141414141 löst eine sofortige Zugriffsverletzung aus, bevor RIP geladen wird, was bedeutet, dass der Absturz anders aussieht als auf x86, kein sauberes RIP = 4141414141414141. Der Offset muss gefunden werden, indem das zyklische Muster nach dem Absturz vom Stack gelesen wird, anstatt direkt aus RIP.
Der Absturz kann reproduziert werden, indem eine lange Zeichenfolge in das Sprachfeld eingefügt wird. Keine Authentifizierung erforderlich. Beispiel mit Python zum Generieren des Payloads:
import struct
payload = b'A' * 400
with open('payload.txt', 'wb') as f:
f.write(payload)
Open R 3.4.4 x64
Edit -> GUI Preferences
Paste contents of payload.txt into Language for menus and messages
Click OK
Das Ziel dieses Repository ist es nicht nur, den Absturz zu demonstrieren, sondern den vollständigen Ausnutzungsprozess auf beiden Architekturen durchzugehen und zu dokumentieren, was auf x86 funktioniert, was auf x64 bricht und, was noch wichtiger ist, warum.
Um die Haupt-README übersichtlich zu halten, befinden sich die detaillierten Ausnutzungsnotizen, Skripte und Debugger-Schritte im Ordner Vulnerability 📂 dieses Repositorys, organisiert in separate x86- und x64-Unterordner.
Dort finden Sie den vollständigen Arbeitsablauf für beide Architekturen:
x86 - Vollständige Ausnutzung:
x64 - RIP-Kontrolle und Ausnutzungsanalyse: