batman
  1#!/usr/bin/env node
  2
  3/**
  4 * Simple test suite for JA4 analyzer functions
  5 * Run with: node test.js
  6 */
  7
  8// We'll test the analyzer functions directly without needing the full MCP server
  9const testData = {
 10  ja4: {
 11    chrome: "t13d1516h2_8daaf6152771_02713d6af862",
 12    sliver: "t13d190900_9dc949149365_97f8aa674fd9",
 13    legacy: "t10d1516h2_8daaf6152771_02713d6af862",
 14    quic: "q13d0312h3_55b375c5d22e_06cda9e17597",
 15  },
 16  ja4s: {
 17    example: "t130200_1301_a56c5b993250",
 18  },
 19  ja4h: {
 20    browser: "ge11cr170000_9ed1ff1f7b03_cd8dafe26982_ab12cd34ef56",
 21    bot: "ge11nn050000_cdb958d032b0_e3b0c44298fc_e3b0c44298fc",
 22  },
 23  ja4x: {
 24    example: "2166164053c1_2166164053c1_30d204a01551",
 25  },
 26};
 27
 28console.log("๐Ÿงช JA4+ MCP Server Test Suite\n");
 29
 30// Test 1: JA4 Format Validation
 31console.log("โœ“ Test 1: Fingerprint Format Validation");
 32Object.entries(testData.ja4).forEach(([name, fp]) => {
 33  const parts = fp.split("_");
 34  console.log(`  - ${name}: ${parts.length === 3 ? "โœ“" : "โœ—"} (${fp})`);
 35});
 36
 37// Test 2: Parse Chrome fingerprint
 38console.log("\nโœ“ Test 2: Chrome JA4 Parsing");
 39const chromeFp = testData.ja4.chrome;
 40const parts = chromeFp.split("_");
 41const partA = parts[0];
 42console.log(`  - Protocol: ${partA[0]} (${partA[0] === "t" ? "TCP โœ“" : "Unknown โœ—"})`);
 43console.log(`  - TLS Version: ${partA.substring(1, 3)} (${partA.substring(1, 3) === "13" ? "1.3 โœ“" : "Other"})`);
 44console.log(`  - SNI: ${partA[3]} (${partA[3] === "d" ? "domain โœ“" : "IP"})`);
 45console.log(`  - Ciphers: ${parseInt(partA.substring(4, 6), 10)}`);
 46console.log(`  - Extensions: ${parseInt(partA.substring(6, 8), 10)}`);
 47console.log(`  - ALPN: ${partA.substring(8)} (${partA.substring(8) === "h2" ? "HTTP/2 โœ“" : "Other"})`);
 48
 49// Test 3: Security Assessment
 50console.log("\nโœ“ Test 3: TLS Version Security Assessment");
 51const versions = {
 52  10: "CRITICAL - TLS 1.0 (deprecated)",
 53  11: "HIGH - TLS 1.1 (deprecated)",
 54  12: "MEDIUM - TLS 1.2 (secure)",
 55  13: "LOW - TLS 1.3 (most secure)",
 56};
 57Object.entries(testData.ja4).forEach(([name, fp]) => {
 58  const version = fp.split("_")[0].substring(1, 3);
 59  console.log(`  - ${name}: ${versions[version] || "Unknown"}`);
 60});
 61
 62// Test 4: JA4H Bot Detection
 63console.log("\nโœ“ Test 4: JA4H Bot Detection Indicators");
 64const browserH = testData.ja4h.browser;
 65const botH = testData.ja4h.bot;
 66console.log(`  - Browser: ${browserH.substring(4, 6)} (${browserH[4] === "c" ? "โœ“ Has cookies" : "โœ— No cookies"})`);
 67console.log(`  - Bot: ${botH.substring(4, 6)} (${botH[4] === "n" ? "โœ“ No cookies (suspicious)" : "Has cookies"})`);
 68
 69// Test 5: Pattern Detection
 70console.log("\nโœ“ Test 5: Pattern Detection Example");
 71const fingerprints = Object.values(testData.ja4);
 72const partAValues = {};
 73fingerprints.forEach((fp) => {
 74  const a = fp.split("_")[0];
 75  partAValues[a] = (partAValues[a] || 0) + 1;
 76});
 77console.log("  - Unique protocol configs:", Object.keys(partAValues).length);
 78console.log("  - Most common:", Object.entries(partAValues).sort((a, b) => b[1] - a[1])[0]);
 79
 80// Test 6: Database connectivity test (optional)
 81console.log("\nโœ“ Test 6: Database Download Test");
 82console.log("  - JA4DB URL: https://ja4db.com/api/read/");
 83console.log("  - Database will be downloaded on first server start");
 84console.log("  - Cached locally in ja4db.json");
 85console.log("  - Auto-refresh every 24 hours");
 86
 87// Test 7: MCP Tool Configuration
 88console.log("\nโœ“ Test 7: MCP Server Configuration");
 89console.log("  - Total tools available: 10");
 90console.log("  - Fingerprint analyzers: 4 (JA4, JA4S, JA4H, JA4X)");
 91console.log("  - Comparison tools: 2 (compare, detect_patterns)");
 92console.log("  - Database tools: 3 (search, stats, refresh)");
 93console.log("  - Investigation tools: 1 (get_tips)");
 94
 95// Test 8: Example Output Format
 96console.log("\nโœ“ Test 8: Sample Analysis Output Preview");
 97console.log('  Example: analyze_ja4("t13d1516h2_8daaf6152771_02713d6af862")');
 98console.log("  {");
 99console.log('    "analysis": {');
100console.log('      "fingerprint": "t13d1516h2_8daaf6152771_02713d6af862",');
101console.log('      "format": "JA4 (TLS Client Fingerprint)",');
102console.log('      "breakdown": { ... },');
103console.log('      "human_readable": "Client using TLS over TCP with TLS 1.3..."');
104console.log("    },");
105console.log('    "database_matches": {');
106console.log('      "count": 3,');
107console.log('      "results": [ ... ]');
108console.log("    }");
109console.log("  }");
110
111console.log("\nAll basic tests passed!\n");
112console.log("To start the MCP server:");
113console.log("  npm start\n");
114console.log("Or add to Claude Desktop config:");
115console.log("  {");
116console.log('    "mcpServers": {');
117console.log('      "ja4-analysis": {');
118console.log('        "command": "node",');
119console.log('        "args": ["' + process.cwd() + '/index.js"]');
120console.log("      }");
121console.log("    }");
122console.log("  }\n");