Contribuez à SecuObs en envoyant des bitcoins ou des dogecoins.
Nouveaux articles (fr): 1pwnthhW21zdnQ5WucjmnF3pk9puT5fDF
Amélioration du site: 1hckU85orcGCm8A9hk67391LCy4ECGJca

Contribute to SecuObs by sending bitcoins or dogecoins.



L'art du fingerprinting web ou comment contourner Nmap.

Par Rédaction, secuobs.com
Le 14/03/2006


Résumé : La méthode du Fingerprinting s'apparente à un relevé d'empreintes qui permet d'avoir accès à des informations qui permettront de deviner le type d'applicatif utilisé ainsi que sa version. Nous allons nous intéresser plus particulièrement au cas du serveur web Apache et les différentes techniques existantes pour contourner les outils les plus usuels de fingerprinting.



La méthode du Fingerprinting s'apparente à un relevé d'empreintes qui permet d'avoir accès à des informations qui permettront de deviner le type d'applicatif utilisé ainsi que la version & par là même le système d'exploitation, la version de celui-ci et la distribution.

Nous allons nous intéresser plus particulièrement au cas du serveur web Apache et les différentes techniques existantes pour contourner les outils les plus usuels de fingerprinting.

L'affichage des informations de la bannière du serveur web Apache se configure via les directives ServerSignature & ServerTokens du fichier de configuration d'Apache httpd.conf.

Dans un premier temps nous allons tester les différentes options possibles pour la directive ServerTokens et vérifier les informations renvoyées par Apache :

- Avec ServerTokens Full :

telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.localdomain.
Escape character is '^]'.
GET HTTP/1.0
HTTP/1.1 400 Bad Request
Date: Tue, 14 Mar 2006 12:49:12 GMT
Server: Apache/1.3.33 (Debian GNU/Linux)
Connection: close
Content-Type: text/html; charset=iso-8859-1

On apprend ici que le serveur web est Apache, en version 1.3.33 sur un système d'exploitation de type GNU/Linux & plus spécialement la distribution Debian

- avec ServerTokens Min :

telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.localdomain.
Escape character is '^]'.
GET / /
HTTP/1.1 400 Bad Request
Date: Tue, 14 Mar 2006 12:59:31 GMT
Server: Apache/1.3.33
Connection: close
Content-Type: text/html; charset=iso-8859-1

On apprend ici que le serveur web est Apache, en version 1.3.33, les informations relatives au système d'exploitation ne sont plus présentes.

- avec ServerTokens Prod :

telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.localdomain.
Escape character is '^]'.
GET / /
HTTP/1.1 400 Bad Request
Date: Tue, 14 Mar 2006 13:06:29 GMT
Server: Apache
Connection: close
Content-Type: text/html; charset=iso-8859-1

On apprend ici que le serveur web est Apache, les informations relatives au numéro de version et au système d'exploitation ne sont plus présentes.

- avec ServerTokens Os

telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.localdomain.
Escape character is '^]'.
GET / /
HTTP/1.1 400 Bad Request
Date: Tue, 14 Mar 2006 13:08:15 GMT
Server: Apache/1.3.33 (Debian GNU/Linux)
Connection: close
Content-Type: text/html; charset=iso-8859-1

On apprend ici que le serveur web est Apache, en version 1.3.33 sur un système d'exploitation de type GNU/Linux & plus spécialement la distribution Debian, ce résultat est équivalent à Servertokens Full

Prod est l'option la moins verbeuse pour la directive ServerTokens, intéressons nous maintenant à la directive ServerSignature et ses options :

- avec ServerSignature On & ServerTokens Prod

telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.localdomain.
Escape character is '^]'.
GET / /
HTTP/1.1 400 Bad Request
Date: Tue, 14 Mar 2006 13:12:01 GMT
Server: Apache
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML><HEAD>
<TITLE>400 Bad Request</TITLE>
</HEAD><BODY>
<H1>Bad Request</H1>
Your browser sent a request that this server could not understand.<P>
The request line contained invalid characters following the protocol string.<P>
<P>
<HR>
<ADDRESS>Apache/1.3.33 Server at localhost Port 80</ADDRESS>
</BODY></HTML>
Connection closed by foreign host.

Comme vous pouvez le constater, il n'est pas possible de retrouver les informations relatives au numéro de version dans « Server: Apache » (ServerTokens Prod) ni celles inhérentes au système d'exploitation mais il est possible de retrouver la version du serveur Apache via « <ADDRESS>Apache/1.3.33 Server at localhost Port 80</ADDRESS> » grâce à ServerSignature On.

- avec ServerSignature Off & ServerTokens Prod :

telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.localdomain.
Escape character is '^]'.
GET / /
HTTP/1.1 400 Bad Request
Date: Tue, 14 Mar 2006 13:11:13 GMT
Server: Apache
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML><HEAD>
<TITLE>400 Bad Request</TITLE>
</HEAD><BODY>
<H1>Bad Request</H1>
Your browser sent a request that this server could not understand.<P>
The request line contained invalid characters following the protocol string.<P>
<P>
</BODY></HTML>
Connection closed by foreign host.

Il n'est plus possible de retrouver le numéro de version cependant il n'est pas possible pour l'instant via le fichier httpd.conf de cacher l'empreinte du serveur web Apache.

Les opérations de relevé d'empreintes (fingerprinting) de serveur web peuvent se faire également à l'aide de deux outils bien connus des spécialistes, le scanner de port « opensource » nmap avec l'option -sV qui permet de lister les services et le scanner d'empreinte web httprint qui quant à lui n'est pas en GPL mais peut être utilisé gratuitement à des fins non commerciales :

Vérifions la version du serveur web apache installé sur notre machine :

apache -v
Server version: Apache/1.3.33 (Debian GNU/Linux)
Server built: Sep 6 2005 13:10:30

- Pour installer httprint,

Récupérer httprint sur lien
unzip httprint_linux_301.zip
cd httprint_301/linux

Récupérer un fichier de signatures récent sur lien

./httprint -h localhost -s httprint-signatures.txt
httprint v0.301 (beta) - web server relevé d'empreintes (fingerprinting) tool
(c) 2003-2005 net-square solutions pvt. ltd. - see readme.txt
net-square.com/httprint/
httprint@net-square.com

Finger Printing on localhost:80/
Finger Printing Completed on localhost:80/
--------------------------------------------------
Host: localhost
Derived Signature:
Apache

Banner Reported: Apache
Banner Deduced: Apache/1.3.33 (Darwin) PHP/4.3.11, Apache/1.3.32 (Unix), Apache/1.3.32 (Darwin), Apache/1.3.31 (Unix), Apache/1.3.31 (Darwin), Apache/1.3.29 (Unix), Apache/1.3.29 (Darwin), Apache/1.3.28 (Unix), Apache/1.3.28 (Darwin), Apache/1.3.27 (Darwin)
Score: 135
Confidence: 81.33
------------------------
Scores:
Apache/1.3.33 (Darwin) PHP/4.3.11: 135 81.33
Apache/1.3.32 (Unix): 135 81.33
Apache/1.3.32 (Darwin): 135 81.33
Apache/1.3.31 (Unix): 135 81.33
Apache/1.3.31 (Darwin): 135 81.33
Apache/1.3.29 (Unix): 135 81.33
Apache/1.3.29 (Darwin): 135 81.33
Apache/1.3.28 (Unix): 135 81.33
Apache/1.3.28 (Darwin): 135 81.33
Apache/1.3.27 (Darwin): 135 81.33
Apache/1.3.24 (Darwin): 134 78.27

Httprint reconnaît bien le serveur Apache et sa version 1.33 obtient le score le plus important de probabilité.

Pour installer nmap,

Récupérer nmap sur lien
tar -zxvf nmap-4.01.tgz
cd nmap-4.01
./configure
make
make install

Vérifions le chemin d'installation de nmap :

which nmap
/usr/local/bin/nmap

Vérifions la version de nmap :

nmap -V
Nmap version 4.01 ( www.insecure.org/nmap/ )

On lance un relevé d'empreintes (fingerprinting) sur le port 80 en local :

nmap -sV -p 80 -P0 localhost

Starting Nmap 4.01 ( www.insecure.org/nmap/ ) at 2006-03-14 13:01 CET

Interesting ports on localhost.localdomain (127.0.0.1):
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd

Nmap finished: 1 IP address (1 host up) scanned in 6.053 seconds

Nmap reconnaît bien le serveur httpd Apache mais aucunes informations sur le numéro de version.

Essayons maintenant de contourner cette détection avec le module Modsecurity pour Apache :

Récupérer Modsecurity sur lien
tar -zxvf modsecurity-apache-1.9.2.tar.gz
cd modsecurity-apache-1.9.2/apache1
which apxs
/usr/local/apache/bin/apxs
apxs -cia mod_security.c

Vérifier la présence de la ligne suivante dans le fichier httpd.conf sinon ajouter la :
LoadModule security_module /usr/lib/apache/1.3/mod_security.so
.
Ajuster également les directives de configuration de Modsecurity dans ce fichier de la façon suivante :

<IfModule mod_security.c>
SecFilterEngine On
SecFilterCheckURLEncoding On
SecFilterCheckUnicodeEncoding On
SecFilterForceByteRange 0 255
SecAuditEngine RelevantOnly
SecFilterDebugLevel 0
SecFilterScanPOST On
SecFilterDefaultAction "deny,log,status:401"
SecServerSignature "Microsoft-IIS/4.0"
</IfModule>

La ligne « SecServerSignature "Microsoft-IIS/4.0" » nous intéresse plus particulièrement puisque c'est elle qui est en charge de modifier les informations renvoyées par le serveur Apache.

Pour être effectif, le changement de bannière via Modsecurity doit se faire conjointement à l'utilisation de l'option Full pour la direction ServerTokens, ajuster puis enregistrer votre fichier httpd.conf.

On redémarre le serveur Apache :

/etc/init.d/apache restart
Restarting apache.

Une première vérification :

telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.localdomain.
Escape character is '^]'.
GET / /
HTTP/1.1 400 Bad Request
Date: Tue, 14 Mar 2006 14:54:57 GMT
Server: Microsoft-IIS/4.0
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML><HEAD>
<TITLE>400 Bad Request</TITLE>
</HEAD><BODY>
<H1>Bad Request</H1>
Your browser sent a request that this server could not understand.<P>
The request line contained invalid characters following the protocol string.<P>
<P>
<HR>
<ADDRESS>Apache/1.3.33 Server at localhost Port 80</ADDRESS>
</BODY></HTML>
Connection closed by foreign host.

On a bien « Server: Microsoft-IIS/4.0 » mais aussi « <ADDRESS>Apache/1.3.33 Server at localhost Port 80</ADDRESS> », Modsecurity n'intervient donc qu'au niveau de la directive ServerTokens, il est nécessaire de positionner la directive ServerSignature sur l'option Off, vérification :

telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.localdomain.
Escape character is '^]'.
GET / /
HTTP/1.1 400 Bad Request
Date: Tue, 14 Mar 2006 14:57:37 GMT
Server: Microsoft-IIS/4.0
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML><HEAD>
<TITLE>400 Bad Request</TITLE>
</HEAD><BODY>
<H1>Bad Request</H1>
Your browser sent a request that this server could not understand.<P>
The request line contained invalid characters following the protocol string.<P>
<P>
</BODY></HTML>
Connection closed by foreign host.

On relance maintenant les opérations de relevé d'empreintes (fingerprinting) :

Avec nmap,

/usr/local/bin/nmap -sV -p 80 -P0 localhost

Starting Nmap 4.01 ( www.insecure.org/nmap/ ) at 2006-03-14 15:36 CET
Interesting ports on localhost.localdomain (127.0.0.1):
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS webserver 4.0
Service Info: OS: Windows

Nmap finished: 1 IP address (1 host up) scanned in 6.026 seconds

Modsecurity permet bien de contourner le relevé d'empreintes (fingerprinting) web par nmap. On est même gratifié d'un « Service Info: OS: Windows » du plus bel effet. L'utilisation de l'option -O permet de fingerprinter le système d'exploitation :

nmap -sV -p 80 -P0 -O localhost

Starting Nmap 4.01 ( www.insecure.org/nmap/ ) at 2006-03-14 15:36 CET
Warning: OS detection will be MUCH less reliable because we did not find at least 1 open and 1 closed TCP port
Interesting ports on localhost.localdomain (127.0.0.1):
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS webserver 4.0
Device type: general purpose
Running: Linux 2.4.X
OS details: Linux 2.4.20 - 2.4.22 w/grsecurity.org patch
Uptime 48.958 days (since Tue Jan 24 16:37:08 2006)

Nmap finished: 1 IP address (1 host up) scanned in 7.135 seconds

On récupère un fingerprint « convenable » pour le système d'exploitation mais nmap voit toujours un « 80/tcp open http Microsoft IIS webserver 4.0 », hérésie sous Linux ;)

Avec httprint,

./httprint -h localhost -s httprint-signatures.txt
httprint v0.301 (beta) - web server relevé d'empreintes (fingerprinting) tool
(c) 2003-2005 net-square solutions pvt. ltd. - see readme.txt
net-square.com/httprint/
httprint@net-square.com

Finger Printing on localhost:80/
Finger Printing Completed on localhost:80/
--------------------------------------------------
Host: localhost
Derived Signature:
Microsoft-IIS/4.0

Banner Reported: Microsoft-IIS/4.0
Banner Deduced: Apache/1.3.33 (Unix), Apache/1.3.33 (Darwin) PHP/4.3.11, Apache/1.3.32 (Unix), Apache/1.3.32 (Darwin), Apache/1.3.31 (Unix), Apache/1.3.31 (Darwin), Apache/1.3.29 (Unix), Apache/1.3.29 (Darwin), Apache/1.3.28 (Unix), Apache/1.3.28 (Darwin), Apache/1.3.27 (Darwin)
Score: 56
Confidence: 33.73
------------------------
Scores:
Apache/1.3.33 (Unix): 56 33.73
Apache/1.3.33 (Darwin) PHP/4.3.11: 56 33.73
Apache/1.3.32 (Unix): 56 33.73
Apache/1.3.32 (Darwin): 56 33.73
Apache/1.3.31 (Unix): 56 33.73
Apache/1.3.31 (Darwin): 56 33.73
Apache/1.3.29 (Unix): 56 33.73
Apache/1.3.29 (Darwin): 56 33.73
Apache/1.3.28 (Unix): 56 33.73
Apache/1.3.28 (Darwin): 56 33.73
Apache/1.3.27 (Darwin): 56 33.73
Apache/1.3.24 (Darwin): 55 30.20

Comme vous pouvez le constater, les résultats issus de httprint donne bien « Microsoft-IIS/4.0 » comme bannière reportée mais ne se laisse pas pour autant prendre au piège, bannière déduite la plus probable « Apache/1.3.33 (Unix) », ce qui est conforme aux informations véridiques du serveur web installé sur notre machine. Modsecurity ne contourne pas le relevé d'empreintes (fingerprinting) par httprint.

Il existe une méthode alternative afin de changer directement la bannière du serveur web Apache, pour se faire vous devez éditer les sources du logiciels avant même la compilation d'Apache :

Récupérer Apache sur lien
tar -zxvf apache_1.3.34.tar.gz
groupadd apache
useradd apache -d /dev/null -g apache -s /sbin/nologin
cd apache_1.3.34

Editer le fichier httpd.c dans src/include/, vous trouverez les lignes suivantes :

#define SERVER_BASEVENDOR "Apache Group"
#define SERVER_BASEPRODUCT "Apache"
#define SERVER_BASEREVISION "1.3.34"

enum server_token_type {
SrvTk_MIN, /* eg: Apache/1.3.0 */
SrvTk_OS, /* eg: Apache/1.3.0 (UNIX) */
SrvTk_FULL, /* eg: Apache/1.3.0 (UNIX) PHP/3.0 FooBar/1.2b */
SrvTk_PRODUCT_ONLY /* eg: Apache */
};

#define APACHE_RELEASE 10334100

#define SERVER_PROTOCOL "HTTP/1.1"
#ifndef SERVER_SUPPORT
#define SERVER_SUPPORT "www.apache.org/"

Effectuer les modifications nécessaires

#define SERVER_BASEVENDOR "Microsoft Windows"
#define SERVER_BASEPRODUCT "IIS webserver"
#define SERVER_BASEREVISION "4.0"

enum server_token_type {
SrvTk_MIN, /* eg: Microsoft IIS webserver 4.0 */
SrvTk_OS, /* eg: Microsoft IIS webserver 4.0 */
SrvTk_FULL, /* eg: Microsoft IIS webserver 4.0 */
SrvTk_PRODUCT_ONLY /* eg: Microsoft IIS webserver 4.0 */
};

#define APACHE_RELEASE

#define SERVER_PROTOCOL "HTTP/1.1"
#ifndef SERVER_SUPPORT
#define SERVER_SUPPORT ""

./configure --enable-module=so --server-uid=apache --server-gid=apache
make
make install

Démarrer le serveur Apache :

/usr/local/apache/bin/apachectl start
/usr/local/apache/bin/apachectl start: httpd started

Vérification avec ServerSignature On & ServerTokens Prod :

telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.localdomain.
Escape character is '^]'.
get / /
HTTP/1.1 400 Bad Request
Date: Tue, 14 Mar 2006 15:33:32 GMT
Server: IIS webserver
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML><HEAD>
<TITLE>400 Bad Request</TITLE>
</HEAD><BODY>
<H1>Bad Request</H1>
Your browser sent a request that this server could not understand.<P>
The request line contained invalid characters following the protocol string.<P>
<P>
<HR>
<ADDRESS>IIS webserver/4.0 Server at localhost Port 80</ADDRESS>
</BODY></HTML>
Connection closed by foreign host.

On apprend que « Server: IIS webserver » et « <ADDRESS>IIS webserver/4.0 Server at localhost Port 80</ADDRESS> ». L'opération a donc été effectuée avec succès

Passons au relevé d'empreintes (fingerprinting) avec nmap :

/usr/local/bin/nmap -sV -p 80 -P0 localhost

Starting Nmap 4.01 ( www.insecure.org/nmap/ ) at 2006-03-14 16:36 CET
Interesting ports on localhost.localdomain (127.0.0.1):
PORT STATE SERVICE VERSION
80/tcp open http?

Nmap finished: 1 IP address (1 host up) scanned in 66.072 seconds

Apparemment il n'a pas aimé ;)

Avec httprint :

./httprint -h localhost -s httprint-signatures.txt
httprint v0.301 (beta) - web server relevé d'empreintes (fingerprinting) tool
(c) 2003-2005 net-square solutions pvt. ltd. - see readme.txt
net-square.com/httprint/
httprint@net-square.com

Finger Printing on localhost:80/
Finger Printing Completed on localhost:80/
--------------------------------------------------
Host: localhost
Derived Signature:
IIS webserver

Banner Reported: IIS webserver
Banner Deduced: Apache/1.3.33 (Darwin) PHP/4.3.11, Apache/1.3.32 (Unix), Apache/1.3.32 (Darwin), Apache/1.3.31 (Unix), Apache/1.3.31 (Darwin), Apache/1.3.29 (Unix), Apache/1.3.29 (Darwin), Apache/1.3.28 (Unix), Apache/1.3.28 (Darwin), Apache/1.3.27 (Darwin)
Score: 140
Confidence: 84.34
------------------------
Scores:
Apache/1.3.33 (Darwin) PHP/4.3.11: 140 84.34
Apache/1.3.32 (Unix): 140 84.34
Apache/1.3.32 (Darwin): 140 84.34
Apache/1.3.31 (Unix): 140 84.34
Apache/1.3.31 (Darwin): 140 84.34
Apache/1.3.29 (Unix): 140 84.34
Apache/1.3.29 (Darwin): 140 84.34
Apache/1.3.28 (Unix): 140 84.34
Apache/1.3.28 (Darwin): 140 84.34
Apache/1.3.27 (Darwin): 140 84.34
Apache/1.3.24 (Darwin): 139 81.30

Encore une fois httprint ne se laisse pas prendre au piège quand nmap passe totalement à coté de son sujet. On peut expliquer cette faiblesse par la conception même du processus de relevé d'empreintes (fingerprinting) de Nmap. Il repose sur plusieurs étapes chaînées, la première consiste à recouvrir la bannière du service attaché au port scanné.

Si une bannière est renvoyée nmap s'en contente et ne pousse pas l'investigation plus loin, ce qui n'est pas le cas de httprint qui lui opére une comparaison d'empreinte avec celles présentes dans le fichier signatures.txt (par défaut), httprint-signatures.txt dans notre cas et cela même en ayant reçu une première information via le recouvrement de la bannière.

Nmap est réputé comme l'un ou le meilleur scanner de port existant, cette réputation n'est pas usurpée, cependant comme vous le voyez qui peut le plus peut parfois le moins d'où l'utilité d'avoir toujours dans sa boîte à outils plusieurs logiciels pour une même tâche afin de croiser les résultats et vérifier la véracité de ceux-ci, privilégier également les outils dédiés aux « couteaux suisses » quand cela est possible.

Ce tutorial est basé partiellement sur une présentation de Piotr Sobolewski, rédacteur en chef du magasine Hackin9, réalisée lors de la conférence It Underground qui s'est tenue à Prague les 23 et 24 février derniers.