
サイバーセキュリティの領域では、Webサーバーを正確に特定し特性を把握することが、 脅威検出、脆弱性評価、ネットワークマッピングにとって重要です。私たちは、 多層的なアプローチを通じて独自のサーバープロファイルを明らかにする新しいアクティブフィンガープリンティングアルゴリズム、HTTP-Basmaを紹介します。
HTTP-Basma は https://httpbasma.netomize.ca/ で稼働中です。
サイバーセキュリティの分野では、Webサーバーを正確に識別し特徴付けることが、脅威検出、脆弱性評価、ネットワークマッピングにとって極めて重要です。そこで我々は、多層的なアプローチで独自のサーバープロファイルを明らかにする新しいアクティブフィンガープリンティングアルゴリズム HTTP-Basma を導入し、この課題に取り組みます。
主な特徴: Crafted Requests, Revealing Responses: HTTP-Basma は、サーバー構成を反映した特徴的な応答を引き出すために、綿密に設計された8つのHTTPプローブを送信します。 Dual Hashing for Versatility. アルゴリズムは2つのハッシュを生成します:
Clustering and Hunting: これらのハッシュにより、サーバーのクラスタリング、ユニークで類似したサーバーの識別、悪意のあるアクターの追跡がより確実に行えます。 Modular Design for Expansion: アルゴリズムのアーキテクチャは新しいハッシュバリアントの追加を促進し、コラボレーションと適応性を促します。
本稿では、まずHTTPフィンガープリンティングに関する注目すべき既存研究を概観し、次にアルゴリズムの機能、設計、アーキテクチャ、結果を探ります。さらに、上位100万のMajesticウェブサイトのスキャン から得られた説得力のある発見を紹介します。これには、さまざまなマルウェアファミリーのC&C HTTPサーバーの識別とクラスタリングが含まれます。
HTTP-Basmaのアルゴリズムの核となるアイデアは、異なる要件を持つ8つの特別に作られたHTTPリクエストを送信し、サーバーから異なる応答を引き出すことにあります。サーバーの応答が取得されると、HTTPステータス行がすべての要素に慎重に分解され、最適にエンコードされます。さらに、サーバー応答からの選択されたヘッダーもエンコードがチェックされます。
送信するリクエストは次のタイプです:
各リクエストの後、サーバーの応答が分析され、特定のヘッダーとその値が抽出されます。抽出されたデータは、分解とエンコードを含むさらなる処理を経て、可逆的なフィンガープリントが生成されます。
アルゴリズムの動作に関する完全な技術的詳細は、添付の論文にあります。
このモジュラーデザインの哲学は、各リクエストのフィンガープリントを構成要素として扱い、エレガントなリファクタリングを可能にし、任意のリクエストのフィンガープリントを追加・削除できるようにします。
フィンガープリントのサンプル:
- verbosus fp: 011420958a0014514bd5221420958a221420958a221420958a2200001420958a22000000001f
- pacto fp: 02464ae8b7d86f82c9918e2c2b9d6b91
- note: false-positive rate (72/986,910)
- verbosus fp: 01142494d60914514bd522142494d6221420958a701420958a220000140e04922032c37f1609
- pacto fp: 020769322f3d94ac2f258ddf5ce08502
- note-1: false-positive rate 0
- note-2: tevedadav.site/43.209.165.126:443 (TLS)
- sample-(sha-256): 9aa1dec8dd12f8adc7fc1274e1958f3613450109ee8b4ec6442a0fcf06df0972
- verbosus fp: 01140a85e40014512f3612140a85e422140a85e422140a85e4220000140a85e4220000000001
- pacto fp: 0207292309a7a7e798e417d69df5f2a5
- note: false-positive rate (73/986,910)
- verbosus fp: 01140a85e4001320958a22142494d62214254c5e2214254c5e22080014254c5e220000000000
- pacto fp: 0202be780e1eaae0eaa6184e20c909b6
- note: false-positive rate (4/986,910)
- verbosus fp: 01140a85e4011320958a22142494d67214254c5e2214254c5e22080014254c5e220000000000
- pacto fp: 02cc5be6d05192e17de041538508bc22
- note: false-positive rate (38/986,910)
- verbosus fp: 01140a85e40914514bd522140a85e4721420958a701420958a220800140a85e4720000001609
- pacto fp: 0221b4e46bbd0e5c037f5a852ca3fdc0
- note: false-positive rate (6/986,910)
HTTP-Basma は、このアルゴリズムの実用性と実行可能性を示すために私が開発した C++ ツールです。すべての HTTP ソケット通信に Chilkat ライブラリを利用し、ライブラリ内の他のサポートクラスも活用しています。さらに、このツールには verbosus ファジーハッシュを分解して逆変換し、包括的な JSON オブジェクトを出力するデマングラ機能と、2つの verbosus フィンガープリント間の差異を出力する比較機能が含まれています。
ツールの出力では一部のプローブ番号が若干異なる場合がありますが、基本的な順序は一貫しています: P1->P1, P2->P2, P3->P3, P4->P4, P->P5, P6->P6F, P7->P6L, P8->P7a。
Usage:
HTTP-Basma [OPTION...]
-d, --domain arg domains/IPs (you may query multiple domains, comma separated)
-p, --port arg port number
-s, --ssl does the HTTP connection have to be carried over SSL/TLS?
-q, --qpath check domain with url path included (not recommended)
-w, --redirect enable/disable HTTP redirects. If disabled/false, only the next redirect is followed,
otherwise, all redirects are followed (default: true)
-t, --ctimeout arg socket connection timeout value in seconds (default: 1)
-g, --rtimeout arg socket read (from the server) timeout value in seconds (default: 1)
-e, --sleep arg the duration (in milliseconds) to pause between each request (default: 100)
-x, --proxy arg proxy config: <"socks4|socks5|http">,<domain>,<port>,<bool:direct_tls>,<login>,<pass>
all values are comma-separated. <direct_tls> is ignored with a non-HTTP proxy
-f, --file arg file with list of domains/IPs (requires "-c/--csv" or "-j/--json")
-P, --parallel Scan list of domains passed via the "-f/--file" option in parallel
-c, --csv save to csv file; if the option 'n' is not specified, the CSV filename will be auto
generated
-n, --csvfile arg name of the CSV file
-j, --json save to json file; if the option 'l' is not specified, the JSON filename will be auto
generated
-l, --jsonfile arg name of the JSON file
-r, --saveh save request response headers
-o, --pjson display fingerprint dissection to the console as a JSON object
-i, --demangle_json arg demangle a fingerprint into a detailed json format (you can have more than one, comma
separated)
-u, --demangle_txt arg output a concise text format of the fingerprint, comma-separated for multiple results
-C, --compare arg compare two verbosus fingerprints (comma-separated)
-a, --pacto arg obtain the Pacto fingerprint using Verbosus
-h, --help print usage
特定のドメイン/IP にリクエストすると、サーバーの応答ヘッダーと各プローブの固有フィンガープリントに関する豊富な情報を含む CSV または JSON ファイルに応答を保存できます。
例えば、サーバー https://google.com のフィンガープリントを取得し、結果を JSON ファイルと CSV ファイルに保存し、さらに各プローブの HTTP 応答ヘッダーを保存するには:
HTTPBasma.exe -d https://google.com --json --csv --saveh
Output フォルダに、CSV ファイル google_hb_results_2026-05-19_08-35-38_am.csv と JSON ファイル google_hb_results_2026-05-19_08-35-38_am.json があります。
ツールのデマングラ関数 "-i/--demangle_json" は、verbosus フィンガープリントを受け取り、各プローブの属性を再構築し、包括的な JSON オブジェクトを出力します。特に、FNV-1a ハッシュを逆変換しようとする場合、デマングラは2つのローカルデータベースを利用します: options.csv(許可された HTTP メソッド用)と status_line_db.csv(ステータス行の理由フレーズ用)。これらのデータベースファイルのいずれかが欠けている場合、対応するハッシュ逆変換機能は自動的に無効になります。これらのデータベースは、上位100万の Majestic ウェブサイトのスキャンから作成されました。
verbosus フィンガープリントのデマングル(ドメイン 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": "this header is not used"
}
},
"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": "content-length/transfer-encoding:chunked header is present with either of the size values: [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": "content-length/transfer-encoding:chunked header is present with either of the size values: [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": "content-length/transfer-encoding:chunked header is present with either of the size values: [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": "content-length/transfer-encoding:chunked header is present with either of the size values: [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": "content-length/transfer-encoding:chunked header is present with either of the size values: [0,1,>1]"
},
"allow_hdr": {
"fp": "000000",
"cmt": "this header is not used"
},
"cnx": {
"ka": true,
"c": false
}
}
}
「status_code」配列に複数の HTTP ステータスコードが含まれていることに注意してください。これは、異なるサーバーが異なるステータスコードに対して同じ理由フレーズを使用する可能性があり、その結果、同一の FNV-1a ハッシュになるためです。
比較オプション "-C/--compare" は、2つの verbosus フィンガープリントを比較し、各プローブの主要コンポーネント間の差異を出力します。
例えば、Google と YouTube の以下の2つのフィンガープリントを比較します:
HTTPBasma.exe --compare 01140a85e4001320958a22142494d62214254c5e2214254c5e22080014254c5e220000000000,01140a85e4011320958a22142494d67214254c5e2214254c5e22080014254c5e220000000000
次の出力が得られます:
< FPrnt-1 Vs. FPrnt-2 >
[ P1 ]
{Strict-Transport-Security}
sts header: 00 != 01
[ P2 ]
[ P3 ]
{Content-Length}
cl_name: 2 != 7
[ P4 ]
[ P5 ]
[ P6F ]
[ P6L ]
[ P7a ]
出力は、P1プローブのハッシュコンポーネントに差異があることを示しており、最初のfpではSTSヘッダーが存在し、もう一方にはありません。さらに、P3プローブの「Content-Length」のエンコードが2つのフィンガープリント間で異なっています。
Netomize は、このリポジトリの公開コードのコンパイル済み Windows および Linux x64 バージョンを提供しています。さらに、最初のリリースには、majestic 100万件の HTTP-Basma フィンガープリント CSV ファイル - データセット が含まれています。
プルリクエストとイシューは歓迎します。コメントや提案をいただければ幸いです。