-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathfinger.go
157 lines (140 loc) · 4.02 KB
/
finger.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
package fingerscan
import (
"context"
"embed"
"fmt"
"github.com/yqcs/fingerscan/utils/arr"
"net"
"strconv"
"strings"
"time"
)
var (
initProbe InitProbe //nmap指纹数据
)
//go:embed data/nmap-service-probes data/nmap-services data/web-finger.json
var temp embed.FS
func InitFinger() {
//解析NMAP
initProbe.initNmap()
//加载web指纹
initProbe.initWappalyze()
}
// ScanFingerprint 扫描
func ScanFingerprint(ip string, port int, timeout time.Duration) *AppFinger {
//检测tcp指纹
finger := probeCheck(ip, port, false, timeout)
//扫描到服务是ssl,再深入识别
if finger != nil && finger.Service == "ssl" {
sslFinger := probeCheck(ip, port, true, timeout)
if sslFinger != nil {
finger.Service += "/" + sslFinger.Service
finger.Version = sslFinger.Version
finger.Response = sslFinger.Response
} else {
if portFinger := initProbe.portToServer(ip, port); portFinger != nil {
finger.Service += "/" + portFinger.Service //BUG处理
}
}
} else if finger == nil {
//通过端口解析服务
finger = initProbe.portToServer(ip, port)
}
//识别web指纹
if finger != nil && strings.Contains(finger.Service, "http") {
if strings.Contains(finger.Service, "ssl/http") {
finger.Service = "https"
}
//获取web指纹
if res := initProbe.webFinger(fmt.Sprintf("%s://%s", finger.Service, net.JoinHostPort(ip, strconv.Itoa(port))), timeout); res != nil {
finger.WebApp = *res
finger.Response = []byte(fmt.Sprintf("%s\n%s", res.Header, res.Body))
}
} else if finger != nil && finger.Service == "ssl" {
if subFinger := initProbe.portToServer(ip, port); subFinger != nil {
finger.Service += "/" + subFinger.Service //BUG处理
}
}
finger = makeTcpFinger(finger)
finger.Uri = net.JoinHostPort(ip, strconv.Itoa(port))
finger.IP = ip
finger.Port = port
return finger
}
func probeCheck(ip string, port int, ssl bool, timeout time.Duration) (finger *AppFinger) {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
//第一步,先匹配匹配port指定端口的探针`
for _, item := range initProbe.probeList {
if ctx.Err() != nil {
return
}
if ((item.ProbeName != "NULL" && (!arr.IntSliceContains(item.Ports, port) || item.Rarity > 7)) && !ssl) || item.Protocol == "UDP" {
continue
}
if finger = initProbe.regxResponse(ip, port, item, ssl); finger != nil {
return
}
time.Sleep(time.Duration(item.TcpWrappedMS) * time.Millisecond)
}
//第二步,匹配sslPort指定端口的探针
for _, item := range initProbe.probeList {
if ctx.Err() != nil {
return
}
//是否ssl检测
if !arr.IntSliceContains(item.SSLPorts, port) || item.Rarity > 7 {
continue
}
if finger = initProbe.regxResponse(ip, port, item, true); finger != nil {
return
}
time.Sleep(time.Duration(item.TcpWrappedMS) * time.Millisecond)
}
//第三步,依次从低到高进行匹配TCP
for _, item := range initProbe.probeList {
if ctx.Err() != nil {
return
}
//过滤以下探针:包含port/sslPort、Name = NULL
if item.ProbeName == "NULL" || arr.IntSliceContains(item.Ports, port) || arr.IntSliceContains(item.SSLPorts, port) || item.Protocol == "UDP" || item.Rarity > 7 {
continue
}
//检测
if finger = initProbe.regxResponse(ip, port, item, ssl); finger != nil {
return
}
time.Sleep(time.Duration(item.TcpWrappedMS) * time.Millisecond)
}
//第四步,匹配全部UDP
for _, item := range initProbe.probeList {
if ctx.Err() != nil {
return
}
if item.Protocol == "TCP" {
continue
}
if finger = initProbe.regxResponse(ip, port, item, ssl); finger != nil {
return
}
time.Sleep(time.Duration(item.TcpWrappedMS) * time.Millisecond)
}
return
}
// GetWebAppList 获取全部WebApp列表
func GetWebAppList() (list []string) {
for k, _ := range initProbe.wappalyze.Apps {
if k != "" {
list = append(list, k)
}
}
return
}
func GetNmapAppList() (list []string) {
for _, item := range initProbe.probeList {
for _, subItem := range item.Matches {
list = append(list, subItem.Service)
}
}
return
}