
Dans le domaine de la cybersécurité, identifier et caractériser précisément les serveurs web est essentiel pour la détection des menaces, l'évaluation des vulnérabilités et la cartographie du réseau. Nous présentons HTTP-Basma, un nouvel algorithme de fingerprinting actif qui révèle des profils de serveurs uniques grâce à une approche multicouche.
HTTP-Basma est disponible en ligne à l'adresse https://httpbasma.netomize.ca/
Dans le domaine de la cybersécurité, identifier et caractériser avec précision les serveurs web est crucial pour la détection des menaces, l'évaluation des vulnérabilités et la cartographie des réseaux. Nous présentons HTTP-Basma, un nouvel algorithme d'empreinte active qui révèle des profils de serveurs uniques grâce à une approche multicouche, répondant ainsi à ce défi.
Caractéristiques clés : Requêtes élaborées, réponses révélatrices : HTTP-Basma envoie 8 sondes HTTP méticuleusement conçues, suscitant des réponses distinctives qui reflètent les configurations des serveurs. Double hachage pour la polyvalence. L'algorithme génère deux hachages :
Regroupement et traque : Ces hachages permettent le regroupement des serveurs, l'identification de serveurs uniques et similaires, ainsi que la poursuite d'acteurs malveillants avec une confiance accrue.
Conception modulaire pour l'extension : L'architecture de l'algorithme favorise l'ajout de nouvelles variantes de hachage, encourageant la collaboration et l'adaptabilité.
Dans cet article, nous examinons d'abord les travaux existants notables sur l'empreinte HTTP, puis nous explorons la fonctionnalité, la conception, l'architecture et les résultats de l'algorithme. De plus, nous présenterons des résultats convaincants issus du balayage du top 1 million de sites web Majestic, y compris l'identification et le regroupement des serveurs HTTP C&C pour diverses familles de logiciels malveillants.
L'idée centrale de l'algorithme d'HTTP-Basma repose sur l'envoi de 8 requêtes HTTP spécialement conçues avec des exigences variées afin de susciter des réponses différentes du serveur. Une fois la réponse du serveur récupérée, la ligne de statut HTTP est disséquée chirurgicalement pour tous ses éléments et encodée de manière optimale. De plus, certains en-têtes sélectionnés de la réponse du serveur sont également vérifiés pour l'encodage.
Les requêtes envoyées sont des types suivants :
Après chaque requête, la réponse du serveur est analysée pour extraire des en-têtes spécifiques et leurs valeurs. Ces données extraites subissent un traitement supplémentaire, y compris la dissection et l'encodage, pour générer une empreinte réversible.
Les détails techniques complets du fonctionnement de l'algorithme figurent dans le document ci-joint.
Cette philosophie de conception modulaire traite chaque empreinte de requête comme un élément de base, permettant une refactorisation élégante, avec la possibilité d'ajouter et de soustraire l'empreinte de toute requête.
Exemples d'empreintes :
- empreinte verbosus : 011420958a0014514bd5221420958a221420958a221420958a2200001420958a22000000001f
- empreinte pacto : 02464ae8b7d86f82c9918e2c2b9d6b91
- note : taux de faux positifs (72/986 910)
- empreinte verbosus : 01142494d60914514bd522142494d6221420958a701420958a220000140e04922032c37f1609
- empreinte pacto : 020769322f3d94ac2f258ddf5ce08502
- note-1 : taux de faux positifs 0
- note-2 : tevedadav.site/43.209.165.126:443 (TLS)
- échantillon-(sha-256) : 9aa1dec8dd12f8adc7fc1274e1958f3613450109ee8b4ec6442a0fcf06df0972
- empreinte verbosus : 01140a85e40014512f3612140a85e422140a85e422140a85e4220000140a85e4220000000001
- empreinte pacto : 0207292309a7a7e798e417d69df5f2a5
- note : taux de faux positifs (73/986 910)
- empreinte verbosus : 01140a85e4001320958a22142494d62214254c5e2214254c5e22080014254c5e220000000000
- empreinte pacto : 0202be780e1eaae0eaa6184e20c909b6
- note : taux de faux positifs (4/986 910)
- empreinte verbosus : 01140a85e4011320958a22142494d67214254c5e2214254c5e22080014254c5e220000000000
- empreinte pacto : 02cc5be6d05192e17de041538508bc22
- note : taux de faux positifs (38/986 910)
- empreinte verbosus : 01140a85e40914514bd522140a85e4721420958a701420958a220800140a85e4720000001609
- empreinte pacto : 0221b4e46bbd0e5c037f5a852ca3fdc0
- note : taux de faux positifs (6/986 910)
HTTP-Basma est un outil en C++ que j'ai développé pour démontrer le caractère pratique et la viabilité de cet algorithme. Il exploite la bibliothèque de Chilkat pour toutes les interactions de sockets HTTP et utilise d'autres classes de support au sein de la bibliothèque. De plus, l'outil comprend une fonction de démêlage qui peut disséquer et inverser le hachage flou verbosus, produisant un objet JSON complet, ainsi qu'une fonction de comparaison qui affiche les différences entre deux empreintes verbosus.
Sachez que certains résultats de l'outil peuvent utiliser des numéros de sondes légèrement différents, mais l'ordre sous-jacent reste cohérent : P1->P1, P2->P2, P3->P3, P4->P4, P->P5, P6->P6F, P7->P6L, P8->P7a.
Usage:
HTTP-Basma [OPTION...]
-d, --domain arg domaines/IP (vous pouvez interroger plusieurs domaines, séparés par des virgules)
-p, --port arg numéro de port
-s, --ssl la connexion HTTP doit-elle être effectuée via SSL/TLS ?
-q, --qpath vérifier le domaine avec le chemin d'URL inclus (non recommandé)
-w, --redirect activer/désactiver les redirections HTTP. Si désactivé/faux, seule la redirection suivante est suivie,
sinon, toutes les redirections sont suivies (défaut : true)
-t, --ctimeout arg valeur du délai d'expiration de la connexion socket en secondes (défaut : 1)
-g, --rtimeout arg valeur du délai d'expiration de lecture socket (depuis le serveur) en secondes (défaut : 1)
-e, --sleep arg la durée (en millisecondes) de pause entre chaque requête (défaut : 100)
-x, --proxy arg configuration du proxy : <"socks4|socks5|http">,<domaine>,<port>,<bool:direct_tls>,<login>,<pass>
toutes les valeurs sont séparées par des virgules. <direct_tls> est ignoré avec un proxy non-HTTP
-f, --file arg fichier contenant la liste des domaines/IP (nécessite "-c/--csv" ou "-j/--json")
-P, --parallel analyser la liste des domaines transmise via l'option "-f/--file" en parallèle
-c, --csv enregistrer dans un fichier CSV ; si l'option 'n' n'est pas spécifiée, le nom du fichier CSV sera généré
automatiquement
-n, --csvfile arg nom du fichier CSV
-j, --json enregistrer dans un fichier JSON ; si l'option 'l' n'est pas spécifiée, le nom du fichier JSON sera généré
automatiquement
-l, --jsonfile arg nom du fichier JSON
-r, --saveh enregistrer les en-têtes de réponse des requêtes
-o, --pjson afficher la dissection de l'empreinte sur la console sous forme d'objet JSON
-i, --demangle_json arg démêler une empreinte dans un format json détaillé (vous pouvez en avoir plus d'un, séparés par des
virgules)
-u, --demangle_txt arg afficher un format texte concis de l'empreinte, séparé par des virgules pour plusieurs résultats
-C, --compare arg comparer deux empreintes verbosus (séparées par des virgules)
-a, --pacto arg obtenir l'empreinte Pacto en utilisant Verbosus
-h, --help afficher l'utilisation
Lors de l'interrogation d'un domaine/IP donné, la réponse peut être enregistrée dans un fichier CSV ou JSON avec une multitude d'informations sur les en-têtes de réponse du serveur et l'empreinte unique de chaque sonde.
Par exemple, pour obtenir l'empreinte du serveur https://google.com et enregistrer les résultats dans des fichiers JSON et CSV, tout en enregistrant les en-têtes de réponse HTTP de chaque sonde :
HTTPBasma.exe -d https://google.com --json --csv --saveh
Dans le dossier Output, vous trouverez le fichier CSV google_hb_results_2026-05-19_08-35-38_am.csv et le fichier JSON google_hb_results_2026-05-19_08-35-38_am.json.
La fonction de démêlage de l'outil "-i/--demangle_json" prend une empreinte verbosus et reconstruit les attributs de chaque sonde, produisant un objet JSON complet. Notamment, lors de la tentative d'inversion des hachages FNV-1a, le démêleur utilise deux bases de données locales : options.csv pour les méthodes HTTP autorisées et status_line_db.csv pour les phrases de raison de la ligne de statut. Si l'un de ces fichiers de base de données est manquant, la fonction d'inversion de hachage correspondante est automatiquement désactivée. Ces bases de données ont été compilées à partir d'un balayage du top 1 million de sites web Majestic.
Le démêlage de l'empreinte verbosus, pour le domaine example.com :
HTTPBasma.exe --demangle_json 01140a85e40014514bd522142494d67214254c5e721420958a22020214254c5e720000001609
{
"type": "verbosus",
"fp": "01140a85e40014514bd522142494d67214254c5e721420958a22020214254c5e720000001609",
"p1": {
"type": "get_normal",
"fp": "140a85e400",
"status_line": {
"http_version": {
"fp": "14",
"val_cmt": "HTTP/1.1"
},
"status_code": {
"fp": "0a",
"val_cmt": "200"
},
"http_reason": {
"fp": "85e4",
"val_cmt": "OK"
},
"sl_reversed_db": {
"http_version": "HTTP/1.1",
"status_code": [
200,
404,
403,
500,
204,
999,
888,
603
],
"http_reason": "OK"
}
},
"sts_hdr": {
"fp": "00",
"cmt": "cet en-tête n'est pas utilisé"
}
},
"p2": {
"type": "get_invalid_ver_nb",
"fp": "14514bd522",
"status_line": {
"http_version": {
"fp": "14",
"val_cmt": "HTTP/1.1"
},
"status_code": {
"fp": "51",
"val_cmt": "505"
},
"http_reason": {
"fp": "4bd5",
"val_cmt": "HTTP Version Not Supported"
},
"sl_reversed_db": {
"http_version": "HTTP/1.1",
"status_code": [
505
],
"http_reason": "HTTP Version Not Supported"
}
},
"cont_len_hdr": {
"fp": "22",
"name": "Content-Length",
"value": ">1",
"cmt": "l'en-tête content-length/transfer-encoding:chunked est présent avec l'une des valeurs de taille : [0,1,>1]"
},
"cnx": {
"ka": false,
"c": true
}
},
"p3": {
"type": "get_rnd_resource",
"fp": "142494d672",
"status_line": {
"http_version": {
"fp": "14",
"val_cmt": "HTTP/1.1"
},
"status_code": {
"fp": "24",
"val_cmt": "404"
},
"http_reason": {
"fp": "94d6",
"val_cmt": "Not Found"
},
"sl_reversed_db": {
"http_version": "HTTP/1.1",
"status_code": [
404,
403,
501,
410,
204,
400,
200,
418
],
"http_reason": "Not Found"
}
},
"cont_len_hdr": {
"fp": "72",
"name": "Transfer-Encoding",
"value": ">1",
"cmt": "l'en-tête content-length/transfer-encoding:chunked est présent avec l'une des valeurs de taille : [0,1,>1]"
},
"cnx": {
"ka": true,
"c": false
}
},
"p4": {
"type": "get_rnd_verb",
"fp": "14254c5e72",
"status_line": {
"http_version": {
"fp": "14",
"val_cmt": "HTTP/1.1"
},
"status_code": {
"fp": "25",
"val_cmt": "405"
},
"http_reason": {
"fp": "4c5e",
"val_cmt": "Method Not Allowed"
},
"sl_reversed_db": {
"http_version": "HTTP/1.1",
"status_code": [
405,
403,
204,
418,
404
],
"http_reason": "Method Not Allowed"
}
},
"cont_len_hdr": {
"fp": "72",
"name": "Transfer-Encoding",
"value": ">1",
"cmt": "l'en-tête content-length/transfer-encoding:chunked est présent avec l'une des valeurs de taille : [0,1,>1]"
},
"cnx": {
"ka": true,
"c": false
}
},
"p5": {
"type": "get_lowercase_verb",
"fp": "1420958a22",
"status_line": {
"http_version": {
"fp": "14",
"val_cmt": "HTTP/1.1"
},
"status_code": {
"fp": "20",
"val_cmt": "400"
},
"http_reason": {
"fp": "958a",
"val_cmt": "Bad Request"
},
"sl_reversed_db": {
"http_version": "HTTP/1.1",
"status_code": [
400,
422,
405,
401
],
"http_reason": "Bad Request"
}
},
"cont_len_hdr": {
"fp": "22",
"name": "Content-Length",
"value": ">1",
"cmt": "l'en-tête content-length/transfer-encoding:chunked est présent avec l'une des valeurs de taille : [0,1,>1]"
},
"cnx": {
"ka": false,
"c": true
}
},
"p6f": {
"type": "get_accept_encoding_full",
"fp": "02",
"cont_enc_hdr": {
"value": "br",
"empty_value": false,
"total_plus": 0
}
},
"p6l": {
"type": "get_accept_encoding_less",
"fp": "02",
"cont_enc_hdr": {
"value": "br",
"empty_value": false,
"total_plus": 0
}
},
"p7a": {
"type": "options_allow_hdr",
"fp": "14254c5e72000000",
"status_line": {
"http_version": {
"fp": "14",
"val_cmt": "HTTP/1.1"
},
"status_code": {
"fp": "25",
"val_cmt": "405"
},
"http_reason": {
"fp": "4c5e",
"val_cmt": "Method Not Allowed"
},
"sl_reversed_db": {
"http_version": "HTTP/1.1",
"status_code": [
405,
403,
204,
418,
404
],
"http_reason": "Method Not Allowed"
}
},
"cont_len_hdr": {
"fp": "72",
"name": "Transfer-Encoding",
"value": ">1",
"cmt": "l'en-tête content-length/transfer-encoding:chunked est présent avec l'une des valeurs de taille : [0,1,>1]"
},
"allow_hdr": {
"fp": "000000",
"cmt": "cet en-tête n'est pas utilisé"
},
"cnx": {
"ka": true,
"c": false
}
}
}
Observez que le tableau « status_code » contient plusieurs codes de statut HTTP. Cela se produit parce que différents serveurs peuvent utiliser la même phrase de raison pour différents codes de statut, ce qui donne des hachages FNV-1a identiques.
L'option de comparaison "-C/--compare" compare deux empreintes verbosus et affiche les différences entre les principaux composants de chacune des sondes.
Par exemple, comparer les deux empreintes suivantes pour Google et YouTube :
HTTPBasma.exe --compare 01140a85e4001320958a22142494d62214254c5e2214254c5e22080014254c5e220000000000,01140a85e4011320958a22142494d67214254c5e2214254c5e22080014254c5e220000000000
Donne ce résultat :
< FPrnt-1 Vs. FPrnt-2 >
[ P1 ]
{Strict-Transport-Security}
en-tête sts : 00 != 01
[ P2 ]
[ P3 ]
{Content-Length}
cl_name : 2 != 7
[ P4 ]
[ P5 ]
[ P6F ]
[ P6L ]
[ P7a ]
La sortie révèle des différences spécifiquement dans le composant de hachage de la sonde P1, où l'en-tête STS est présent dans la première empreinte et pas dans l'autre. De plus, l'encodage du « Content-Length » diffère entre les deux empreintes pour la sonde P3.
Netomize fournit des versions compilées Windows et Linux x64 du code public de ce dépôt. De plus, le fichier CSV des empreintes HTTP-Basma du top 1 million Majestic - ensemble de données est inclus dans la première version.
Ouvert aux pull requests et aux problèmes. Les commentaires et suggestions sont grandement appréciés.