2013-12-21 9 views
12

Für eine Klasse in Software-Sicherheit muss ich eine einfache Rückkehr zu libc Angriff machen. Ich habe es geschafft, ein Perl-Skript zu erstellen, das den Angriff mit den richtigen Zeigern zu system(), exit() und der/bin/sh-Zeichenfolge vervollständigt. Ich habe diese Zeiger mit gdb "p system" usw. gefunden. Nun möchte ich den Exploit etwas "dynamischer" machen, indem ich ein c-Programm schreibe, das zur Laufzeit die adressen von system() und exit() findet. Wie mache ich das? Ich habe versucht "& System", aber das scheint mir nicht die richtige Adresse überhaupt geben.Zurück zu libc finding pointers

Bearbeiten: Das System hat keine ASLR aktiviert.

Antwort

6

Sie einfach die Adressen mit binutils finden - objdump oder readelf, aber nur Adressen der Symbole der binären tatsächlich verwendet wird. Die nicht verwendeten Symbole sind nicht mit der libc-Bibliothek verknüpft.

Sagen Sie den ls Befehl hacken wollen:

objdump -d `which ls` | less 

Sie diesen Abschnitt finden:

0000000000402910 <[email protected]>: 
    402910:  ff 25 da 89 21 00  jmpq *0x2189da(%rip)  # 61b2f0 <_fini+0x208704> 
    402916:  68 5e 00 00 00   pushq $0x5e 
    40291b:  e9 00 fa ff ff   jmpq 402320 <_init+0x10> 

So, jetzt die Adresse Sie haben: 0x402910 ist die Sprungadresse der exit() Funktion (die, die Sie gedruckt bekommen würden, wenn Sie es versuchten printf("%x\n", exit);

In Bezug auf system, ls verwendet dieses Symbol nicht, sodass Sie nicht auf diese Weise darauf zugreifen können, da es nicht verknüpft ist.

+0

Wenn es kein Bibliothekseinstiegspunkt ist, muss es irgendwo definiert werden. Der C-Standard verlangte, dass er als eine Funktion definiert wurde, so dass er irgendwo existieren musste. Versuchen Sie es zu finden. – randomusername

+0

@randomusername Ich habe meine Antwort aktualisiert - jetzt weiß ich genau, wie ich die Adresse der Funktion finde.Aber ** das Symbol/die Funktion, die Sie aufrufen möchten, müssen bereits von der Binärdatei verwendet werden, die Sie hacken möchten. ** Andernfalls ist es nicht verknüpft. – TMS

+0

@randomusername ein Prozess wird auch enden, wenn Main zurückkommt ... es gibt keine spezielle Funktion für das ... du hast gerade kein Programm mehr. Wenn ein Symbol nicht verwendet wird, ist es nicht erforderlich, dass es sich irgendwo in der Objektdatei befindet. und wenn es nicht kompiliert wird, müsste man es zur Laufzeit dynamisch verknüpfen ... was von begrenztem Nutzen ist, weil das Programm es nicht benutzt und man bereits beliebigen Code an diesem Punkt ausführt. –

0

Ich denke &system wird zur Kompilierzeit aufgelöst werden. Haben Sie versucht dlopen() und dlsym()? Nur Vorschläge, ich weiß nicht, ob sie funktionieren werden.

bearbeiten

Keiner von ihnen wird außerhalb des Zielprozesskontext funktionieren, wenn irgendeine Art von Address space layout randomization an seinem Platz ist.

2

ASCII-Armoring ist standardmäßig auf einigen gängigen Linux-Distributionen aktiviert. Im Allgemeinen werden Adressen wichtiger Bibliotheken einem Speicherbereich zugeordnet, der ein NULL-Byte enthält. Sie können mehr darüber lesen, wie ASCII Armoring umgehen here.

+0

Ein interessanter Artikel. Danke für das Teilen. +1 –

2

Wenn ich mich nicht irre, versuchen Sie, ein Programm in C zu schreiben, das ein anfälliges Userspace-Programm ausführt und ausnutzt? In diesem Fall, wenn Ihr in C geschriebenes Programm execve() verwendet, startet dies den anfälligen Prozess mit seinem eigenen Prozessraum. Dies beinhaltet libc neu geladen. Betrachten Sie es wie folgt aus:

pwner 
`-[libc] 
`-./vuln 
    `-[libc] 

In diesem Fall Ihr dynamisches Programm, ‚pwner‘ müssen so etwas wie die ptrace() syscall verwenden, um die gefährdeten Programm zu verfolgen und erhalten libc Zeiger. Dies ist effektiv, was GDB auch tut, wenn es eine Binärdatei debuggt. Ihr Programm sollte die ELF-Spezifikation verwenden, um die Adresse von E_ENTRY zu finden. Verwenden Sie von hier aus ptrace(). Zuerst mit PTRACE_TRACEME und dann PTRACE_PEEKTEXT.