Los Caballeros

"Sobre seguridad, programación, modding, frikismo, etc... "

Tecnicas de fingerprinting a servidores web 1

Twitter icon Twitter icon
Una tecnica mas para fingerprinting a servidores web...

Un paquete GET basico tiene mas o menos la siguiente estructura:

GET / HTTP/1.1
Host: hackingtelevision.blogspot.com



Como pueden notar el caracter que se utilizar para separar campos (el campo del metodo, de la direccion absoluta o relativa del archivo y la version de protocolo, asi como el nombre del encabezado y el valor) es un espacio, pero pasa algo curioso, muchos servidores web no solo soportan ese caracter como separador, ahora vamos a ver algunas firmas unicas de los servidores web mas utilizados:

Apache/2.x: 9,11,12,13,32
IIS/x.x: 9,32
GWS: 10,32
Cherokee Web Server: 32

Ahora en base a esto podemos programar un analizador:


#!/usr/bin/perl
use IO::Socket::INET;

# by Xianur0

open REGLAS,"reglas.txt";
%reglas = ();
@estados = ("501","400","502");
my $firma = "";
while($linea = <REGLAS>) {
if($linea =~ /^separador:\s+/) {
($separador,$servidor) = ($linea =~ /^separador:\s+(.+)=>(.+)$/);
$servidor =~ s/<!--.+//g;
$servidor =~ s/^(\s|\t)+//g;
$servidor =~ s/(\s|\t)$//g;
$separador =~ s/([^\d\,])//g;
$reglas{$separador} =  $servidor;
}
}
for($numero = 0; $numero < 33; $numero++) {
my $char = chr($numero);
my $paquete = "GET${char}/${char}HTTP/1.1\r\nHost: ".$ARGV[0]."\r\nConnection: close\r\n\r\n";
SOCKER: while(true) {
$sock = IO::Socket::INET->new(PeerAddr => $ARGV[0],
 PeerPort => $ARGV[1],
Timeout => 3,
 Proto => 'tcp');
last SOCKER if($sock);
}
binmode($sock);
binmode($paquete);
$resulta = "";
print $sock $paquete;
while(<$sock>) {
$resulta .= $_;
}
$contador = 0;
($estado,$crlf) = ($resulta =~ /^(.+?)(\r|\r\n|\n)/);
BLOQUE: foreach $num (@estados) {
if($estado =~ /^HTTP\/(1|0)\.(0|9|1)\s$num/i || $estado !~ /^HTTP\//) {
$contador++;
last BLOQUE;
}
}
if($contador == 0) {
$firma .= $numero.",";
print "[-] Numero soportado: ".$numero."\n".$estado."\n";
}
close($sock);
}
$firma =~ s/,$//g;
if($reglas{$firma} ne "") {
print "[!] Servidor reconocido: ".$reglas{$firma}."\n";
}
else {
print "[x] Servidor desconocido!\n\tFirma: ".$firma."\n";
}


Se tiene que crear un reglas.txt, mas o menos como este:

separador: 9,11,12,13,32 => Apache/2.x
separador: 9,32 => IIS/x.x
separador: 10,32 => GWS
separador: 32 => Cherokee Web Server

Aqui ya pueden ir integando mas servidores web


Saludos!