GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Linux Kernel ROP - Rückkehr zum Userland aus dem Kernel-Kontext?

Am Ende habe ich meinen Shellcode anders geschrieben. Da ich nicht herausfinden konnte, wie ich zurückkehren sollte, ließ ich den Kernel die schwere Arbeit für mich erledigen, um ins Userland zurückzukehren. Die Idee war, mein Privilegien-Eskalationsbit auszuführen und dorthin zurückzuspringen, wo die verwundbare Funktion zurückkehren sollte, wobei die Register und der Stack repariert wurden.

Sobald der Kernel von der verwundbaren Funktion zurückkehrte (wenn er nicht übergelaufen war), bemerkte ich etwas über gdb . (Die Adressen sind frei erfunden, erklären aber trotzdem das Konzept.)

(gdb) x/i $eip
0xadd1: ret
(gdb) x/xw $esp
0xadd1: 0xadd2
(gdb) x/6i 0xadd2
0xadd2: add esp,0x40
0xadd3: pop ...
0xadd4: pop ...
0xadd5: pop ...
0xadd6: pop ...
0xadd7: ret

Unmittelbar nach der Rückkehr sind also 0x40 Byte Stack ungenutzt und würde einfach mit der add esp verschwinden Anweisung. Daher habe ich diese Tatsache ausgenutzt und eine ROP-Kette konstruiert (ich hatte sie bereits beim Schreiben dieser Frage konstruiert, ihre Aufgabe war es, SMEP zu deaktivieren und zu meinem Userland-Shellcode zu springen), die 24 Bytes lang war. 4 Bytes würden den EIP zum Zeitpunkt der Rückgabe überschreiben, die restlichen 20 (0x14 ) würde direkt in den unbenutzten Stapel folgen. Dies lässt uns mit 0x2c zurück Bytes unbenutzter Stack noch.

Aber wenn wir zu 0xadd2 zurückkehren würden , würden wir riskieren, ein weiteres 0x14 zu verlieren Bytes wertvoller Registerinformationen aus dem Stack und das Auffüllen der Register mit ungültigen Daten. Wir könnten add 0x2c bis esp in unserem Userland Shellcode, und springe direkt zu 0xadd3 , wobei das eigentliche add übersprungen wird Anleitung.

Beachten Sie auch aus der Debugging-Sitzung alles außer eax und ebx wurden fachgerecht restauriert. Da mein Überlauf beide zerstört hatte, musste ich sie mit Werten wiederherstellen, die den Fällen ähnelten, in denen die Funktion eine saubere Rückgabe machte. (Dies zu tun war einfach:Ich habe einen Haltepunkt bei 0xadd2 gesetzt , und extrahierte die Werte aus info reg )

Mein endgültiger Userland-Shellcode war also dieser:

Execute privesc payload -> add esp,0x2c -> register fixup -> jump to 0xadd3

Dabei kam der Codepfad vollkommen sauber zurück, und der Kernel erledigte die Aufgabe, für mich in den Benutzermodus zurückzukehren.


Linux
  1. Meine Linux-Geschichte:Vom 8-Bit-Enthusiasten zum Unix-Systemadministrator

  2. Warum ich von Mac zu Linux gewechselt bin

  3. Linux-Systemadministrator werden:Vom Vertrieb zum Systemadministrator

  4. Linux – Sind verschiedene Linux/Unix-Kernel austauschbar?

  5. Wie lade ich Linux-Kernel-Module aus C-Code?

So erstellen Sie einen Linux-Kernel von Grund auf neu {Schritt-für-Schritt-Anleitung}

Linux-Kernel vs. Mac-Kernel

Vom Traum zur Realität:Wie Linux mein Leben verändert hat

Arbeiten mit Microsoft Exchange von Ihrem Linux-Desktop aus

So erstellen Sie einen Linux-Kernel von Grund auf neu

So kompilieren Sie den Linux-Kernel aus der Quelle, um einen benutzerdefinierten Kernel zu erstellen