1
- package whatweb
1
+ package main
2
2
3
3
import (
4
4
"encoding/json"
5
5
"fmt"
6
6
"github.com/PuerkitoBio/goquery"
7
- "github.com/prometheus/common/log"
8
7
"io/ioutil"
9
8
"regexp"
10
9
"strconv"
11
10
"strings"
11
+ // "github.com/prometheus/common/log"
12
12
)
13
13
14
14
/*
15
15
对 https://github.com/unstppbl/gowap/blob/master/gowap.go 进行修改
16
16
17
- 传入以下数据即可进行分析
17
+ 传入以下数据即可进行分析, 已经被改为内存加载具体数据
18
18
19
19
( url, 响应头[list], 网页内容, js返回内容 )
20
20
@@ -23,10 +23,10 @@ TODO:
23
23
*/
24
24
25
25
type HttpData struct {
26
- Url string
27
- Headers map [string ][]string
28
- Html string
29
- Jsret string
26
+ Url string
27
+ Headers map [string ][]string
28
+ Html string
29
+ Jsret string
30
30
}
31
31
32
32
type analyzeData struct {
@@ -64,12 +64,35 @@ type category struct {
64
64
65
65
// Wappalyzer implements analyze method as original wappalyzer does
66
66
type Wappalyzer struct {
67
- HttpData * HttpData
67
+ HttpData * HttpData
68
68
Apps map [string ]* application
69
69
Categories map [string ]* category
70
70
JSON bool
71
71
}
72
72
73
+ var cache = make (map [string ]map [string ]map [string ][]* pattern )
74
+
75
+ func getPatterns (app * application , typ string ) map [string ][]* pattern {
76
+ return cache [app.Name ][typ ]
77
+ }
78
+
79
+ func initPatterns (app * application ) {
80
+ c := map [string ]map [string ][]* pattern {"url" : parsePatterns0 (app .URL )}
81
+ if app .HTML != nil {
82
+ c ["html" ] = parsePatterns0 (app .HTML )
83
+ }
84
+ if app .Headers != nil {
85
+ c ["headers" ] = parsePatterns0 (app .Headers )
86
+ }
87
+ if app .Cookies != nil {
88
+ c ["cookies" ] = parsePatterns0 (app .Cookies )
89
+ }
90
+ if app .Scripts != nil {
91
+ c ["scripts" ] = parsePatterns0 (app .Scripts )
92
+ }
93
+ cache [app .Name ] = c
94
+ }
95
+
73
96
// Init
74
97
func Init (appsJSONPath string , JSON bool ) (wapp * Wappalyzer , err error ) {
75
98
wapp = & Wappalyzer {}
@@ -78,14 +101,14 @@ func Init(appsJSONPath string, JSON bool) (wapp *Wappalyzer, err error) {
78
101
//}
79
102
appsFile , err := ioutil .ReadFile (appsJSONPath )
80
103
if err != nil {
81
- log .Errorf ("Couldn't open file at %s\n " , appsJSONPath )
104
+ // log.Errorf("Couldn't open file at %s\n", appsJSONPath)
82
105
return nil , err
83
106
}
84
107
85
108
temporary := & temp {}
86
109
err = json .Unmarshal (appsFile , & temporary )
87
110
if err != nil {
88
- log .Errorf ("Couldn't unmarshal apps.json file: %s\n " , err )
111
+ // log.Errorf("Couldn't unmarshal apps.json file: %s\n", err)
89
112
return nil , err
90
113
}
91
114
@@ -95,7 +118,7 @@ func Init(appsJSONPath string, JSON bool) (wapp *Wappalyzer, err error) {
95
118
for k , v := range temporary .Categories {
96
119
catg := & category {}
97
120
if err = json .Unmarshal (* v , catg ); err != nil {
98
- log .Errorf ("[!] Couldn't unmarshal Categories: %s\n " , err )
121
+ // log.Errorf("[!] Couldn't unmarshal Categories: %s\n", err)
99
122
return nil , err
100
123
}
101
124
wapp .Categories [k ] = catg
@@ -105,10 +128,11 @@ func Init(appsJSONPath string, JSON bool) (wapp *Wappalyzer, err error) {
105
128
app := & application {}
106
129
app .Name = k
107
130
if err = json .Unmarshal (* v , app ); err != nil {
108
- log .Errorf ("Couldn't unmarshal Apps: %s\n " , err )
131
+ // log.Errorf("Couldn't unmarshal Apps: %s\n", err)
109
132
return nil , err
110
133
}
111
134
parseCategories (app , & wapp .Categories )
135
+ initPatterns (app )
112
136
wapp .Apps [k ] = app
113
137
}
114
138
wapp .JSON = JSON
@@ -124,17 +148,17 @@ type resultApp struct {
124
148
implies interface {}
125
149
}
126
150
127
- func (wapp * Wappalyzer ) ConvHeader (headers string ) ( map [string ][]string ) {
151
+ func (wapp * Wappalyzer ) ConvHeader (headers string ) map [string ][]string {
128
152
head := make (map [string ][]string )
129
153
130
154
tmp := strings .Split (strings .TrimRight (headers , "\n " ), "\n " )
131
155
for _ , v := range tmp {
132
- if strings .HasPrefix (strings .ToLower (v ), "http/1. " ) {
156
+ if strings .HasPrefix (strings .ToLower (v ), "http/" ) {
133
157
continue
134
158
}
135
159
splitStr := strings .Split (v , ":" )
136
160
header_key := strings .ToLower (strings .Replace (splitStr [0 ], "_" , "-" , - 1 ))
137
- header_val := strings .TrimSpace (strings .Join (splitStr [1 :],"" ))
161
+ header_val := strings .TrimSpace (strings .Join (splitStr [1 :], "" ))
138
162
139
163
head [header_key ] = append (head [header_key ], header_val )
140
164
}
@@ -149,7 +173,7 @@ func (wapp *Wappalyzer) Analyze(httpdata *HttpData) (result interface{}, err err
149
173
// analyze html script src
150
174
doc , err := goquery .NewDocumentFromReader (strings .NewReader (httpdata .Html ))
151
175
if err != nil {
152
- log .Fatal (err )
176
+ // log.Fatal(err)
153
177
}
154
178
155
179
doc .Find ("script" ).Each (func (i int , s * goquery.Selection ) {
@@ -163,7 +187,7 @@ func (wapp *Wappalyzer) Analyze(httpdata *HttpData) (result interface{}, err err
163
187
analyze headers cookie
164
188
165
189
two set-cookie?
166
- */
190
+ */
167
191
analyzeData .cookies = make (map [string ]string )
168
192
for _ , cookie := range httpdata .Headers ["set-cookie" ] {
169
193
keyValues := strings .Split (cookie , ";" )
@@ -175,7 +199,6 @@ func (wapp *Wappalyzer) Analyze(httpdata *HttpData) (result interface{}, err err
175
199
}
176
200
}
177
201
}
178
-
179
202
for _ , app := range wapp .Apps {
180
203
analyzeURL (app , httpdata .Url , & detectedApplications )
181
204
if app .HTML != nil {
@@ -214,6 +237,9 @@ func (wapp *Wappalyzer) Analyze(httpdata *HttpData) (result interface{}, err err
214
237
return string (j ), nil
215
238
}
216
239
240
+ //fmt.Println(res)
241
+ fmt .Println (httpdata .Url , res )
242
+
217
243
return res , nil
218
244
}
219
245
@@ -261,7 +287,7 @@ type pattern struct {
261
287
confidence string
262
288
}
263
289
264
- func parsePatterns (patterns interface {}) (result map [string ][]* pattern ) {
290
+ func parsePatterns0 (patterns interface {}) (result map [string ][]* pattern ) {
265
291
parsed := make (map [string ][]string )
266
292
switch ptrn := patterns .(type ) {
267
293
case string :
@@ -277,7 +303,7 @@ func parsePatterns(patterns interface{}) (result map[string][]*pattern) {
277
303
}
278
304
parsed ["main" ] = slice
279
305
default :
280
- log .Errorf ("Unkown type in parsePatterns: %T\n " , ptrn )
306
+ // log.Errorf("Unkown type in parsePatterns: %T\n", ptrn)
281
307
}
282
308
result = make (map [string ][]* pattern )
283
309
for k , v := range parsed {
@@ -314,7 +340,7 @@ func parsePatterns(patterns interface{}) (result map[string][]*pattern) {
314
340
}
315
341
316
342
func analyzeURL (app * application , url string , detectedApplications * map [string ]* resultApp ) {
317
- patterns := parsePatterns (app . URL )
343
+ patterns := getPatterns (app , "url" )
318
344
for _ , v := range patterns {
319
345
for _ , pattrn := range v {
320
346
if pattrn .regex != nil && pattrn .regex .Match ([]byte (url )) {
@@ -361,7 +387,7 @@ func detectVersion(app *resultApp, pattrn *pattern, value *string) {
361
387
1. 如果regex为空的话, 就看headers名是否存在了
362
388
*/
363
389
func analyzeHeaders (app * application , headers map [string ][]string , detectedApplications * map [string ]* resultApp ) {
364
- patterns := parsePatterns (app . Headers )
390
+ patterns := getPatterns (app , "headers" )
365
391
for headerName , v := range patterns {
366
392
headerNameLowerCase := strings .ToLower (headerName )
367
393
@@ -372,7 +398,7 @@ func analyzeHeaders(app *application, headers map[string][]string, detectedAppli
372
398
continue
373
399
}
374
400
375
- if ok && pattrn .regex == nil {
401
+ if ok && pattrn .regex == nil {
376
402
resApp := & resultApp {app .Name , app .Version , app .Categories , app .Excludes , app .Implies }
377
403
(* detectedApplications )[resApp .Name ] = resApp
378
404
}
@@ -393,22 +419,24 @@ func analyzeHeaders(app *application, headers map[string][]string, detectedAppli
393
419
}
394
420
395
421
func analyzeHTML (app * application , html string , detectedApplications * map [string ]* resultApp ) {
396
- patterns := parsePatterns (app . HTML )
422
+ patterns := getPatterns (app , "html" )
397
423
for _ , v := range patterns {
398
424
for _ , pattrn := range v {
425
+
399
426
if pattrn .regex != nil && pattrn .regex .Match ([]byte (html )) {
400
427
if _ , ok := (* detectedApplications )[app .Name ]; ! ok {
401
428
resApp := & resultApp {app .Name , app .Version , app .Categories , app .Excludes , app .Implies }
402
429
(* detectedApplications )[resApp .Name ] = resApp
403
430
detectVersion (resApp , pattrn , & html )
404
431
}
405
432
}
433
+
406
434
}
407
435
}
408
436
}
409
437
410
438
func analyzeScripts (app * application , scripts []string , detectedApplications * map [string ]* resultApp ) {
411
- patterns := parsePatterns (app . Scripts )
439
+ patterns := getPatterns (app , "scripts" )
412
440
for _ , v := range patterns {
413
441
for _ , pattrn := range v {
414
442
if pattrn .regex != nil {
@@ -431,19 +459,17 @@ func analyzeScripts(app *application, scripts []string, detectedApplications *ma
431
459
1. 如果regex为空的话, 就看session名是否存在了
432
460
*/
433
461
func analyzeCookies (app * application , cookies map [string ]string , detectedApplications * map [string ]* resultApp ) {
434
- patterns := parsePatterns (app . Cookies )
462
+ patterns := getPatterns (app , "cookies" )
435
463
for cookieName , v := range patterns {
436
464
cookieNameLowerCase := strings .ToLower (cookieName )
437
465
for _ , pattrn := range v {
438
- cookie , ok := cookies [cookieNameLowerCase ];
466
+ cookie , ok := cookies [cookieNameLowerCase ]
439
467
440
468
if ! ok {
441
469
continue
442
470
}
443
471
444
- //fmt.Println(cookie, cookieName, pattrn)
445
-
446
- if ok && pattrn .regex == nil {
472
+ if ok && pattrn .regex == nil {
447
473
if _ , ok := (* detectedApplications )[app .Name ]; ! ok {
448
474
resApp := & resultApp {app .Name , app .Version , app .Categories , app .Excludes , app .Implies }
449
475
(* detectedApplications )[resApp .Name ] = resApp
@@ -460,4 +486,3 @@ func analyzeCookies(app *application, cookies map[string]string, detectedApplica
460
486
}
461
487
}
462
488
}
463
-
0 commit comments