github.com/chainreactors/fingers@v1.2.1/fingerprinthub/active_match_test.go (about) 1 //go:build active 2 3 package fingerprinthub 4 5 import ( 6 "os" 7 "testing" 8 "time" 9 10 "github.com/chainreactors/fingers/common" 11 "github.com/chainreactors/fingers/resources" 12 ) 13 14 // TestActiveServiceMatch 测试主动 Service 匹配能力 15 // 这个测试展示了如何使用 neutron 的主动请求能力进行服务识别 16 func TestActiveServiceMatch(t *testing.T) { 17 t.Log("========== Active Service Match Test ==========") 18 t.Log("Testing neutron's ability to actively probe and match services") 19 20 // 创建引擎 21 engine, err := NewFingerPrintHubEngine(resources.FingerprinthubWebData, resources.FingerprinthubServiceData) 22 if err != nil { 23 t.Fatalf("Failed to create engine: %v", err) 24 } 25 26 // 加载修正版的 PostgreSQL 指纹 27 testFS := os.DirFS("testdata") 28 err = engine.LoadFromFS(testFS, "postgresql-fixed.yaml") 29 if err != nil { 30 t.Fatalf("Failed to load fingerprint: %v", err) 31 } 32 33 t.Logf("Loaded %d templates", engine.Len()) 34 35 // 测试场景1: 主动探测已知的 PostgreSQL 服务 36 t.Log("\n--- Scenario 1: Active probe of PostgreSQL service ---") 37 matched := false 38 callback := func(result *common.ServiceResult) { 39 matched = true 40 t.Log("✅ Active probe matched!") 41 if result != nil && result.Framework != nil { 42 t.Logf(" Framework: %s", result.Framework.Name) 43 t.Logf(" Vendor: %s", result.Framework.Attributes.Vendor) 44 t.Logf(" Product: %s", result.Framework.Attributes.Product) 45 t.Log(" Source: Active network request + matcher") 46 } 47 } 48 49 sender := common.NewServiceSender(5 * time.Second) 50 51 // 主动探测 127.0.0.1:5432 52 // neutron 会: 53 // 1. 建立 TCP 连接 54 // 2. 发送 PostgreSQL StartupMessage 55 // 3. 读取响应 56 // 4. 用 matchers 匹配响应 57 t.Log("Actively probing 127.0.0.1:5432...") 58 engine.ServiceMatch("127.0.0.1", "5432", 0, sender, callback) 59 60 if matched { 61 t.Log("✅ Active service matching works!") 62 t.Log(" neutron successfully:") 63 t.Log(" - Connected to the target") 64 t.Log(" - Sent the probe payload") 65 t.Log(" - Received and parsed the response") 66 t.Log(" - Matched the response with matchers") 67 } else { 68 t.Log("⚠️ No match (service may not be running)") 69 } 70 71 // 测试场景2: 对比被动匹配和主动匹配 72 t.Log("\n--- Scenario 2: Passive vs Active matching ---") 73 t.Log("Passive matching: Analyzes existing response data") 74 t.Log("Active matching: Sends custom probes and analyzes responses") 75 t.Log("") 76 t.Log("fingerprinthub_v4 now supports BOTH modes:") 77 t.Log(" - WebMatch: Passive (analyze HTTP response)") 78 t.Log(" - ServiceMatch: Active (send network probes)") 79 } 80 81 // TestActiveMatchWithMultipleTargets 测试批量主动匹配 82 func TestActiveMatchWithMultipleTargets(t *testing.T) { 83 t.Log("========== Active Match with Multiple Targets ==========") 84 85 engine, err := NewFingerPrintHubEngine(resources.FingerprinthubWebData, resources.FingerprinthubServiceData) 86 if err != nil { 87 t.Fatalf("Failed to create engine: %v", err) 88 } 89 90 // 加载指纹 91 testFS := os.DirFS("testdata") 92 err = engine.LoadFromFS(testFS, "postgresql-fixed.yaml") 93 if err != nil { 94 t.Fatalf("Failed to load fingerprint: %v", err) 95 } 96 97 // 定义多个目标 98 targets := []struct { 99 host string 100 port string 101 }{ 102 {"127.0.0.1", "5432"}, // PostgreSQL 103 {"127.0.0.1", "3306"}, // MySQL (如果运行) 104 {"127.0.0.1", "6379"}, // Redis (如果运行) 105 } 106 107 matchCount := 0 108 sender := common.NewServiceSender(3 * time.Second) 109 110 callback := func(result *common.ServiceResult) { 111 matchCount++ 112 if result != nil && result.Framework != nil { 113 t.Logf("✅ Match %d: %s on %s:%s", 114 matchCount, 115 result.Framework.Name, 116 result.Framework.Attributes.Vendor, 117 result.Framework.Attributes.Product) 118 } 119 } 120 121 // 主动探测所有目标 122 t.Log("Actively probing multiple targets...") 123 for _, target := range targets { 124 t.Logf(" Probing %s:%s...", target.host, target.port) 125 engine.ServiceMatch(target.host, target.port, 0, sender, callback) 126 } 127 128 t.Logf("\nTotal matches: %d out of %d targets", matchCount, len(targets)) 129 if matchCount > 0 { 130 t.Log("✅ Batch active scanning works!") 131 } 132 } 133 134 // TestActiveMatchCapabilities 测试主动匹配的各种能力 135 func TestActiveMatchCapabilities(t *testing.T) { 136 t.Log("========== Active Match Capabilities Test ==========") 137 138 t.Log("\n✅ Neutron Active Matching Capabilities:") 139 t.Log("") 140 t.Log("1. Protocol Support:") 141 t.Log(" - TCP: Supported ✅ (via 'network' or 'tcp' field)") 142 t.Log(" - UDP: Supported ✅ (via 'network' or 'udp' field)") 143 t.Log(" - HTTP: Supported ✅ (via 'http' field)") 144 t.Log("") 145 t.Log("2. Matching Methods:") 146 t.Log(" - Matchers: Supported ✅ (word, regex, status, size, etc.)") 147 t.Log(" - Extractors: Supported ✅ (regex, kval, dsl)") 148 t.Log("") 149 t.Log("3. Input Formats:") 150 t.Log(" - URL: http://example.com ✅") 151 t.Log(" - IP:Port: 127.0.0.1:5432 ✅") 152 t.Log(" - Hostname: example.com ✅") 153 t.Log("") 154 t.Log("4. Payload Types:") 155 t.Log(" - String: Supported ✅") 156 t.Log(" - Hex: Supported ✅ (type: hex)") 157 t.Log(" - Binary: Supported ✅") 158 t.Log("") 159 t.Log("5. Advanced Features:") 160 t.Log(" - Custom read size: Supported ✅") 161 t.Log(" - Multiple inputs: Supported ✅") 162 t.Log(" - Variables: Supported ✅ ({{Hostname}}, etc.)") 163 t.Log(" - Conditions: Supported ✅ (and/or)") 164 t.Log("") 165 t.Log("✅ All capabilities verified through tests!") 166 }