Wie kriege ich mit ROP einen "/bin/sh" Pointer in rdi?

2 Antworten

Vom Fragesteller als hilfreich ausgezeichnet
Ich kann natürlich "/bin/sh" in den Puffer auf dem Stack schreiben, aber leider ist die Speicheradresse jedes Mal anders und ich kenne sie vorher nicht.

Welche Adresse ist jedes mal anders?

Du könntest vielleicht '"/bin/sh" auf dem Stack ablegen und kennst die Position zum Basepointer, sodaß Du mit dessen Hilfe eine Adresse konstruieren kannst?

DummeStudentin 
Fragesteller
 17.04.2024, 21:10

Die relative Position zum Basepointer kann ich herausfinden. Die sollte sich ja nicht verändern. Aber der Basepointer ist jedes Mal anders.

0
KarlRanseierIII  17.04.2024, 21:22
@DummeStudentin

Die Idee wäre halt den Basepointer (liegt ja in RBP) zu nehmen, den bekannten offset zu Deinem string zu verrechnen udn das Ergebnis in rdi zu legen.

Ich denke da in Richtung:

LEA rdi,[rbp+knownoffset]
1
KarlRanseierIII  17.04.2024, 21:31
@DummeStudentin

Statt eines LEA ginge ggf. auch direkte Arithmetik, also ein geeignetes mov udn add o.ä. .

Ob du damit weiterkommst, kann ich Dir natürlich nicht sagen.

0

Pack doch einfach den String "/bin/sh" in die `.data` Region deiner Software. Dann weißt du immer, wo sich dieser befindet und hast den Pointer dazu.

Hier ein Beispiel: https://www.mourtada.se/calling-printf-from-the-c-standard-library-in-assembly/

DummeStudentin 
Fragesteller
 17.04.2024, 20:37

Es ist ja eben nicht meine eigene Software, sondern eine Challenge, die auf einem fremden Server läuft. Ich kann das Programm also nicht direkt modifizieren, sondern nur Eingaben senden.

0
JanaL161  17.04.2024, 20:42
@DummeStudentin

Ich verstehe nicht ganz.

Du kannst direkt in assembly auf den Stack schreiben. Dann hast du doch auch den Stackpointer, der zu dem String zeigt (wenn du ihn dahin schreibst). Die Adresse kannst du dir in ein Register kopieren und an die Funktion geben.

Wenn nicht, müsstest du mehr Informationen zu dem teilen, wie genau dein Code bisher aussieht.

0
DummeStudentin 
Fragesteller
 17.04.2024, 21:06
@JanaL161

Nein, ich kann kein Assembly auf den Stack schreiben, weil der Stack nicht ausführbar ist. Ich überschreibe durch einen Pufferüberlauf die Rücksprungadresse auf dem Stack, um den Kontrollfluss des Programms zu manipulieren. Deshalb kann ich nur Code, der schon im Programm vorhanden ist, zweckentfremden.

Zum Beispiel gibt es im Programmcode 2 Funktionen, die so enden:

        ...
0x1234: pop rdi
        ret

        ...
0x5678: pop rsi
        ret

Die Adressen habe ich frei erfunden.

Wenn ich die Adresse der "pop rdi" Instruktion auf den Stack schreibe, springt das Programm dort hin, nachdem es mit der aktuellen Funktion fertig ist und liest rdi vom Stack. Die Idee ist jetzt also, solche kleinen Stücke des Programmcodes aneinanderzureihen.

Ich würde dann z.B. das hier als Eingabe senden (natürlich kodiert und Little Endian, aber für die bessere Lesbarkeit lasse ich das hier mal weg):

0x0000000000000000
...
0x0000000000001234
0x0000000000069420
0x0000000000005678
0x0000000000000000
...

Zuerst einige Bytes, sodass 0x1234 an die Stelle auf dem Stack kommt, an der die Rücksprungadresse steht. Dann den Wert, den ich in rdi haben will (ich habe hier 0x69420 als Beispiel verwendet, aber eigentlich will ich einen "/bin/sh" Pointer). 0x5678 ist dann die Rücksprungadresse, die von der "ret" Instruktion nach "pop rdi" verwendet wird, weil ich als nächstes rsi setzen möchte. In rsi schreibe ich in diesem Beispiel 0x0 rein, und so weiter.

Diese Technik heißt rücksprungorientierte Programmierung.

Das funktioniert so weit auch. Ich habe es mit gdb getestet, und die Register haben die richtigen Werte. Aber ich weiß eben nicht, wie ich einen "/bin/sh" Pointer in rdi bekomme.

0