dddd/lib/gonmap/gonmap.go

242 lines
11 KiB
Go
Raw Normal View History

2023-08-18 08:55:46 +02:00
package gonmap
import (
"log"
"os"
"regexp"
"strings"
"time"
)
var nmap *Nmap
var ProbesCount = 0 //探针数
var MatchCount = 0 //指纹数
var UsedProbesCount = 0 //已使用探针数
var UsedMatchCount = 0 //已使用指纹数
var logger = Logger(log.New(os.Stderr, "[gonmap] ", log.Ldate|log.Ltime|log.Lshortfile))
type Logger interface {
Printf(format string, v ...interface{})
Println(v ...interface{})
}
// r["PROBE"] 总探针数、r["MATCH"] 总指纹数 、r["USED_PROBE"] 已使用探针数、r["USED_MATCH"] 已使用指纹数
func init() {
initWithFilter(9)
}
func initWithFilter(filter int) {
//初始化NMAP探针库
repairNMAPString()
nmap = &Nmap{
exclude: emptyPortList,
probeNameMap: make(map[string]*probe),
probeSort: []string{},
portProbeMap: make(map[int]ProbeList),
filter: filter,
timeout: time.Second,
probeUsed: emptyProbeList,
bypassAllProbePort: []int{161, 137, 139, 135, 389, 443, 548, 1433, 6379, 1883, 5432, 1521, 3389, 3388, 3389, 33890, 33900},
sslSecondProbeMap: []string{"TCP_TerminalServerCookie", "TCP_TerminalServer"},
2024-04-03 06:32:26 +02:00
allProbeMap: []string{"TCP_GetRequest", "TCP_NULL", "TCP_JDWP", "TCP_redis-server", "TCP_ms-sql-s", "TCP_adbConnect"},
2023-08-18 08:55:46 +02:00
sslProbeMap: []string{"TCP_TLSSessionReq", "TCP_SSLSessionReq", "TCP_SSLv23SessionReq"},
}
for i := 0; i <= 65535; i++ {
nmap.portProbeMap[i] = []string{}
}
nmap.loads(nmapServiceProbes + nmapCustomizeProbes)
//修复fallback
nmap.fixFallback()
//新增自定义指纹信息
customNMAPMatch()
//优化检测逻辑,及端口对应的默认探针
optimizeNMAPProbes()
//排序
nmap.sslSecondProbeMap = nmap.sortOfRarity(nmap.sslSecondProbeMap)
nmap.allProbeMap = nmap.sortOfRarity(nmap.allProbeMap)
nmap.sslProbeMap = nmap.sortOfRarity(nmap.sslProbeMap)
for index, value := range nmap.portProbeMap {
nmap.portProbeMap[index] = nmap.sortOfRarity(value)
}
//输出统计数据状态
statistical()
}
func statistical() {
ProbesCount = len(nmap.probeSort)
for _, p := range nmap.probeNameMap {
MatchCount += len(p.matchGroup)
}
UsedProbesCount = len(nmap.portProbeMap[0])
for _, p := range nmap.portProbeMap[0] {
UsedMatchCount += len(nmap.probeNameMap[p].matchGroup)
}
}
func repairNMAPString() {
nmapServiceProbes = strings.ReplaceAll(nmapServiceProbes, "${backquote}", "`")
nmapServiceProbes = strings.ReplaceAll(nmapServiceProbes, `q|GET / HTTP/1.0\r\n\r\n|`,
`q|GET / HTTP/1.0\r\nHost: {Host}\r\nUser-Agent: Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)\r\nAccept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2\r\nAccept: */*\r\n\r\n|`)
nmapServiceProbes = strings.ReplaceAll(nmapServiceProbes, `\1`, `$1`)
nmapServiceProbes = strings.ReplaceAll(nmapServiceProbes, `(?=\\)`, `(?:\\)`)
nmapServiceProbes = strings.ReplaceAll(nmapServiceProbes, `(?=[\w._-]{5,15}\r?\n$)`, `(?:[\w._-]{5,15}\r?\n$)`)
nmapServiceProbes = strings.ReplaceAll(nmapServiceProbes, `(?:[^\r\n]*r\n(?!\r\n))*?`, `(?:[^\r\n]+\r\n)*?`)
nmapServiceProbes = strings.ReplaceAll(nmapServiceProbes, `(?:[^\r\n]*\r\n(?!\r\n))*?`, `(?:[^\r\n]+\r\n)*?`)
nmapServiceProbes = strings.ReplaceAll(nmapServiceProbes, `(?:[^\r\n]+\r\n(?!\r\n))*?`, `(?:[^\r\n]+\r\n)*?`)
nmapServiceProbes = strings.ReplaceAll(nmapServiceProbes, `(?!2526)`, ``)
nmapServiceProbes = strings.ReplaceAll(nmapServiceProbes, `(?!400)`, ``)
nmapServiceProbes = strings.ReplaceAll(nmapServiceProbes, `(?!\0\0)`, ``)
nmapServiceProbes = strings.ReplaceAll(nmapServiceProbes, `(?!/head>)`, ``)
nmapServiceProbes = strings.ReplaceAll(nmapServiceProbes, `(?!HTTP|RTSP|SIP)`, ``)
nmapServiceProbes = strings.ReplaceAll(nmapServiceProbes, `(?!.*[sS][sS][hH]).*`, `.*`)
nmapServiceProbes = strings.ReplaceAll(nmapServiceProbes, `(?!\xff)`, `.`)
nmapServiceProbes = strings.ReplaceAll(nmapServiceProbes, `(?!x)`, `[^x]`)
nmapServiceProbes = strings.ReplaceAll(nmapServiceProbes, `(?<=.)`, `(?:.)`)
nmapServiceProbes = strings.ReplaceAll(nmapServiceProbes, `(?<=\?)`, `(?:\?)`)
nmapServiceProbes = strings.ReplaceAll(nmapServiceProbes, `\x20\x02\x00.`, `\x20\x02..`)
nmapServiceProbes = strings.ReplaceAll(nmapServiceProbes, `match rtmp`, `# match rtmp`)
nmapServiceProbes = strings.ReplaceAll(nmapServiceProbes, `nmap`, `pamn`)
nmapServiceProbes = strings.ReplaceAll(nmapServiceProbes, `Nmap`, `pamn`)
}
func customNMAPMatch() {
//新增自定义指纹信息
nmap.AddMatch("TCP_GetRequest", `echo m|^GET / HTTP/1.0\r\n\r\n$|s`)
nmap.AddMatch("TCP_GetRequest", `mongodb m|.*It looks like you are trying to access MongoDB.*|s p/MongoDB/`)
nmap.AddMatch("TCP_GetRequest", `http m|^HTTP/1\.[01] \d\d\d (?:[^\r\n]+\r\n)*?Server: ([^\r\n]+)| p/$1/`)
nmap.AddMatch("TCP_GetRequest", `http m|^HTTP/1\.[01] \d\d\d|`)
nmap.AddMatch("TCP_NULL", `mysql m|.\x00\x00..j\x04Host '.*' is not allowed to connect to this MariaDB server| p/MariaDB/`)
nmap.AddMatch("TCP_NULL", `mysql m|.\x00\x00..j\x04Host '.*' is not allowed to connect to this MySQL server| p/MySQL/`)
nmap.AddMatch("TCP_NULL", `mysql m|.\x00\x00\x00\x0a(\d+\.\d+\.\d+)\x00.*caching_sha2_password\x00| p/MariaDB/ v/$1/`)
nmap.AddMatch("TCP_NULL", `mysql m|.\x00\x00\x00\x0a(\d+\.\d+\.\d+)\x00.*caching_sha2_password\x00| p/MariaDB/ v/$1/`)
nmap.AddMatch("TCP_NULL", `mysql m|.\x00\x00\x00\x0a([\d.-]+)-MariaDB\x00.*mysql_native_password\x00| p/MariaDB/ v/$1/`)
nmap.AddMatch("TCP_NULL", `redis m|-DENIED Redis is running in.*| p/Redis/ i/Protected mode/`)
nmap.AddMatch("TCP_NULL", `telnet m|^.*Welcome to visit (.*) series router!.*|s p/$1 Router/`)
nmap.AddMatch("TCP_NULL", `telnet m|^Username: ??|`)
nmap.AddMatch("TCP_NULL", `telnet m|^.*Telnet service is disabled or Your telnet session has expired due to inactivity.*|s i/Disabled/`)
nmap.AddMatch("TCP_NULL", `telnet m|^.*Telnet connection from (.*) refused.*|s i/Refused/`)
nmap.AddMatch("TCP_NULL", `telnet m|^.*Command line is locked now, please retry later.*\x0d\x0a\x0d\x0a|s i/Locked/`)
nmap.AddMatch("TCP_NULL", `telnet m|^.*Warning: Telnet is not a secure protocol, and it is recommended to use Stelnet.*|s`)
nmap.AddMatch("TCP_NULL", `telnet m|^telnetd:|s`)
nmap.AddMatch("TCP_NULL", `telnet m|^.*Quopin CLI for (.*)\x0d\x0a\x0d\x0a|s p/$1/`)
nmap.AddMatch("TCP_NULL", `telnet m|^\x0d\x0aHello, this is FRRouting \(version ([\d.]+)\).*|s p/FRRouting/ v/$1/`)
nmap.AddMatch("TCP_NULL", `telnet m|^.*User Access Verification.*Username:|s`)
nmap.AddMatch("TCP_NULL", `telnet m|^Connection failed. Windows CE Telnet Service cannot accept anymore concurrent users.|s o/Windows/`)
nmap.AddMatch("TCP_NULL", `telnet m|^\x0d\x0a\x0d\x0aWelcome to the host.\x0d\x0a.*|s o/Windows/`)
nmap.AddMatch("TCP_NULL", `telnet m|^.*Welcome Visiting Huawei Home Gateway\x0d\x0aCopyright by Huawei Technologies Co., Ltd.*Login:|s p/Huawei/`)
nmap.AddMatch("TCP_NULL", `telnet m|^..\x01..\x03..\x18..\x1f|s p/Huawei/`)
nmap.AddMatch("TCP_NULL", `smtp m|^220 ([a-z0-1.-]+).*| h/$1/`)
nmap.AddMatch("TCP_NULL", `ftp m|^220 H3C Small-FTP Server Version ([\d.]+).* | p/H3C Small-FTP/ v/$1/`)
nmap.AddMatch("TCP_NULL", `ftp m|^421[- ]Service not available..*|`)
nmap.AddMatch("TCP_NULL", `ftp m|^220[- ].*filezilla.*|i p/FileZilla/`)
nmap.AddMatch("TCP_TerminalServerCookie", `ms-wbt-server m|^\x03\0\0\x13\x0e\xd0\0\0\x124\0\x02.*\0\x02\0\0\0| p/Microsoft Terminal Services/ o/Windows/ cpe:/o:microsoft:windows/a`)
nmap.AddMatch("TCP_redis-server", `redis m|^.*redis_version:([.\d]+)\n|s p/Redis key-value store/ v/$1/ cpe:/a:redislabs:redis:$1/`)
nmap.AddMatch("TCP_redis-server", `redis m|^-NOAUTH Authentication required.|s p/Redis key-value store/`)
}
func optimizeNMAPProbes() {
nmap.probeNameMap["TCP_GenericLines"].sslports = nmap.probeNameMap["TCP_GenericLines"].sslports.append(993, 994, 456, 995)
//优化检测逻辑,及端口对应的默认探针
nmap.portProbeMap[993] = append([]string{"TCP_GenericLines"}, nmap.portProbeMap[993]...)
nmap.portProbeMap[994] = append([]string{"TCP_GenericLines"}, nmap.portProbeMap[994]...)
nmap.portProbeMap[995] = append([]string{"TCP_GenericLines"}, nmap.portProbeMap[995]...)
nmap.portProbeMap[465] = append([]string{"TCP_GenericLines"}, nmap.portProbeMap[465]...)
nmap.portProbeMap[3390] = append(nmap.portProbeMap[3390], "TCP_TerminalServer")
nmap.portProbeMap[3390] = append(nmap.portProbeMap[3390], "TCP_TerminalServerCookie")
nmap.portProbeMap[33890] = append(nmap.portProbeMap[33890], "TCP_TerminalServer")
nmap.portProbeMap[33890] = append(nmap.portProbeMap[33890], "TCP_TerminalServerCookie")
nmap.portProbeMap[33900] = append(nmap.portProbeMap[33900], "TCP_TerminalServer")
nmap.portProbeMap[33900] = append(nmap.portProbeMap[33900], "TCP_TerminalServerCookie")
nmap.portProbeMap[7890] = append(nmap.portProbeMap[7890], "TCP_Socks5")
nmap.portProbeMap[7891] = append(nmap.portProbeMap[7891], "TCP_Socks5")
nmap.portProbeMap[4000] = append(nmap.portProbeMap[4000], "TCP_Socks5")
nmap.portProbeMap[2022] = append(nmap.portProbeMap[2022], "TCP_Socks5")
nmap.portProbeMap[6000] = append(nmap.portProbeMap[6000], "TCP_Socks5")
nmap.portProbeMap[7000] = append(nmap.portProbeMap[7000], "TCP_Socks5")
2024-04-03 06:32:26 +02:00
2023-08-18 08:55:46 +02:00
//将TCP_GetRequest的fallback参数设置为NULL探针避免漏资产
nmap.probeNameMap["TCP_GenericLines"].fallback = "TCP_NULL"
nmap.probeNameMap["TCP_GetRequest"].fallback = "TCP_NULL"
nmap.probeNameMap["TCP_TerminalServerCookie"].fallback = "TCP_GetRequest"
nmap.probeNameMap["TCP_TerminalServer"].fallback = "TCP_GetRequest"
}
// 配置类
func SetFilter(filter int) {
initWithFilter(filter)
}
func SetLogger(v Logger) {
logger = v
}
// 功能类
func New() *Nmap {
n := *nmap
return &n
}
func GuessProtocol(port int) string {
protocol := nmapServices[port]
if protocol == "unknown" {
protocol = "http"
}
return protocol
}
var regexpFirstNum = regexp.MustCompile(`^\d`)
func FixProtocol(oldProtocol string) string {
//进行最后输出修饰
if oldProtocol == "ssl/http" {
return "https"
}
if oldProtocol == "http-proxy" {
return "http"
}
if oldProtocol == "ms-wbt-server" {
return "rdp"
}
if oldProtocol == "microsoft-ds" {
return "smb"
}
if oldProtocol == "netbios-ssn" {
return "netbios"
}
if oldProtocol == "oracle-tns" {
return "oracle"
}
if oldProtocol == "msrpc" {
return "rpc"
}
if oldProtocol == "ms-sql-s" {
return "mssql"
}
if oldProtocol == "domain" {
return "dns"
}
if oldProtocol == "svnserve" {
return "svn"
}
if oldProtocol == "ibm-db2" {
return "db2"
}
if oldProtocol == "socks-proxy" {
return "socks5"
}
if len(oldProtocol) > 4 {
if oldProtocol[:4] == "ssl/" {
return oldProtocol[4:] + "-ssl"
}
}
if regexpFirstNum.MatchString(oldProtocol) {
oldProtocol = "S" + oldProtocol
}
oldProtocol = strings.ReplaceAll(oldProtocol, "_", "-")
return oldProtocol
}