github.com/chainreactors/fingers@v1.2.1/engine_test.go (about) 1 package fingers 2 3 import ( 4 "bytes" 5 "crypto/tls" 6 "fmt" 7 "net/http" 8 "os" 9 "strconv" 10 "testing" 11 "time" 12 13 "github.com/chainreactors/fingers/common" 14 "github.com/chainreactors/fingers/ehole" 15 "github.com/chainreactors/fingers/fingerprinthub" 16 "github.com/chainreactors/fingers/fingers" 17 "github.com/chainreactors/fingers/goby" 18 "github.com/chainreactors/fingers/resources" 19 "github.com/chainreactors/fingers/wappalyzer" 20 "github.com/chainreactors/utils/httputils" 21 ) 22 23 func TestEngine(t *testing.T) { 24 if testing.Short() { 25 t.Skip("skipping test requiring local file in short mode") 26 } 27 engine, err := NewEngine() 28 if err != nil { 29 panic(err) 30 } 31 fmt.Println(engine.String()) 32 33 //client := &http.Client{ 34 // Transport: &http.Transport{ 35 // TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, 36 // }, 37 //} 38 //resp, err := client.Get("https://boce.aliyun.com/detect/http") 39 //if err != nil { 40 // panic(err) 41 //} 42 //start := time.Now() 43 //content := httputils.ReadRaw(resp) 44 45 // 调用 DetectContent 46 47 content, err := os.ReadFile("1.raw") 48 if err != nil { 49 return 50 } 51 frames, err := engine.DetectContent(content) 52 if err != nil { 53 return 54 } 55 56 // 打印执行时间 57 //println("耗时: " + time.Since(start).String()) 58 fmt.Println(frames.String()) 59 60 // 打印内存分配 61 for _, f := range frames { 62 fmt.Println("cpe: ", f.CPE(), "||||", f.String()) 63 } 64 } 65 66 func TestEngine_Match(t *testing.T) { 67 if testing.Short() { 68 t.Skip("skipping live network test in short mode") 69 } 70 engine, err := NewEngine() 71 if err != nil { 72 panic(err) 73 } 74 resp, err := http.Get("http://nc.scsstjt.com:8090/index.jsp") 75 if err != nil { 76 panic(err) 77 } 78 frames := engine.Match(resp) 79 fmt.Println(frames.String()) 80 } 81 82 func TestFavicon(t *testing.T) { 83 if testing.Short() { 84 t.Skip("skipping live network test in short mode") 85 } 86 engine, err := NewEngine() 87 if err != nil { 88 panic(err) 89 } 90 resp, err := http.Get("http://baidu.com/favicon.ico") 91 if err != nil { 92 return 93 } 94 content := httputils.ReadRaw(resp) 95 body, _, _ := httputils.SplitHttpRaw(content) 96 frame := engine.DetectFavicon(body) 97 fmt.Println(frame) 98 } 99 100 func TestFingersEngine(t *testing.T) { 101 if testing.Short() { 102 t.Skip("skipping live network test in short mode") 103 } 104 engine, err := fingers.NewFingersEngine(resources.FingersHTTPData, resources.FingersSocketData, resources.PortData) 105 if err != nil { 106 t.Error(err) 107 return 108 } 109 110 // 模拟比较真实的浏览器请求头 111 headers := http.Header{ 112 "User-Agent": []string{ 113 "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36", 114 }, 115 "Accept": []string{ 116 "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8", 117 }, 118 "Accept-Language": []string{"zh-CN,zh;q=0.9,en;q=0.8"}, 119 "Accept-Encoding": []string{"gzip, deflate"}, 120 "Connection": []string{"keep-alive"}, 121 // 如果目标网站有严格的 referer 检查,可以加上 122 // "Referer": []string{"https://www.google.com/"}, 123 } 124 125 client := &http.Client{ 126 Transport: &http.Transport{ 127 TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, 128 }, 129 } 130 131 req, err := http.NewRequest("GET", "http://nc.scsstjt.com:8090/login/login.php", nil) 132 if err != nil { 133 t.Fatal(err) 134 } 135 136 // 一次性设置所有 header 137 req.Header = headers 138 139 resp, err := client.Do(req) 140 if err != nil { 141 t.Log(err) 142 return 143 } 144 defer resp.Body.Close() 145 146 content := httputils.ReadRaw(resp) 147 frames := engine.WebMatch(content) 148 149 for _, frame := range frames { 150 t.Log(frame) 151 } 152 } 153 154 func TestEngine_MatchWithEngines(t *testing.T) { 155 if testing.Short() { 156 t.Skip("skipping live network test in short mode") 157 } 158 engine, err := NewEngine() 159 if err != nil { 160 t.Error(err) 161 } 162 resp, err := http.Get("http://127.0.0.1") 163 if err != nil { 164 return 165 } 166 167 need := []string{FingersEngine, FingerPrintEngine} 168 frames := engine.MatchWithEngines(resp, need...) 169 for _, frame := range frames { 170 t.Log(frame) 171 } 172 } 173 174 func TestFingerPrintHubsEngine(t *testing.T) { 175 if testing.Short() { 176 t.Skip("skipping live network test in short mode") 177 } 178 engine, err := fingerprinthub.NewFingerPrintHubEngine(resources.FingerprinthubWebData, resources.FingerprinthubServiceData) 179 if err != nil { 180 t.Error(err) 181 } 182 resp, err := http.Get("http://127.0.0.1") 183 if err != nil { 184 return 185 } 186 187 content := httputils.ReadRaw(resp) 188 frames := engine.WebMatch(content) 189 for _, frame := range frames { 190 t.Log(frame) 191 } 192 } 193 194 func TestEHoleEngine(t *testing.T) { 195 if testing.Short() { 196 t.Skip("skipping live network test in short mode") 197 } 198 engine, err := ehole.NewEHoleEngine(resources.EholeData) 199 if err != nil { 200 t.Error(err) 201 } 202 resp, err := http.Get("http://127.0.0.1:8089") 203 if err != nil { 204 return 205 } 206 207 content := httputils.ReadRaw(resp) 208 header, body, ok := httputils.SplitHttpRaw(content) 209 if ok { 210 frames := engine.MatchWithHeaderAndBody(string(header), string(body)) 211 for _, frame := range frames { 212 t.Log(frame) 213 } 214 } 215 } 216 217 func TestGobyEngine(t *testing.T) { 218 if testing.Short() { 219 t.Skip("skipping live network test in short mode") 220 } 221 engine, err := goby.NewGobyEngine(resources.GobyData) 222 if err != nil { 223 t.Error(err) 224 } 225 resp, err := http.Get("https://baidu.com") 226 if err != nil { 227 return 228 } 229 230 content := httputils.ReadRaw(resp) 231 content = bytes.ToLower(content) 232 start := time.Now() 233 frames := engine.WebMatch(content) 234 fmt.Println(frames) 235 fmt.Println(time.Since(start).String()) 236 } 237 238 func TestEngine_Wappalyzer(t *testing.T) { 239 if testing.Short() { 240 t.Skip("skipping live network test in short mode") 241 } 242 engine, err := wappalyzer.NewWappalyzeEngine(resources.WappalyzerData) 243 if err != nil { 244 t.Error(err) 245 return 246 } 247 resp, err := http.Get("http://127.0.0.1:8000") 248 if err != nil { 249 return 250 } 251 252 content := httputils.ReadBody(resp) 253 start := time.Now() 254 frames := engine.Fingerprint(resp.Header, content) 255 fmt.Println(frames) 256 fmt.Println(time.Since(start).String()) 257 } 258 259 func TestAlias(t *testing.T) { 260 engine, err := NewEngine(FingersEngine, FingerPrintEngine) 261 if err != nil { 262 t.Fatal(err) 263 } 264 fmt.Println(engine.FindAny("cdncache_server")) 265 fmt.Println(engine.Aliases.Aliases["cdn-cache-server"]) 266 fmt.Println(engine.Aliases.Map["fingers"]["cdn-cache-server"]) 267 } 268 269 func TestNmapEngine(t *testing.T) { 270 if testing.Short() { 271 t.Skip("skipping live network test in short mode") 272 } 273 engine, err := NewEngine(NmapEngine) 274 if err != nil { 275 t.Error(err) 276 return 277 } 278 279 nmapEngine := engine.Nmap() 280 if nmapEngine == nil { 281 t.Error("nmap engine not found") 282 return 283 } 284 285 fmt.Printf("nmap engine loaded with %d fingerprints\n", nmapEngine.Len()) 286 287 // 测试Service指纹匹配 - 使用common包的默认实现 288 testServiceSender := common.NewServiceSender(3 * time.Second) 289 290 testServiceCallback := func(result *common.ServiceResult) { 291 if result.Framework != nil { 292 t.Logf("detected service: %s", result.Framework.String()) 293 } 294 } 295 296 result := nmapEngine.ServiceMatch("127.0.0.1", "80", 1, testServiceSender, testServiceCallback) 297 if result != nil && result.Framework != nil { 298 t.Logf("service result: %s", result.Framework.String()) 299 } 300 301 // 测试引擎能力 302 capability := nmapEngine.Capability() 303 if !capability.SupportService { 304 t.Error("nmap engine should support service fingerprinting") 305 } 306 if capability.SupportWeb { 307 t.Error("nmap engine should not support web fingerprinting") 308 } 309 310 // 测试WebMatch应该返回空结果 311 webFrames := nmapEngine.WebMatch([]byte("test")) 312 if len(webFrames) != 0 { 313 t.Error("nmap engine WebMatch should return empty results") 314 } 315 } 316 317 // TestServiceEngine 测试Service引擎的能力 318 func TestServiceEngine(t *testing.T) { 319 if testing.Short() { 320 t.Skip("skipping live network test in short mode") 321 } 322 engine, err := NewEngine(NmapEngine) 323 if err != nil { 324 t.Error(err) 325 return 326 } 327 328 // 测试获取支持Service的引擎 329 serviceEngines := engine.GetEnginesByType(common.ServiceFingerprint) 330 expectedServiceEngines := []string{NmapEngine} 331 332 if len(serviceEngines) != len(expectedServiceEngines) { 333 t.Errorf("Expected %d service engines, got %d", len(expectedServiceEngines), len(serviceEngines)) 334 } 335 336 for _, expected := range expectedServiceEngines { 337 found := false 338 for _, actual := range serviceEngines { 339 if actual == expected { 340 found = true 341 break 342 } 343 } 344 if !found { 345 t.Errorf("Expected service engine %s not found", expected) 346 } 347 } 348 349 // 测试DetectService API 350 testSender := common.NewServiceSender(3 * time.Second) 351 352 ports := []int{80, 443, 445, 135, 1080, 3306, 1433, 1521} 353 for _, port := range ports { 354 results, err := engine.DetectService("127.0.0.1", strconv.Itoa(port), 9, testSender, nil) 355 if err != nil { 356 t.Logf("DetectService error: %v", err) 357 } 358 if len(results) > 0 && results[0].Framework != nil { 359 fmt.Printf("DetectService result: %s\n", results[0].Framework.String()) 360 } 361 } 362 }