diff --git a/cmd/dismap/dismap.go b/cmd/dismap/dismap.go index 4c83b99..cf7b0d2 100644 --- a/cmd/dismap/dismap.go +++ b/cmd/dismap/dismap.go @@ -16,5 +16,5 @@ import ( ) func main() { - internal.DisMap() + internal.Execute() } diff --git a/configs/rule.go b/configs/rule.go index b7deed9..633e5d8 100644 --- a/configs/rule.go +++ b/configs/rule.go @@ -22,7 +22,7 @@ type RuleLab struct { Http ReqHttp } -var RuleData = []RuleLab{ +var RuleData = []*RuleLab{ {1, "EnterCRM", "body", "", InStr{"(Ent.base.js)", "", ""}, ReqHttp{"", "", nil, ""}}, {1, "MeterSphere", "body", "", InStr{"(MeterSphere)", "", ""}, ReqHttp{"", "", nil, ""}}, {3, "Apache Druid", "body", "", InStr{"(Apache Druid|content=\"Apache Druid console\")", "", ""}, ReqHttp{"", "", nil, ""}}, diff --git a/go.mod b/go.mod index 9750b94..ed1c4ca 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,8 @@ go 1.16 require ( github.com/gookit/color v1.4.2 + github.com/ivanpirog/coloredcobra v1.0.1 + github.com/spf13/cobra v1.7.0 github.com/spf13/pflag v1.0.5 github.com/txthinking/socks5 v0.0.0-20220212043548-414499347d4a golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd diff --git a/go.sum b/go.sum index 5fba999..0e5a7c9 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,29 @@ +github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/gookit/color v1.4.2 h1:tXy44JFSFkKnELV6WaMo/lLfu/meqITX3iAV52do7lk= github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/ivanpirog/coloredcobra v1.0.1 h1:aURSdEmlR90/tSiWS0dMjdwOvCVUeYLfltLfbgNxrN4= +github.com/ivanpirog/coloredcobra v1.0.1/go.mod h1:iho4nEKcnwZFiniGSdcgdvRgZNjxm+h20acv8vqmN6Q= +github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -21,8 +39,11 @@ github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHg github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -30,5 +51,7 @@ golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/checkRule.go b/internal/checkRule.go new file mode 100644 index 0000000..a161a0b --- /dev/null +++ b/internal/checkRule.go @@ -0,0 +1,49 @@ +package internal + +import ( + "fmt" + "strings" + + "github.com/spf13/cobra" + "github.com/zhzyker/dismap/configs" + "github.com/zhzyker/dismap/pkg/logger" +) + +var checkCmd = &cobra.Command{ + Use: "check", + Short: "check rules", + Run: func(cmd *cobra.Command, args []string) { + for _, rule := range configs.RuleData { + modes := strings.Split(rule.Mode, "|") + types := strings.Split(rule.Type, "|") + // Check the number of matches + if rule.Mode == "" { + if len(strings.Split(rule.Type, "|")) != 1 { + logger.Error(fmt.Sprintf("Abnormal match pattern and quantity name: %-30v type: %-20v mode: %v", rule.Name, rule.Type, rule.Mode)) + } + } else { + if len(modes)+1 != len(types) { + logger.Error(fmt.Sprintf("Abnormal match pattern and quantity name: %-30v type: %-20v mode: %v", rule.Name, rule.Type, rule.Mode)) + } + + } + // check keyword + for _, item := range types { + if !(item == "body" || item == "header" || item == "ico") { + logger.Error(fmt.Sprintf("Abnormal keyword, name: %-30v type: %-20v mode: %v", rule.Name, rule.Type, rule.Mode)) + break + } + } + for _, item2 := range modes { + if !(item2 == "" || item2 == "and" || item2 == "or") { + logger.Error(fmt.Sprintf("Abnormal mode, name: %-30v type: %-20v mode: %v", rule.Name, rule.Type, rule.Mode)) + break + } + } + } + }, +} + +func init() { + RootCmd.AddCommand(checkCmd) +} diff --git a/internal/dismap.go b/internal/dismap.go index 66b79b1..74c17c9 100644 --- a/internal/dismap.go +++ b/internal/dismap.go @@ -1,49 +1,102 @@ package internal import ( + "net/http" + "os" + "sync" + + "github.com/ivanpirog/coloredcobra" + "github.com/spf13/cobra" "github.com/zhzyker/dismap/configs" "github.com/zhzyker/dismap/internal/flag" "github.com/zhzyker/dismap/internal/operate" "github.com/zhzyker/dismap/internal/output" - "sync" "github.com/zhzyker/dismap/pkg/logger" ) +func which(wg *sync.WaitGroup, lock *sync.Mutex) { + op := output.Open() -func which(Args map[string]interface{}, wg *sync.WaitGroup, lock *sync.Mutex) { - op := output.Open(Args) - - address := Args["FlagNetwork"].(string) + address := flag.NetWork if address != "" { - operate.FlagNetwork(op, wg, lock, address, Args) + operate.FlagNetwork(op, wg, lock, address) output.Close(op) return } - uri := Args["FlagUrl"].(string) + uri := flag.InUrl if uri != "" { - operate.FlagUrl(op, uri, Args) + operate.FlagUrl(op, uri) output.Close(op) return } - file := Args["FlagFile"].(string) + file := flag.File if file != "" { - operate.FlagFile(op, wg, lock, file, Args) + operate.FlagFile(op, wg, lock, file) output.Close(op) return } +} +func init() { + RootCmd.Flags().StringVarP(&flag.InUrl, "uri", "u", "", "Specify a target URI [e.g. -u https://example.com]") + RootCmd.Flags().StringVarP(&flag.NetWork, "ip", "i", "", "Network segment [e.g. -i 192.168.1.0/24 or -i 192.168.1.1-10]") + RootCmd.Flags().StringVarP(&flag.Mode, "mode", "m", "", "Specify the protocol [e.g. -m mysql/-m http]") + RootCmd.Flags().StringVar(&flag.Type, "type", "", "Specify the type [e.g. --type tcp/--type udp]") + RootCmd.Flags().IntVar(&flag.Timeout, "timeout", 5, "Response timeout time, the default is 5 seconds") + RootCmd.Flags().IntVarP(&flag.Thread, "thread", "t", 500, "Number of concurrent threads") + RootCmd.Flags().StringVarP(&flag.Port, "port", "p", "", "Custom scan ports [e.g. -p 80,443 or -p 1-65535]") + RootCmd.Flags().StringVarP(&flag.Output, "output", "o", "output.txt", "Save the scan results to the specified file") + RootCmd.Flags().StringVarP(&flag.File, "file", "f", "", "Parse the target from the specified file for batch recognition") + RootCmd.Flags().BoolVar(&flag.NoIcmp, "np", false, "Not use ICMP/PING to detect surviving hosts") + RootCmd.Flags().StringVarP(&flag.OutJson, "json", "j", "", "Scan result in json format [e.g. -j r.json]") + RootCmd.Flags().BoolVar(&flag.NoColor, "nc", false, "Do not print character colors") + RootCmd.Flags().IntVarP(&flag.Level, "level", "l", 3, "Specify log level (0:Fatal 1:Error 2:Info 3:Warning 4:Debug 5:Verbose)") + RootCmd.Flags().StringVarP(&flag.Proxy, "proxy", "", "", "Use proxy scan, support http/socks5 protocol [e.g. --proxy socks5://127.0.0.1:1080]") + RootCmd.Flags().BoolVarP(&flag.Pprof, "pprof", "d", false, "use pprof debug, on http://localhost:6060/debug/pprof/") } -func DisMap() { - configs.Banner() - Args := flag.Flags() - wg := &sync.WaitGroup{} - lock := &sync.Mutex{} +func Execute() { + coloredcobra.Init(&coloredcobra.Config{ + RootCmd: RootCmd, + Headings: coloredcobra.HiGreen + coloredcobra.Underline, + Commands: coloredcobra.Cyan + coloredcobra.Bold, + Example: coloredcobra.Italic, + ExecName: coloredcobra.Bold, + Flags: coloredcobra.Cyan + coloredcobra.Bold, + NoExtraNewlines: true, + }) + err := RootCmd.Execute() + if err != nil { + os.Exit(1) + } +} + +var RootCmd = &cobra.Command{ + Use: "dismap", + Run: func(cmd *cobra.Command, args []string) { + if flag.NetWork == "" && flag.File == "" && flag.InUrl == "" { + configs.Banner() + cmd.Help() + return + } + _wg := &sync.WaitGroup{} + if flag.Pprof { + _wg.Add(1) + go func() { + logger.Info(http.ListenAndServe("localhost:6060", nil).Error()) + }() + } + + configs.Banner() + wg := &sync.WaitGroup{} + lock := &sync.Mutex{} + which(wg, lock) + + logger.Info("Identification completed and ended") - information() - which(Args, wg, lock) - logger.Info("Identification completed and ended") + _wg.Wait() + }, } diff --git a/internal/flag/flag.go b/internal/flag/flag.go index 58fc7f0..883b2e7 100644 --- a/internal/flag/flag.go +++ b/internal/flag/flag.go @@ -1,66 +1,61 @@ package flag -import ( - flag "github.com/spf13/pflag" - "os" -) - var ( - NetWork string - InUrl string - Timeout int - Thread int - Port string - Output string - File string - NoIcmp bool - NoColor bool - Mode string - Type string - Help bool - Level int - Proxy string - OutJson string + NetWork string + InUrl string + Timeout int + Thread int + Port string + Output string + File string + NoIcmp bool + NoColor bool + Mode string + Type string + Help bool + Level int + Proxy string + OutJson string + Pprof bool ) +// func init() { +// flag.StringVarP(&InUrl, "uri", "u", "", "Specify a target URI [e.g. -u https://example.com]") +// flag.StringVarP(&NetWork,"ip", "i", "", "Network segment [e.g. -i 192.168.1.0/24 or -i 192.168.1.1-10]") +// flag.StringVarP(&Mode,"mode", "m", "", "Specify the protocol [e.g. -m mysql/-m http]") +// flag.StringVar(&Type,"type", "", "Specify the type [e.g. --type tcp/--type udp]") +// flag.IntVar(&Timeout, "timeout", 5, "Response timeout time, the default is 5 seconds") +// flag.IntVarP(&Thread, "thread", "t", 500, "Number of concurrent threads") +// flag.StringVarP(&Port, "port", "p", "", "Custom scan ports [e.g. -p 80,443 or -p 1-65535]") +// flag.StringVarP(&Output, "output", "o", "output.txt", "Save the scan results to the specified file") +// flag.StringVarP(&File, "file", "f", "", "Parse the target from the specified file for batch recognition") +// flag.BoolVar(&NoIcmp, "np",false, "Not use ICMP/PING to detect surviving hosts") +// flag.StringVarP(&OutJson, "json", "j", "", "Scan result in json format [e.g. -j r.json]") +// flag.BoolVar(&NoColor, "nc", false, "Do not print character colors") +// flag.IntVarP(&Level, "level", "l", 3, "Specify log level (0:Fatal 1:Error 2:Info 3:Warning 4:Debug 5:Verbose)") +// flag.StringVarP(&Proxy, "proxy", "", "", "Use proxy scan, support http/socks5 protocol [e.g. --proxy socks5://127.0.0.1:1080]") +// flag.BoolVarP(&Help, "help", "h",false, "Show help") +// } -func init() { - flag.StringVarP(&InUrl, "uri", "u", "", "Specify a target URI [e.g. -u https://example.com]") - flag.StringVarP(&NetWork,"ip", "i", "", "Network segment [e.g. -i 192.168.1.0/24 or -i 192.168.1.1-10]") - flag.StringVarP(&Mode,"mode", "m", "", "Specify the protocol [e.g. -m mysql/-m http]") - flag.StringVar(&Type,"type", "", "Specify the type [e.g. --type tcp/--type udp]") - flag.IntVar(&Timeout, "timeout", 5, "Response timeout time, the default is 5 seconds") - flag.IntVarP(&Thread, "thread", "t", 500, "Number of concurrent threads") - flag.StringVarP(&Port, "port", "p", "", "Custom scan ports [e.g. -p 80,443 or -p 1-65535]") - flag.StringVarP(&Output, "output", "o", "output.txt", "Save the scan results to the specified file") - flag.StringVarP(&File, "file", "f", "", "Parse the target from the specified file for batch recognition") - flag.BoolVar(&NoIcmp, "np",false, "Not use ICMP/PING to detect surviving hosts") - flag.StringVarP(&OutJson, "json", "j", "", "Scan result in json format [e.g. -j r.json]") - flag.BoolVar(&NoColor, "nc", false, "Do not print character colors") - flag.IntVarP(&Level, "level", "l", 3, "Specify log level (0:Fatal 1:Error 2:Info 3:Warning 4:Debug 5:Verbose)") - flag.StringVarP(&Proxy, "proxy", "", "", "Use proxy scan, support http/socks5 protocol [e.g. --proxy socks5://127.0.0.1:1080]") - flag.BoolVarP(&Help, "help", "h",false, "Show help") -} - -func Flags() map[string]interface{} { - flag.Parse() - if Help { - flag.PrintDefaults() - os.Exit(0) - } - flags := map[string]interface{}{ - "FlagUrl": InUrl, - "FlagNetwork": NetWork, - "FlagMode": Mode, - "FlagType": Type, - "FlagTimeout": Timeout, - "FlagThread": Thread, - "FlagPort": Port, - "FlagOutput": Output, - "FlagFile": File, - "FlagNoIcmp": NoIcmp, - "FlagProxy": Proxy, - "FlagOutJson": OutJson, - } - return flags -} +// func Flags() map[string]interface{} { +// flag.Parse() +// if Help { +// flag.PrintDefaults() +// os.Exit(0) +// } +// flags := map[string]interface{}{ +// "FlagUrl": InUrl, +// "FlagNetwork": NetWork, +// "FlagMode": Mode, +// "FlagType": Type, +// "FlagTimeout": Timeout, +// "FlagThread": Thread, +// "FlagPort": Port, +// "FlagOutput": Output, +// "FlagFile": File, +// "FlagNoIcmp": NoIcmp, +// "FlagProxy": Proxy, +// "FlagOutJson": OutJson, +// } +// return flags +// } diff --git a/internal/model/result.go b/internal/model/result.go new file mode 100644 index 0000000..e268918 --- /dev/null +++ b/internal/model/result.go @@ -0,0 +1,45 @@ +package model + +import "time" + +type Result struct { + Date time.Time + Status string + Banner string + BannerB []byte + Protocol string // HTTP / MYSQL ... + Type string // TCP / UDP + Host string + Port int + Uri string + Note string + Path string + IdentifyBool bool + IdentifyStr string + Identify []HintFinger + HttpResult *HttpResult + Hint bool +} + +type HttpResult struct { + Url string // URL + Body string // Body + Server string // WebServer + Header string // Header + HeaderM map[string][]string // Header map + StatusCode string // 状态码 + Title string // 标题 + FaviconMd5 string // 图标Md5 + FaviconMM3Hash string // mm3Hash (指纹专用) + Type string // HTTP/HTTPs + Result string // dismap 原版的信息存储位置 +} + +type HintFinger struct { + Name string + Version string + Description string + Rank int + Type string + Source string +} diff --git a/internal/operate/flag_file.go b/internal/operate/flag_file.go index 807a819..4d04d99 100644 --- a/internal/operate/flag_file.go +++ b/internal/operate/flag_file.go @@ -2,17 +2,19 @@ package operate import ( "bufio" - "github.com/zhzyker/dismap/internal/parse" - "github.com/zhzyker/dismap/pkg/logger" "io" "net/url" "os" "strings" "sync" + + "github.com/zhzyker/dismap/internal/flag" + "github.com/zhzyker/dismap/internal/parse" + "github.com/zhzyker/dismap/pkg/logger" ) -func FlagFile(op *os.File, wg *sync.WaitGroup, lock *sync.Mutex, file string, Args map[string]interface{}) { - thread := Args["FlagThread"].(int) +func FlagFile(op *os.File, wg *sync.WaitGroup, lock *sync.Mutex, file string) { + thread := flag.Thread f, err := os.Open(file) if err != nil { logger.Error("There is no " + logger.LightRed(f) + " file or the directory does not exist") @@ -33,7 +35,7 @@ func FlagFile(op *os.File, wg *sync.WaitGroup, lock *sync.Mutex, file string, Ar } if parse.NetJudgeParse(line) { - FlagNetwork(op, wg, lock, line, Args) + FlagNetwork(op, wg, lock, line) continue } _, err = url.Parse(line) @@ -43,12 +45,12 @@ func FlagFile(op *os.File, wg *sync.WaitGroup, lock *sync.Mutex, file string, Ar } else { wg.Add(1) intSyncThread++ - go func(line string, Args map[string]interface{}) { + go func(line string) { lock.Lock() - FlagUrl(op, line, Args) + FlagUrl(op, line) lock.Unlock() wg.Done() - }(line, Args) + }(line) if intSyncThread >= thread { intSyncThread = 0 wg.Wait() @@ -57,4 +59,4 @@ func FlagFile(op *os.File, wg *sync.WaitGroup, lock *sync.Mutex, file string, Ar } } wg.Wait() -} \ No newline at end of file +} diff --git a/internal/operate/flag_network.go b/internal/operate/flag_network.go index c8ebcdc..8b29faa 100644 --- a/internal/operate/flag_network.go +++ b/internal/operate/flag_network.go @@ -1,21 +1,23 @@ package operate import ( - "github.com/zhzyker/dismap/internal/output" - "github.com/zhzyker/dismap/internal/parse" - "github.com/zhzyker/dismap/internal/protocol" - "github.com/zhzyker/dismap/pkg/logger" "os" "strconv" "strings" "sync" + + "github.com/zhzyker/dismap/internal/flag" + "github.com/zhzyker/dismap/internal/output" + "github.com/zhzyker/dismap/internal/parse" + "github.com/zhzyker/dismap/internal/protocol" + "github.com/zhzyker/dismap/pkg/logger" ) -func FlagNetwork(op *os.File, wg *sync.WaitGroup, lock *sync.Mutex, address string, Args map[string]interface{}) { - timeout := Args["FlagTimeout"].(int) - thread := Args["FlagThread"].(int) - np := Args["FlagNoIcmp"].(bool) - flagPort := Args["FlagPort"].(string) +func FlagNetwork(op *os.File, wg *sync.WaitGroup, lock *sync.Mutex, address string) { + timeout := flag.Timeout + thread := flag.Thread + np := flag.NoIcmp + flagPort := flag.Port ports := parse.PortParse(flagPort) logger.Info("Start to detect host from " + address) @@ -34,44 +36,44 @@ func FlagNetwork(op *os.File, wg *sync.WaitGroup, lock *sync.Mutex, address stri for _, port := range ports { wg.Add(3) intSyncThread++ - go func(host string, port int, Args map[string]interface{}) { - resTls := protocol.DiscoverTls(host, port, Args) - if resTls["status"].(string) == "open" { + go func(host string, port int) { + resTls := protocol.DiscoverTls(host, port) + if resTls.Status == "open" { intAll++ parse.VerboseParse(resTls) output.Write(resTls, op) - if strings.Contains(resTls["uri"].(string), "://") { + if strings.Contains(resTls.Uri, "://") { intIde++ } } wg.Done() - }(host, port, Args) + }(host, port) - go func(host string, port int, Args map[string]interface{}) { - resTcp := protocol.DiscoverTcp(host, port, Args) - if resTcp["status"].(string) == "open" { + go func(host string, port int) { + resTcp := protocol.DiscoverTcp(host, port) + if resTcp.Status == "open" { intAll++ parse.VerboseParse(resTcp) output.Write(resTcp, op) - if strings.Contains(resTcp["uri"].(string), "://") { + if strings.Contains(resTcp.Uri, "://") { intIde++ } } wg.Done() - }(host, port, Args) + }(host, port) - go func(host string, port int, Args map[string]interface{}) { - resUdp := protocol.DiscoverUdp(host, port, Args) - if resUdp["status"].(string) == "open" { + go func(host string, port int) { + resUdp := protocol.DiscoverUdp(host, port) + if resUdp.Status == "open" { intAll++ parse.VerboseParse(resUdp) output.Write(resUdp, op) - if strings.Contains(resUdp["uri"].(string), "://") { + if strings.Contains(resUdp.Uri, "://") { intIde++ } } wg.Done() - }(host, port, Args) + }(host, port) if intSyncThread >= thread { intSyncThread = 0 wg.Wait() diff --git a/internal/operate/flag_ping.go b/internal/operate/flag_ping.go index 4f1ea22..f6bca6f 100644 --- a/internal/operate/flag_ping.go +++ b/internal/operate/flag_ping.go @@ -1,10 +1,11 @@ package operate import ( - "github.com/zhzyker/dismap/internal/parse" - "github.com/zhzyker/dismap/pkg/logger" "strconv" "sync" + + "github.com/zhzyker/dismap/internal/parse" + "github.com/zhzyker/dismap/pkg/logger" ) func FlagPing(wg *sync.WaitGroup, lock *sync.Mutex, hosts []string, TimeOut int, Thread int, np bool) []string { diff --git a/internal/operate/flag_url.go b/internal/operate/flag_url.go index 39ff801..0e00ee7 100644 --- a/internal/operate/flag_url.go +++ b/internal/operate/flag_url.go @@ -1,25 +1,27 @@ package operate import ( + "os" + + "github.com/zhzyker/dismap/internal/model" "github.com/zhzyker/dismap/internal/output" "github.com/zhzyker/dismap/internal/parse" "github.com/zhzyker/dismap/internal/protocol" "github.com/zhzyker/dismap/pkg/logger" - "os" ) -func FlagUrl(op *os.File, uri string, Args map[string]interface{}) { +func FlagUrl(op *os.File, uri string) { uri, scheme, host, port, err := parse.UriParse(uri) if logger.DebugError(err) { return } - var res map[string]interface{} + var res *model.Result //Args["FlagMode"] = scheme switch scheme { case "http": - res = protocol.DiscoverTcp(host, port, Args) + res = protocol.DiscoverTcp(host, port) case "https": - res = protocol.DiscoverTls(host, port, Args) + res = protocol.DiscoverTls(host, port) } //Args["FlagMode"] = "" parse.VerboseParse(res) diff --git a/internal/output/output.go b/internal/output/output.go index ed9940b..729124f 100644 --- a/internal/output/output.go +++ b/internal/output/output.go @@ -4,37 +4,41 @@ import ( "encoding/hex" "encoding/json" "fmt" - "github.com/zhzyker/dismap/internal/flag" - "github.com/zhzyker/dismap/pkg/logger" "os" "time" + + "github.com/zhzyker/dismap/internal/flag" + "github.com/zhzyker/dismap/internal/model" + "github.com/zhzyker/dismap/pkg/logger" ) -func Open(Args map[string]interface{}) *os.File { - if len(Args["FlagOutJson"].(string)) != 0 { - return openFile(Args["FlagOutJson"].(string)) +func Open() *os.File { + print("openfile: ", flag.File) + if len(flag.OutJson) != 0 { + print(len(flag.OutJson), flag.OutJson) + return openFile(flag.OutJson) } else { - return openFile(Args["FlagOutput"].(string)) + return openFile(flag.Output) } } -func Write(result map[string]interface{}, output *os.File) { - if result["status"].(string) == "close" { +func Write(result *model.Result, output *os.File) { + if result.Status == "close" { return } if len(flag.OutJson) != 0 { - result["banner.byte"] = hex.EncodeToString(result["banner.byte"].([]byte)) - result["date"] = time.Now().Unix() + result.Banner = hex.EncodeToString(result.BannerB) + result.Date = time.Now() byteR, _ := json.Marshal(result) writeContent(output, string(byteR)) } else { content := fmt.Sprintf("%s, %s, %s, %s, %s, %s", logger.GetTime(), - result["type"], - result["protocol"], - logger.Clean(result["identify.string"].(string)), - result["uri"], - result["banner.string"]) + result.Type, + result.Protocol, + logger.Clean(result.IdentifyStr), + result.Uri, + result.Banner) writeContent(output, content) } } diff --git a/internal/parse/parse_proxy.go b/internal/parse/parse_proxy.go index bcad2ad..1ca86c2 100644 --- a/internal/parse/parse_proxy.go +++ b/internal/parse/parse_proxy.go @@ -2,9 +2,10 @@ package parse import ( "fmt" + "net/url" + "github.com/zhzyker/dismap/internal/flag" "github.com/zhzyker/dismap/pkg/logger" - "net/url" ) func ProxyParse() (string, string, string, error) { diff --git a/internal/parse/parse_scheme.go b/internal/parse/parse_scheme.go index 22bfb99..70c772a 100644 --- a/internal/parse/parse_scheme.go +++ b/internal/parse/parse_scheme.go @@ -3,21 +3,23 @@ package parse import ( "fmt" "strconv" + + "github.com/zhzyker/dismap/internal/model" ) -func SchemeParse(result map[string]interface{}) string { - path := result["path"].(string) - scheme := result["protocol"].(string) - port := result["port"].(int) - host := result["host"].(string) +func SchemeParse(result *model.Result) string { + path := result.Path + scheme := result.Protocol + port := result.Port + host := result.Host if scheme != "" && path != "" { - result["uri"] = fmt.Sprintf("%s://%s:%s%s",scheme, host, strconv.Itoa(port), path) - return result["uri"].(string) + result.Uri = fmt.Sprintf("%s://%s:%s%s", scheme, host, strconv.Itoa(port), path) + return result.Uri } else if scheme != "" { - result["uri"] = fmt.Sprintf("%s://%s:%s",scheme, host, strconv.Itoa(port)) - return result["uri"].(string) + result.Uri = fmt.Sprintf("%s://%s:%s", scheme, host, strconv.Itoa(port)) + return result.Uri } else { - result["uri"] = fmt.Sprintf("%s:%s", host, strconv.Itoa(port)) - return result["uri"].(string) + result.Uri = fmt.Sprintf("%s:%s", host, strconv.Itoa(port)) + return result.Uri } } diff --git a/internal/parse/parse_verbose.go b/internal/parse/parse_verbose.go index b2bbd81..c8ff69d 100644 --- a/internal/parse/parse_verbose.go +++ b/internal/parse/parse_verbose.go @@ -3,14 +3,16 @@ package parse import ( "encoding/hex" "fmt" + + "github.com/zhzyker/dismap/internal/model" "github.com/zhzyker/dismap/pkg/logger" ) -func VerboseParse(res map[string]interface{}) { - logger.Verbose(fmt.Sprintf("Hex dump\n%s", hex.Dump(res["banner.byte"].([]byte)))) +func VerboseParse(res *model.Result) { + logger.Verbose(fmt.Sprintf("Hex dump\n%s", hex.Dump(res.BannerB))) r := "\n" - for k, v := range res { - r += fmt.Sprintf("%18s: %s",fmt.Sprintf(k), fmt.Sprintln(v)) - } + // for k, v := range res { + // r += fmt.Sprintf("%18s: %s", fmt.Sprintf(k), fmt.Sprintln(v)) + // } logger.Verbose(fmt.Sprintf("Dismap identify result\n%s", r)) } diff --git a/internal/protocol/discover.go b/internal/protocol/discover.go index 7ce518d..4fb092d 100644 --- a/internal/protocol/discover.go +++ b/internal/protocol/discover.go @@ -1,10 +1,13 @@ package protocol import ( + "time" + + "github.com/zhzyker/dismap/internal/flag" + "github.com/zhzyker/dismap/internal/model" "github.com/zhzyker/dismap/internal/parse" "github.com/zhzyker/dismap/internal/protocol/get" "github.com/zhzyker/dismap/pkg/logger" - "time" ) func isContainInt(items []int, item int) bool { @@ -16,73 +19,62 @@ func isContainInt(items []int, item int) bool { return false } -func setResult(host string, port int, Args map[string]interface{}) map[string]interface{} { - var banner []byte - result := map[string]interface{}{ - "date": time.Now().Unix(), - "status": "None", - "banner.byte": banner, - "banner.string": "None", - "protocol": Args["FlagMode"].(string), - "type": Args["FlagType"].(string), - "host": host, - "port": port, - "uri": "None", - "note": "None", - "path": "", - "identify.bool": false, - "identify.string": "None", +func NewResult(host string, port int) *model.Result { + return &model.Result{ + Date: time.Now(), + Host: host, + Port: port, } - return result } -func DiscoverTls(host string, port int, Args map[string]interface{}) map[string]interface{} { - result := setResult(host, port, Args) - b, err := get.TlsProtocol(host, port, Args["FlagTimeout"].(int)) +func DiscoverTls(host string, port int) *model.Result { + result := NewResult(host, port) + + b, err := get.TlsProtocol(host, port, flag.Timeout) if logger.DebugError(err) { return result } - result["type"] = "tls" - result["status"] = "open" - result["banner.byte"] = b - result["banner.string"] = parse.ByteToStringParse1(b) - if JudgeTls(result, Args) { + result.Type = "tls" + result.Status = "open" + result.BannerB = b + result.Banner = parse.ByteToStringParse1(b) + if JudgeTls(result) { return result } return result } -func DiscoverTcp(host string, port int, Args map[string]interface{}) map[string]interface{} { - result := setResult(host, port, Args) - b, err := get.TcpProtocol(host, port, Args["FlagTimeout"].(int)) +func DiscoverTcp(host string, port int) *model.Result { + result := NewResult(host, port) + b, err := get.TcpProtocol(host, port, flag.Timeout) if logger.DebugError(err) { return result } - result["type"] = "tcp" - result["status"] = "open" - result["banner.byte"] = b - result["banner.string"] = parse.ByteToStringParse1(b) - if JudgeTcp(result, Args) { + result.Type = "tcp" + result.Status = "open" + result.BannerB = b + result.Banner = parse.ByteToStringParse1(b) + if JudgeTcp(result) { return result } return result } -func DiscoverUdp(host string, port int, Args map[string]interface{}) map[string]interface{} { - result := setResult(host, port, Args) +func DiscoverUdp(host string, port int) *model.Result { + result := NewResult(host, port) var udpPort = []int{53, 111, 123, 137, 138, 139, 12345} if isContainInt(udpPort, port) { return result } - b, err := get.UdpProtocol(host, port, Args["FlagTimeout"].(int)) + b, err := get.UdpProtocol(host, port, flag.Timeout) if logger.DebugError(err) { return result } - result["type"] = "tcp" - result["status"] = "open" - result["banner.byte"] = b - result["banner.string"] = parse.ByteToStringParse1(b) - if JudgeUdp(result, Args) { + result.Type = "udp" + result.Status = "open" + result.BannerB = b + result.Banner = parse.ByteToStringParse1(b) + if JudgeUdp(result) { return result } return result diff --git a/internal/protocol/identify.go b/internal/protocol/identify.go index 68a2cc3..20925ca 100644 --- a/internal/protocol/identify.go +++ b/internal/protocol/identify.go @@ -3,19 +3,21 @@ package protocol import ( "bytes" "fmt" + + "github.com/zhzyker/dismap/internal/model" "github.com/zhzyker/dismap/internal/parse" "github.com/zhzyker/dismap/internal/protocol/judge" "github.com/zhzyker/dismap/pkg/logger" ) -func JudgeTcp(result map[string]interface{}, Args map[string]interface{}) bool { - protocol := result["protocol"].(string) +func JudgeTcp(result *model.Result) bool { + protocol := result.Protocol runAll := true if protocol != "" { runAll = false } if protocol == "http" || protocol == "https" || runAll { - if judge.TcpHTTP(result, Args) { + if judge.TcpHTTP(result) { printSuccess("TCP/HTTP", result) return true } @@ -81,31 +83,31 @@ func JudgeTcp(result map[string]interface{}, Args map[string]interface{}) bool { } } if protocol == "oracle" || runAll { - if judge.TcpOracle(result, Args) { + if judge.TcpOracle(result) { printSuccess("TCP/Oracle", result) return true } } if protocol == "frp" || runAll { - if judge.TcpFrp(result, Args) { + if judge.TcpFrp(result) { printSuccess("TCP/Frp", result) return true } } if protocol == "socks" || runAll { - if judge.TcpSocks(result, Args) { + if judge.TcpSocks(result) { printSuccess("TCP/Socks", result) return true } } if protocol == "ldap" || runAll { - if judge.TcpLDAP(result, Args) { + if judge.TcpLDAP(result) { printSuccess("TCP/LDAP", result) return true } } if protocol == "rmi" || runAll { - if judge.TcpRMI(result, Args) { + if judge.TcpRMI(result) { printSuccess("TCP/RMI", result) return true } @@ -117,64 +119,64 @@ func JudgeTcp(result map[string]interface{}, Args map[string]interface{}) bool { } } if protocol == "rtsp" || runAll { - if judge.TcpRTSP(result, Args) { + if judge.TcpRTSP(result) { printSuccess("TCP/RTSP", result) return true } } if protocol == "rdp" || runAll { - if judge.TcpRDP(result, Args) { + if judge.TcpRDP(result) { printSuccess("TCP/RDP", result) return true } } if protocol == "dcerpc" || runAll { - if judge.TcpDceRpc(result, Args) { + if judge.TcpDceRpc(result) { printSuccess("TCP/DceRpc", result) return true } } if protocol == "mssql" || runAll { - if judge.TcpMssql(result, Args) { + if judge.TcpMssql(result) { printSuccess("TCP/Mssql", result) return true } } if protocol == "smb" || runAll { - if judge.TcpSMB(result, Args) { + if judge.TcpSMB(result) { printSuccess("TCP/SMB", result) return true } } if protocol == "giop" || runAll { - if judge.TcpGIOP(result, Args) { + if judge.TcpGIOP(result) { printSuccess("TCP/GIOP", result) return true } } - status := result["status"].(string) + status := result.Status if status == "open" && runAll { printFailed("TCP/unknown", result) } return false } -func JudgeTls(result map[string]interface{}, Args map[string]interface{}) bool { - protocol := result["protocol"].(string) +func JudgeTls(result *model.Result) bool { + protocol := result.Protocol runAll := true if protocol != "" { runAll = false } if protocol == "http" || protocol == "https" || runAll { - if judge.TlsHTTPS(result, Args) { + if judge.TlsHTTPS(result) { printSuccess("TLS/HTTPS", result) return true } } if protocol == "rdp" || runAll { - if judge.TlsRDP(result, Args) { + if judge.TlsRDP(result) { printSuccess("TLS/RDP", result) return true } @@ -186,30 +188,30 @@ func JudgeTls(result map[string]interface{}, Args map[string]interface{}) bool { } } - status := result["status"].(string) + status := result.Status if status == "open" && runAll { printFailed("TLS/unknown", result) } return false } -func JudgeUdp(result map[string]interface{}, Args map[string]interface{}) bool { - protocol := result["protocol"].(string) +func JudgeUdp(result *model.Result) bool { + protocol := result.Protocol runAll := true if protocol != "" { runAll = false } if protocol == "nbns" || runAll { - if judge.UdpNbns(result, Args) { + if judge.UdpNbns(result) { printSuccess("UDP/NBNS", result) return true } } var buffer [256]byte - status := result["status"].(string) - if bytes.Equal(result["banner.byte"].([]byte), buffer[:]) { - result["status"] = "close" + status := result.Status + if bytes.Equal(result.BannerB, buffer[:]) { + result.Status = "close" return false } else if status == "open" && runAll { printFailed("UDP/unknown", result) @@ -218,49 +220,39 @@ func JudgeUdp(result map[string]interface{}, Args map[string]interface{}) bool { return false } -func printSuccess(protocol string, result map[string]interface{}) { - success, b := result["identify.bool"].(bool) - if b == false { - logger.Success(fmt.Sprintf("[%s] %s [%s]", - logger.Cyan(protocol), - parse.SchemeParse(result), - logger.Blue(result["banner.string"].(string))), - ) - result["identify.string"] = logger.Clean(result["identify.string"].(string)) - result["note"] = logger.Clean(result["note"].(string)) - return - } +func printSuccess(protocol string, result *model.Result) { + success := result.IdentifyBool if success { logger.Success(fmt.Sprintf("[%s] %s %s [%s]", logger.Cyan(protocol), - result["identify.string"].(string), + result.IdentifyStr, parse.SchemeParse(result), - logger.Blue(result["banner.string"].(string))), + logger.Blue(result.Banner)), ) - result["identify.string"] = logger.Clean(result["identify.string"].(string)) - result["note"] = logger.Clean(result["note"].(string)) + result.IdentifyStr = logger.Clean(result.IdentifyStr) + result.Note = logger.Clean(result.Note) return } else { logger.Success(fmt.Sprintf("[%s] %s [%s]", logger.Cyan(protocol), parse.SchemeParse(result), - logger.Blue(result["banner.string"].(string))), + logger.Blue(result.Banner)), ) - result["identify.string"] = logger.Clean(result["identify.string"].(string)) - result["note"] = logger.Clean(result["note"].(string)) + result.IdentifyStr = logger.Clean(result.IdentifyStr) + result.Note = logger.Clean(result.Note) return } } -func printFailed(p string, result map[string]interface{}) { - if result["status"].(string) == "open" { +func printFailed(p string, result *model.Result) { + if result.Status == "open" { logger.Failed(fmt.Sprintf("[%s] %s [%s]", logger.Cyan(p), parse.SchemeParse(result), - logger.Blue(result["banner.string"].(string))), + logger.Blue(result.Banner)), ) - result["identify.string"] = logger.Clean(result["identify.string"].(string)) - result["note"] = logger.Clean(result["note"].(string)) + result.IdentifyStr = logger.Clean(result.IdentifyStr) + result.Note = logger.Clean(result.Note) } } diff --git a/internal/protocol/judge/tcp_activemq.go b/internal/protocol/judge/tcp_activemq.go index 3fe0501..750d0a4 100644 --- a/internal/protocol/judge/tcp_activemq.go +++ b/internal/protocol/judge/tcp_activemq.go @@ -3,27 +3,26 @@ package judge import ( "encoding/hex" "fmt" - "github.com/zhzyker/dismap/pkg/logger" "regexp" "strconv" + + "github.com/zhzyker/dismap/internal/model" ) -func TcpActiveMQ(result map[string]interface{}) bool { - var buff []byte - buff, _ = result["banner.byte"].([]byte) - ok, err := regexp.Match(`ActiveMQ`, buff) - if logger.DebugError(err) { +func TcpActiveMQ(result *model.Result) bool { + ok, err := regexp.Match(`ActiveMQ`, result.BannerB) + if err != nil { return false } if ok { - ver, err := strconv.ParseUint(hex.EncodeToString(buff[13:17]), 16, 32) + ver, err := strconv.ParseUint(hex.EncodeToString(result.BannerB[13:17]), 16, 32) if err == nil { - version := logger.LightYellow(fmt.Sprintf("Version:%s", strconv.FormatUint(ver, 10))) - result["identify.bool"] = true - result["identify.string"] = fmt.Sprintf("[%s]", version) + version := fmt.Sprintf("Version:%s", strconv.FormatUint(ver, 10)) + result.IdentifyBool = true + result.Identify = append(result.Identify, model.HintFinger{Name: "ActiveMQ", Version: version}) } - result["protocol"] = "activemq" + result.Protocol = "activemq" return true } return false -} \ No newline at end of file +} diff --git a/internal/protocol/judge/tcp_dcerpc.go b/internal/protocol/judge/tcp_dcerpc.go index d9c0a94..670245d 100644 --- a/internal/protocol/judge/tcp_dcerpc.go +++ b/internal/protocol/judge/tcp_dcerpc.go @@ -3,25 +3,23 @@ package judge import ( "bytes" "encoding/hex" - "github.com/zhzyker/dismap/internal/proxy" - "github.com/zhzyker/dismap/pkg/logger" "strings" -) -func TcpDceRpc(result map[string]interface{}, Args map[string]interface{}) bool { - timeout := Args["FlagTimeout"].(int) - host := result["host"].(string) - port := result["port"].(int) + "github.com/zhzyker/dismap/internal/flag" + "github.com/zhzyker/dismap/internal/model" + "github.com/zhzyker/dismap/internal/proxy" +) - conn, err := proxy.ConnProxyTcp(host, port, timeout) - if logger.DebugError(err) { +func TcpDceRpc(result *model.Result) bool { + conn, err := proxy.ConnProxyTcp(result.Host, result.Port, flag.Timeout) + if err != nil { return false } msg1 := "\x05\x00\x0b\x03\x10\x00\x00\x00\x48\x00\x00\x00\x01\x00\x00\x00\xf8\x0f\xf8\x0f\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x00\xc4\xfe\xfc\x99\x60\x52\x1b\x10\xbb\xcb\x00\xaa\x00\x21\x34\x7a\x00\x00\x00\x00\x04\x5d\x88\x8a\xeb\x1c\xc9\x11\x9f\xe8\x08\x00\x2b\x10\x48\x60\x02\x00\x00\x00" msg2 := "\x05\x00\x00\x03\x10\x00\x00\x00\x18\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00" _, err = conn.Write([]byte(msg1)) - if logger.DebugError(err) { + if err != nil { return false } reply1 := make([]byte, 256) @@ -32,23 +30,23 @@ func TcpDceRpc(result map[string]interface{}, Args map[string]interface{}) bool } _, err = conn.Write([]byte(msg2)) - if logger.DebugError(err) { + if err != nil { return false } reply2 := make([]byte, 512) _, _ = conn.Read(reply2) if conn != nil { - _ = conn.Close() - } + _ = conn.Close() + } - result["protocol"] = "dcerpc" + result.Protocol = "dcerpc" c := 0 zero := make([]byte, 1) var buffer bytes.Buffer for i := 0; i < len(reply2[42:]); { - b := reply2[42:][i:i+2] + b := reply2[42:][i : i+2] i += 2 if 42+i == len(reply2[42:]) { break @@ -62,18 +60,18 @@ func TcpDceRpc(result map[string]interface{}, Args map[string]interface{}) bool break } buffer.Write([]byte("\x7C\x7C")) - result["banner.string"] = strings.Join([]string{string(buffer.Bytes())}, ",") + result.Banner = strings.Join([]string{buffer.String()}, ",") continue } if bytes.Equal(b[0:1], zero[0:1]) { continue } buffer.Write(b[0:1]) - result["banner.string"] = strings.Join([]string{string(buffer.Bytes())}, ",") + result.Banner = strings.Join([]string{buffer.String()}, ",") if c == 6 { break } } - result["banner.byte"] = reply2 + result.BannerB = reply2 return true } diff --git a/internal/protocol/judge/tcp_frp.go b/internal/protocol/judge/tcp_frp.go index 43a800b..c117357 100644 --- a/internal/protocol/judge/tcp_frp.go +++ b/internal/protocol/judge/tcp_frp.go @@ -4,15 +4,18 @@ import ( "bytes" "encoding/hex" "fmt" + "strings" + + "github.com/zhzyker/dismap/internal/flag" + "github.com/zhzyker/dismap/internal/model" "github.com/zhzyker/dismap/internal/proxy" "github.com/zhzyker/dismap/pkg/logger" - "strings" ) -func TcpFrp(result map[string]interface{}, Args map[string]interface{}) bool { - timeout := Args["FlagTimeout"].(int) - host := result["host"].(string) - port := result["port"].(int) +func TcpFrp(result *model.Result) bool { + timeout := flag.Timeout + host := result.Host + port := result.Port conn, err := proxy.ConnProxyTcp(host, port, timeout) if logger.DebugError(err) { @@ -37,9 +40,9 @@ func TcpFrp(result map[string]interface{}, Args map[string]interface{}) bool { } else if hex.EncodeToString(reply[0:12]) != "000100020000000100000000" { return false } - result["protocol"] = "frp" - result["banner.string"] = frpByteToStringParse(reply[0:12]) - result["banner.byte"] = reply + result.Protocol = "frp" + result.Banner = frpByteToStringParse(reply[0:12]) + result.BannerB = reply return true } @@ -48,8 +51,8 @@ func frpByteToStringParse(p []byte) string { var res string for i := 0; i < len(p); i++ { asciiTo16 := fmt.Sprintf("\\x%s", hex.EncodeToString(p[i:i+1])) - w = append(w,asciiTo16) + w = append(w, asciiTo16) } res = strings.Join(w, "") return res -} \ No newline at end of file +} diff --git a/internal/protocol/judge/tcp_ftp.go b/internal/protocol/judge/tcp_ftp.go index 9cd8a29..b000824 100644 --- a/internal/protocol/judge/tcp_ftp.go +++ b/internal/protocol/judge/tcp_ftp.go @@ -1,20 +1,21 @@ package judge import ( - "github.com/zhzyker/dismap/pkg/logger" "regexp" + + "github.com/zhzyker/dismap/internal/model" + "github.com/zhzyker/dismap/pkg/logger" ) -func TcpFTP(result map[string]interface{}) bool { - var buff []byte - buff, _ = result["banner.byte"].([]byte) +func TcpFTP(result *model.Result) bool { + var buff = result.BannerB ok, err := regexp.Match(`(^220(.*FTP|.*FileZilla)|^421(.*)connections)`, buff) if logger.DebugError(err) { return false } if ok { - result["protocol"] = "ftp" + result.Protocol = "ftp" return true } return false -} \ No newline at end of file +} diff --git a/internal/protocol/judge/tcp_giop.go b/internal/protocol/judge/tcp_giop.go index 45f77f1..333abb8 100644 --- a/internal/protocol/judge/tcp_giop.go +++ b/internal/protocol/judge/tcp_giop.go @@ -2,25 +2,23 @@ package judge import ( "encoding/hex" + "strings" + + "github.com/zhzyker/dismap/internal/flag" + "github.com/zhzyker/dismap/internal/model" "github.com/zhzyker/dismap/internal/parse" "github.com/zhzyker/dismap/internal/proxy" - "github.com/zhzyker/dismap/pkg/logger" - "strings" ) -func TcpGIOP(result map[string]interface{}, Args map[string]interface{}) bool { - timeout := Args["FlagTimeout"].(int) - host := result["host"].(string) - port := result["port"].(int) - - conn, err := proxy.ConnProxyTcp(host, port, timeout) - if logger.DebugError(err) { +func TcpGIOP(result *model.Result) bool { + conn, err := proxy.ConnProxyTcp(result.Host, result.Port, flag.Timeout) + if err != nil { return false } msg := "\x47\x49\x4f\x50\x01\x02\x00\x03\x00\x00\x00\x17\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x0b\x4e\x61\x6d\x65\x53\x65\x72\x76\x69\x63\x65" _, err = conn.Write([]byte(msg)) - if logger.DebugError(err) { + if err != nil { return false } @@ -30,12 +28,12 @@ func TcpGIOP(result map[string]interface{}, Args map[string]interface{}) bool { _ = conn.Close() } - if strings.Contains(hex.EncodeToString(reply[0:4]), "47494f50") == false { + if !strings.Contains(hex.EncodeToString(reply[0:4]), "47494f50") { return false } - result["protocol"] = "giop" - result["banner.string"] = parse.ByteToStringParse2(reply[0:4]) - result["banner.byte"] = reply + result.Protocol = "giop" + result.Banner = parse.ByteToStringParse2(reply[0:4]) + result.BannerB = reply return true } diff --git a/internal/protocol/judge/tcp_http.go b/internal/protocol/judge/tcp_http.go index 95b72ee..1bfcd37 100644 --- a/internal/protocol/judge/tcp_http.go +++ b/internal/protocol/judge/tcp_http.go @@ -5,10 +5,6 @@ import ( "crypto/md5" "crypto/tls" "fmt" - "github.com/zhzyker/dismap/configs" - "github.com/zhzyker/dismap/internal/proxy" - "github.com/zhzyker/dismap/pkg/logger" - "golang.org/x/text/encoding/simplifiedchinese" "io/ioutil" "net" "net/http" @@ -19,63 +15,71 @@ import ( "strings" "time" "unicode/utf8" + + "github.com/zhzyker/dismap/configs" + "github.com/zhzyker/dismap/internal/flag" + "github.com/zhzyker/dismap/internal/model" + "github.com/zhzyker/dismap/internal/proxy" + "github.com/zhzyker/dismap/pkg/logger" + "golang.org/x/text/encoding/simplifiedchinese" ) -func TcpHTTP(result map[string]interface{}, Args map[string]interface{}) bool { - var buff []byte - buff, _ = result["banner.byte"].([]byte) +func TcpHTTP(result *model.Result) bool { + var buff = result.BannerB ok, err := regexp.Match(`^HTTP/\d.\d \d*`, buff) if logger.DebugError(err) { return false } if ok { - result["protocol"] = "http" - httpResult, httpErr := httpIdentifyResult(result, Args) + result.Protocol = "http" + httpResult, fpHints, httpErr := httpIdentifyResult(result) if logger.DebugError(httpErr) { - result["banner.string"] = "None" + result.Banner = "None" + result.Identify = fpHints return true } - result["banner.string"] = httpResult["http.title"].(string) - u, err := url.Parse(httpResult["http.target"].(string)) + result.Identify = fpHints + result.Banner = httpResult.Title + u, err := url.Parse(httpResult.Url) if err != nil { - result["path"] = "" + result.Path = "" } else { - result["path"] = u.Path + result.Path = u.Path } - r := httpResult["http.result"].(string) - c := fmt.Sprintf("[%s]", logger.Purple(httpResult["http.code"].(string))) + r := httpResult.Result + c := fmt.Sprintf("[%s]", logger.Purple(httpResult.StatusCode)) if len(r) != 0 { - result["identify.bool"] = true - result["identify.string"] = fmt.Sprintf("%s %s", c, r) - result["note"] = httpResult["http.target"].(string) + result.IdentifyBool = true + result.IdentifyStr = fmt.Sprintf("%s %s", c, r) + result.Note = httpResult.Url return true } else { - result["identify.bool"] = true - result["identify.string"] = c - result["note"] = httpResult["http.target"].(string) + result.IdentifyBool = true + result.IdentifyStr = c + result.Note = httpResult.Url return true } } return false } -func httpIdentifyResult(result map[string]interface{}, Args map[string]interface{}) (map[string]interface{}, error) { - timeout := Args["FlagTimeout"].(int) +func httpIdentifyResult(result *model.Result) (*model.HttpResult, []model.HintFinger, error) { + timeout := flag.Timeout var targetUrl string - if Args["FlagUrl"].(string) != "" { - targetUrl = Args["FlagUrl"].(string) - } else{ - host := result["host"].(string) - port := strconv.Itoa(result["port"].(int)) + if flag.InUrl != "" { + targetUrl = flag.InUrl + } else { + host := result.Host + port := strconv.Itoa(result.Port) add := net.JoinHostPort(host, port) - if result["type"].(string) == "tcp" { + if result.Type == "tcp" { if port == "80" { targetUrl = "http://" + host } else { targetUrl = "http://" + add } } - if result["type"].(string) == "tls" { + if result.Type == "tls" { if port == "443" { targetUrl = "https://" + host } else { @@ -84,45 +88,27 @@ func httpIdentifyResult(result map[string]interface{}, Args map[string]interface } } - var httpType string - var httpCode string - var httpResult string - var httpUrl string - var httpTitle string - r, err := identify(targetUrl, timeout) + r, hint, err := identify(targetUrl, timeout) if logger.DebugError(err) { - return nil, err + return nil, nil, err } - for _, results := range r { - httpType = results.Type - httpCode = results.RespCode - httpResult = results.Result - httpUrl = results.Url - httpTitle = results.Title - } - res := map[string]interface{}{ - "http.type": httpType, - "http.code": httpCode, - "http.result": httpResult, - "http.target": httpUrl, - "http.title": httpTitle, - } - return res, nil + return r, hint, nil } -type RespLab struct { - Url string - RespBody string - RespHeader string - RespStatusCode string - RespTitle string - faviconMd5 string +var RuleFuncs = map[string]func(bool, bool) bool{ + "and": checkRuleAnd, + "or": checkRuleOr, +} +var CheckFuncs = map[string]func(*model.HttpResult, *configs.RuleLab) bool{ + "body": checkBody, + "header": checkHeader, + "ico": checkFavicon, } func getFaviconMd5(Url string, timeout int) string { client := &http.Client{ Timeout: time.Duration(timeout) * time.Second, - Transport: &http.Transport { + Transport: &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, }, CheckRedirect: func(req *http.Request, via []*http.Request) error { @@ -134,7 +120,7 @@ func getFaviconMd5(Url string, timeout int) string { if err != nil { return "" } - for key, value := range configs.DefaultHeader { + for key, value := range configs.DefaultHeader { req.Header.Set(key, value) } //req.Header.Set("Accept-Language", "zh,zh-TW;q=0.9,en-US;q=0.8,en;q=0.7,zh-CN;q=0.6") @@ -151,7 +137,7 @@ func getFaviconMd5(Url string, timeout int) string { return md5 } -func defaultRequests(Url string, timeout int) ([]RespLab, error) { +func defaultRequests(Url string, timeout int) (*model.HttpResult, error) { var redirectUrl string var respTitle string var responseHeader string @@ -164,7 +150,7 @@ func defaultRequests(Url string, timeout int) ([]RespLab, error) { return nil, err } // set requests header - for key, value := range configs.DefaultHeader { + for key, value := range configs.DefaultHeader { req.Header.Set(key, value) } resp, err := proxy.ConnProxyHttp(req, timeout) @@ -195,7 +181,7 @@ func defaultRequests(Url string, timeout int) ([]RespLab, error) { if err != nil { return nil, err } - for key, value := range configs.DefaultHeader { + for key, value := range configs.DefaultHeader { req.Header.Set(key, value) } resp, err := proxy.ConnProxyHttp(req, timeout) @@ -217,7 +203,7 @@ func defaultRequests(Url string, timeout int) ([]RespLab, error) { if err != nil { return nil, err } - for key, value := range configs.DefaultHeader { + for key, value := range configs.DefaultHeader { req.Header.Set(key, value) } resp, err := proxy.ConnProxyHttp(req, timeout) @@ -250,8 +236,13 @@ func defaultRequests(Url string, timeout int) ([]RespLab, error) { responseHeader += re + "\n" } faviconMd5 := getFaviconMd5(Url, timeout) - RespData := []RespLab{ - {redirectUrl, responseBody, responseHeader, responseStatusCode, respTitle, faviconMd5}, + RespData := &model.HttpResult{ + Url: redirectUrl, + Body: responseBody, + Header: responseHeader, + StatusCode: responseStatusCode, + Title: respTitle, + FaviconMd5: faviconMd5, } return RespData, nil } @@ -280,8 +271,13 @@ func defaultRequests(Url string, timeout int) ([]RespLab, error) { responseHeader += re + "\n" } faviconMd5 := getFaviconMd5(Url, timeout) - RespData := []RespLab{ - {redirectUrl, responseBody, responseHeader, responseStatusCode, respTitle, faviconMd5}, + RespData := &model.HttpResult{ + Url: redirectUrl, + Body: responseBody, + Header: responseHeader, + StatusCode: responseStatusCode, + Title: respTitle, + FaviconMd5: faviconMd5, } return RespData, nil @@ -311,13 +307,18 @@ func defaultRequests(Url string, timeout int) ([]RespLab, error) { responseHeader += re + "\n" } faviconMd5 := getFaviconMd5(Url, timeout) - RespData := []RespLab{ - {Url, responseBody, responseHeader, responseStatusCode, respTitle, faviconMd5}, + RespData := &model.HttpResult{ + Url: Url, + Body: responseBody, + Header: responseHeader, + StatusCode: responseStatusCode, + Title: respTitle, + FaviconMd5: faviconMd5, } return RespData, nil } -func customRequests(Url string, timeout int, Method string, Path string, Header []string, Body string) ([]RespLab, error) { +func customRequests(Url string, timeout int, Method string, Path string, Header []string, Body string) (*model.HttpResult, error) { var respTitle string // Splicing Custom Path u, err := url.Parse(Url) @@ -329,8 +330,8 @@ func customRequests(Url string, timeout int, Method string, Path string, Header // Send Http requests client := &http.Client{ Timeout: time.Duration(timeout) * time.Second, - Transport: &http.Transport { - TLSClientConfig:&tls.Config{InsecureSkipVerify: true}, + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, }, } bodyByte := bytes.NewBuffer([]byte(Body)) @@ -381,543 +382,104 @@ func customRequests(Url string, timeout int, Method string, Path string, Header // get response status code var statusCode = resp.StatusCode responseStatusCode := strconv.Itoa(statusCode) - RespData := []RespLab{ - {Url, responseBody, responseHeader, responseStatusCode, respTitle, ""}, + faviconMd5 := getFaviconMd5(Url, timeout) + RespData := &model.HttpResult{ + Url: Url, + Body: responseBody, + Header: responseHeader, + StatusCode: responseStatusCode, + Title: respTitle, + FaviconMd5: faviconMd5, } return RespData, nil } -type IdentifyResult struct { - Type string - RespCode string - Result string - Url string - Title string -} - -func identify(url string, timeout int) ([]IdentifyResult, error) { - var DefaultFavicon string - var CustomFavicon string - var DefaultTarget string - var CustomTarget string - var Favicon string - var RequestRule string - var RespTitle string - var RespBody string - var RespHeader string - var RespCode string - var DefaultRespTitle string - var DefaultRespBody string - var DefaultRespHeader string - var DefaultRespCode string - var CustomRespTitle string - var CustomRespBody string - var CustomRespHeader string - var CustomRespCode string +func identify(url string, timeout int) (*model.HttpResult, []model.HintFinger, error) { + var checkResp *model.HttpResult - R, err := defaultRequests(url, timeout) - if logger.DebugError(err) { - return nil, err + defaultResp, err := defaultRequests(url, timeout) + if err != nil { + return nil, nil, err } - for _, resp := range R { - DefaultRespBody = resp.RespBody - DefaultRespHeader = resp.RespHeader - DefaultRespCode = resp.RespStatusCode - DefaultRespTitle = resp.RespTitle - DefaultTarget = resp.Url - DefaultFavicon = resp.faviconMd5 - } - // start identify - var succes_type string - var identify_result string - type Identify_Result struct { - Name string - Rank int - Type string - } - var IdentifyData []Identify_Result + + var Hints []model.HintFinger + for _, rule := range configs.RuleData { + // 如果规则需要自定义请求,那么就请求一下 if rule.Http.ReqMethod != "" { r, err := customRequests(url, timeout, rule.Http.ReqMethod, rule.Http.ReqPath, rule.Http.ReqHeader, rule.Http.ReqBody) - if logger.DebugError(err) { - return nil, err - } - - for _, resp := range r { - CustomRespBody = resp.RespBody - CustomRespHeader = resp.RespHeader - CustomRespCode = resp.RespStatusCode - CustomRespTitle = resp.RespTitle - CustomTarget = resp.Url - CustomFavicon = resp.faviconMd5 - } - url = CustomTarget - Favicon = CustomFavicon - RespBody = CustomRespBody - RespHeader = CustomRespHeader - RespCode = CustomRespCode - RespTitle = CustomRespTitle - // If the http request fails, then RespBody and RespHeader are both null - // At this time, it is considered that the url does not exist - if RespBody == RespHeader { - continue - } - if rule.Mode == "" { - if len(regexp.MustCompile("header").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == true { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - RequestRule = "CustomRequest" - succes_type = rule.Type - continue - } - } - if len(regexp.MustCompile("body").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == true { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - succes_type = rule.Type - continue - } - } - if len(regexp.MustCompile("ico").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkFavicon(Favicon, rule.Rule.InIcoMd5) == true { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - succes_type = rule.Type - continue - } - } - } - if rule.Mode == "or" { - if len(regexp.MustCompile("header").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == true { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - succes_type = rule.Type - continue - } - } - if len(regexp.MustCompile("body").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == true { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - succes_type = rule.Type - continue - } - } - if len(regexp.MustCompile("ico").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkFavicon(Favicon, rule.Rule.InIcoMd5) == true { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - succes_type = rule.Type - continue - } - } - } - if rule.Mode == "and" { - index := 0 - if len(regexp.MustCompile("header").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == true { - index = index + 1 - } - } - if len(regexp.MustCompile("body").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == true { - index = index + 1 - } - } - if len(regexp.MustCompile("ico").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkFavicon(Favicon, rule.Rule.InIcoMd5) == true { - index = index + 1 - } - } - if index == 2 { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - RequestRule = "CustomRequest" - } - } - if rule.Mode == "and|and" { - index := 0 - if len(regexp.MustCompile("header").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == true { - index = index + 1 - } - } - if len(regexp.MustCompile("body").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == true { - index = index + 1 - } - } - if len(regexp.MustCompile("ico").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkFavicon(Favicon, rule.Rule.InIcoMd5) == true { - index = index + 1 - } - } - if index == 3 { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - RequestRule = "CustomRequest" - } - } - if rule.Mode == "or|or" { - if len(regexp.MustCompile("header").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == true { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - succes_type = rule.Type - continue - } - } - if len(regexp.MustCompile("body").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == true { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - succes_type = rule.Type - continue - } - } - if len(regexp.MustCompile("ico").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkFavicon(Favicon, rule.Rule.InIcoMd5) == true { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - succes_type = rule.Type - continue - } - } - } - if rule.Mode == "and|or" { - grep := regexp.MustCompile("(.*)\\|(.*)\\|(.*)") - all_type := grep.FindStringSubmatch(rule.Type) - if len(regexp.MustCompile("header").FindAllStringIndex(all_type[1], -1)) == 1 { - if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - succes_type = rule.Type - continue - } - if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == checkFavicon(Favicon, rule.Rule.InIcoMd5) { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - succes_type = rule.Type - continue - } - } - if len(regexp.MustCompile("body").FindAllStringIndex(all_type[1], -1)) == 1 { - if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - succes_type = rule.Type - continue - } - if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == checkFavicon(Favicon, rule.Rule.InIcoMd5) { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - succes_type = rule.Type - continue - } - } - if len(regexp.MustCompile("ico").FindAllStringIndex(all_type[1], -1)) == 1 { - if checkFavicon(Favicon, rule.Rule.InIcoMd5) == checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - succes_type = rule.Type - continue - } - if checkFavicon(Favicon, rule.Rule.InIcoMd5) == checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - succes_type = rule.Type - continue - } - } + if err != nil { + return nil, nil, err } - if rule.Mode == "or|and" { - grep := regexp.MustCompile("(.*)\\|(.*)\\|(.*)") - all_type := grep.FindStringSubmatch(rule.Type) - fmt.Println(all_type) - if len(regexp.MustCompile("header").FindAllStringIndex(all_type[3], -1)) == 1 { - if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - succes_type = rule.Type - continue - } - if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == checkFavicon(Favicon, rule.Rule.InIcoMd5) { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - succes_type = rule.Type - continue - } - } - if len(regexp.MustCompile("body").FindAllStringIndex(all_type[3], -1)) == 1 { - if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - succes_type = rule.Type - continue - } - if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == checkFavicon(Favicon, rule.Rule.InIcoMd5) { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - succes_type = rule.Type - continue - } - } - if len(regexp.MustCompile("ico").FindAllStringIndex(all_type[3], -1)) == 1 { - if checkFavicon(Favicon, rule.Rule.InIcoMd5) == checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - succes_type = rule.Type - continue - } - if checkFavicon(Favicon, rule.Rule.InIcoMd5) == checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - succes_type = rule.Type - continue - } + checkResp = r + } else { + // 否则使用默认数据 + // Default Request Result + checkResp = defaultResp + } + // If the http request fails, then RespBody and RespHeader are both null + // At this time, it is considered that the url does not exist + if checkResp.Body == checkResp.Header { + continue + } + // 开始判断 + modes := strings.Split(rule.Mode, "|") + strs := strings.Split(rule.Type, "|") + if modes[0] == "" || len(strs) == 1 { + if ff, ok := CheckFuncs[rule.Type]; ok { + if ff(checkResp, rule) { + Hints = append(Hints, model.HintFinger{Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) + continue } } - } else { // Default Request Result - url = DefaultTarget - Favicon = DefaultFavicon - RespBody = DefaultRespBody - RespHeader = DefaultRespHeader - RespCode = DefaultRespCode - RespTitle = DefaultRespTitle - // If the http request fails, then RespBody and RespHeader are both null - // At this time, it is considered that the url does not exist - if RespBody == RespHeader { + } else if len(modes) == 1 { + if RuleFuncs[modes[0]](CheckFuncs[strs[0]](checkResp, rule), CheckFuncs[strs[1]](checkResp, rule)) { + Hints = append(Hints, model.HintFinger{Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) continue } - if rule.Mode == "" { - if len(regexp.MustCompile("header").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == true { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - RequestRule = "DefaultRequest" - succes_type = rule.Type - continue - } - } - if len(regexp.MustCompile("body").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == true { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - RequestRule = "DefaultRequest" - succes_type = rule.Type - continue - } - } - if len(regexp.MustCompile("ico").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkFavicon(Favicon, rule.Rule.InIcoMd5) == true { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - RequestRule = "DefaultRequest" - succes_type = rule.Type - continue - } - } - } - if rule.Mode == "or" { - if len(regexp.MustCompile("header").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == true { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - RequestRule = "DefaultRequest" - succes_type = rule.Type - continue - } - } - if len(regexp.MustCompile("body").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == true { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - RequestRule = "DefaultRequest" - succes_type = rule.Type - continue - } - } - if len(regexp.MustCompile("ico").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkFavicon(Favicon, rule.Rule.InIcoMd5) == true { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - RequestRule = "DefaultRequest" - succes_type = rule.Type - continue - } - } - } - if rule.Mode == "and" { - index := 0 - if len(regexp.MustCompile("header").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == true { - index = index + 1 - } - } - if len(regexp.MustCompile("body").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == true { - index = index + 1 - } - } - if len(regexp.MustCompile("ico").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkFavicon(Favicon, rule.Rule.InIcoMd5) == true { - index = index + 1 - } - } - if index == 2 { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - RequestRule = "DefaultRequest" - } - } - if rule.Mode == "and|and" { - index := 0 - if len(regexp.MustCompile("header").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == true { - index = index + 1 - } - } - if len(regexp.MustCompile("body").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == true { - index = index + 1 - } - } - if len(regexp.MustCompile("ico").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkFavicon(Favicon, rule.Rule.InIcoMd5) == true { - index = index + 1 - } - } - if index == 3 { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - RequestRule = "DefaultRequest" - } - } - if rule.Mode == "or|or" { - if len(regexp.MustCompile("header").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == true { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - RequestRule = "DefaultRequest" - succes_type = rule.Type - continue - } - } - if len(regexp.MustCompile("body").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == true { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - RequestRule = "DefaultRequest" - succes_type = rule.Type - continue - } - } - if len(regexp.MustCompile("ico").FindAllStringIndex(rule.Type, -1)) == 1 { - if checkFavicon(Favicon, rule.Rule.InIcoMd5) == true { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - RequestRule = "DefaultRequest" - succes_type = rule.Type - continue - } - } - } - if rule.Mode == "and|or" { - grep := regexp.MustCompile("(.*)\\|(.*)\\|(.*)") - all_type := grep.FindStringSubmatch(rule.Type) - fmt.Println(all_type) - if len(regexp.MustCompile("header").FindAllStringIndex(all_type[1], -1)) == 1 { - if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - RequestRule = "DefaultRequest" - succes_type = rule.Type - continue - } - if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == checkFavicon(Favicon, rule.Rule.InIcoMd5) { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - RequestRule = "DefaultRequest" - succes_type = rule.Type - continue - } - } - if len(regexp.MustCompile("body").FindAllStringIndex(all_type[1], -1)) == 1 { - if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - RequestRule = "DefaultRequest" - succes_type = rule.Type - continue - } - if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == checkFavicon(Favicon, rule.Rule.InIcoMd5) { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - RequestRule = "DefaultRequest" - succes_type = rule.Type - continue - } - } - if len(regexp.MustCompile("ico").FindAllStringIndex(all_type[1], -1)) == 1 { - if checkFavicon(Favicon, rule.Rule.InIcoMd5) == checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - RequestRule = "DefaultRequest" - succes_type = rule.Type - continue - } - if checkFavicon(Favicon, rule.Rule.InIcoMd5) == checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - RequestRule = "DefaultRequest" - succes_type = rule.Type - continue - } - } - } - if rule.Mode == "or|and" { - grep := regexp.MustCompile("(.*)\\|(.*)\\|(.*)") - all_type := grep.FindStringSubmatch(rule.Type) - fmt.Println(all_type) - if len(regexp.MustCompile("header").FindAllStringIndex(all_type[3], -1)) == 1 { - if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - RequestRule = "DefaultRequest" - succes_type = rule.Type - continue - } - if checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) == checkFavicon(Favicon, rule.Rule.InIcoMd5) { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - RequestRule = "DefaultRequest" - succes_type = rule.Type - continue - } - } - if len(regexp.MustCompile("body").FindAllStringIndex(all_type[3], -1)) == 1 { - if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - RequestRule = "DefaultRequest" - succes_type = rule.Type - continue - } - if checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) == checkFavicon(Favicon, rule.Rule.InIcoMd5) { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - RequestRule = "DefaultRequest" - succes_type = rule.Type - continue - } - } - if len(regexp.MustCompile("ico").FindAllStringIndex(all_type[3], -1)) == 1 { - if checkFavicon(Favicon, rule.Rule.InIcoMd5) == checkHeader(url, RespHeader, rule.Rule.InHeader, rule.Name, RespTitle, RespCode) { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - RequestRule = "DefaultRequest" - succes_type = rule.Type - continue - } - if checkFavicon(Favicon, rule.Rule.InIcoMd5) == checkBody(url, RespBody, rule.Rule.InBody, rule.Name, RespTitle, RespCode) { - IdentifyData = append(IdentifyData, Identify_Result {Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) - RequestRule = "DefaultRequest" - succes_type = rule.Type - continue - } + } else if len(modes) == 2 { + status := CheckFuncs[strs[0]](checkResp, rule) + for index, _rt := range modes { + status = RuleFuncs[_rt](status, CheckFuncs[strs[index+1]](checkResp, rule)) + if status { + Hints = append(Hints, model.HintFinger{Name: rule.Name, Rank: rule.Rank, Type: rule.Type}) + break } } + continue } } - if RequestRule == "DefaultRequest" { - RespBody = DefaultRespBody - RespHeader = DefaultRespHeader - RespCode = DefaultRespCode - RespTitle = DefaultRespTitle - url = DefaultTarget - } else if RequestRule == "CustomRequest" { - url = CustomTarget - RespBody = CustomRespBody - RespHeader = CustomRespHeader - RespCode = CustomRespCode - RespTitle = CustomRespTitle - } - for _, rs := range IdentifyData { - switch rs.Rank { + + for index := range Hints { + Hints[index].Source = "dismap" + } + + for _, hint := range Hints { + switch hint.Rank { case 1: - identify_result += "[" + logger.LightYellow(rs.Name) + "]" + checkResp.Result += "[" + logger.LightYellow(hint.Name) + "]" case 2: - identify_result += "[" + logger.LightYellow(rs.Name) + "]" + checkResp.Result += "[" + logger.LightYellow(hint.Name) + "]" case 3: - identify_result += "[" + logger.LightRed(rs.Name) + "]" + checkResp.Result += "[" + logger.LightRed(hint.Name) + "]" } } - r := strings.ReplaceAll(identify_result, "][", "] [") - res := []IdentifyResult{{succes_type, RespCode, r, url, RespTitle}} - return res, nil + + checkResp.Result = strings.ReplaceAll(checkResp.Result, "][", "] [") + return checkResp, Hints, nil +} + +func checkRuleAnd(status1, status2 bool) bool { + return status1 && status2 } -func checkHeader(url, responseHeader string, ruleHeader string, name string, title string, RespCode string) bool { - grep := regexp.MustCompile("(?i)" + ruleHeader) - if len(grep.FindStringSubmatch(responseHeader)) != 0 { +func checkRuleOr(status1, status2 bool) bool { + return status1 || status2 +} + +func checkHeader(resp *model.HttpResult, rule *configs.RuleLab) bool { + grep := regexp.MustCompile("(?i)" + rule.Rule.InHeader) + if len(grep.FindStringSubmatch(resp.Header)) != 0 { //fmt.Print("[header] ") return true } else { @@ -925,9 +487,9 @@ func checkHeader(url, responseHeader string, ruleHeader string, name string, tit } } -func checkBody(url, responseBody string, ruleBody string, name string, title string, RespCode string) bool { - grep := regexp.MustCompile("(?i)" + ruleBody) - if len(grep.FindStringSubmatch(responseBody)) != 0 { +func checkBody(resp *model.HttpResult, rule *configs.RuleLab) bool { + grep := regexp.MustCompile("(?i)" + rule.Rule.InBody) + if len(grep.FindStringSubmatch(resp.Body)) != 0 { //fmt.Print("[body] ") return true } else { @@ -935,11 +497,11 @@ func checkBody(url, responseBody string, ruleBody string, name string, title str } } -func checkFavicon(Favicon, ruleFaviconMd5 string) bool { - grep := regexp.MustCompile("(?i)" + ruleFaviconMd5) - if len(grep.FindStringSubmatch(Favicon)) != 0 { +func checkFavicon(resp *model.HttpResult, rule *configs.RuleLab) bool { + grep := regexp.MustCompile("(?i)" + rule.Rule.InIcoMd5) + if len(grep.FindStringSubmatch(resp.FaviconMd5)) != 0 { return true } else { return false } -} \ No newline at end of file +} diff --git a/internal/protocol/judge/tcp_imap.go b/internal/protocol/judge/tcp_imap.go index b8854ee..712095a 100644 --- a/internal/protocol/judge/tcp_imap.go +++ b/internal/protocol/judge/tcp_imap.go @@ -1,20 +1,22 @@ package judge import ( - "github.com/zhzyker/dismap/pkg/logger" "regexp" + + "github.com/zhzyker/dismap/internal/model" + "github.com/zhzyker/dismap/pkg/logger" ) -func TcpIMAP(result map[string]interface{}) bool { +func TcpIMAP(result *model.Result) bool { var buff []byte - buff, _ = result["banner.byte"].([]byte) + buff = result.BannerB ok, err := regexp.Match(`^* OK`, buff) if logger.DebugError(err) { return false } if ok { - result["protocol"] = "imap" + result.Protocol = "imap" return true } return false -} \ No newline at end of file +} diff --git a/internal/protocol/judge/tcp_ldap.go b/internal/protocol/judge/tcp_ldap.go index 45a4dee..f325f1f 100644 --- a/internal/protocol/judge/tcp_ldap.go +++ b/internal/protocol/judge/tcp_ldap.go @@ -3,16 +3,19 @@ package judge import ( "bytes" "encoding/hex" + "strings" + + "github.com/zhzyker/dismap/internal/flag" + "github.com/zhzyker/dismap/internal/model" "github.com/zhzyker/dismap/internal/parse" "github.com/zhzyker/dismap/internal/proxy" "github.com/zhzyker/dismap/pkg/logger" - "strings" ) -func TcpLDAP(result map[string]interface{}, Args map[string]interface{}) bool { - timeout := Args["FlagTimeout"].(int) - host := result["host"].(string) - port := result["port"].(int) +func TcpLDAP(result *model.Result) bool { + timeout := flag.Timeout + host := result.Host + port := result.Port conn, err := proxy.ConnProxyTcp(host, port, timeout) if logger.DebugError(err) { @@ -38,8 +41,8 @@ func TcpLDAP(result map[string]interface{}, Args map[string]interface{}) bool { if strings.Contains(hex.EncodeToString(reply), "010004000400") == false { return false } - result["protocol"] = "ldap" - result["banner.string"] = parse.ByteToStringParse2(reply[0:16]) - result["banner.byte"] = reply + result.Protocol = "ldap" + result.Banner = parse.ByteToStringParse2(reply[0:16]) + result.BannerB = reply return true -} \ No newline at end of file +} diff --git a/internal/protocol/judge/tcp_mssql.go b/internal/protocol/judge/tcp_mssql.go index 66ce678..a2be49a 100644 --- a/internal/protocol/judge/tcp_mssql.go +++ b/internal/protocol/judge/tcp_mssql.go @@ -4,25 +4,23 @@ import ( "bytes" "encoding/hex" "fmt" + "strconv" + + "github.com/zhzyker/dismap/internal/flag" + "github.com/zhzyker/dismap/internal/model" "github.com/zhzyker/dismap/internal/parse" "github.com/zhzyker/dismap/internal/proxy" - "github.com/zhzyker/dismap/pkg/logger" - "strconv" ) -func TcpMssql(result map[string]interface{}, Args map[string]interface{}) bool { - timeout := Args["FlagTimeout"].(int) - host := result["host"].(string) - port := result["port"].(int) - - conn, err := proxy.ConnProxyTcp(host, port, timeout) - if logger.DebugError(err) { +func TcpMssql(result *model.Result) bool { + conn, err := proxy.ConnProxyTcp(result.Host, result.Port, flag.Timeout) + if err != nil { return false } msg := "\x12\x01\x00\x34\x00\x00\x00\x00\x00\x00\x15\x00\x06\x01\x00\x1b\x00\x01\x02\x00\x1c\x00\x0c\x03\x00\x28\x00\x04\xff\x08\x00\x01\x55\x00\x00\x02\x4d\x53\x53\x51\x4c\x53\x65\x72\x76\x65\x72\x00\x00\x00\x31\x32" _, err = conn.Write([]byte(msg)) - if logger.DebugError(err) { + if err != nil { return false } @@ -38,18 +36,20 @@ func TcpMssql(result map[string]interface{}, Args map[string]interface{}) bool { } else if hex.EncodeToString(reply[0:4]) != "04010025" { return false } else { - result["protocol"] = "mssql" + result.Protocol = "mssql" } v, bo := getVersion(reply) if bo { - result["identify.bool"] = true - result["identify.string"] = fmt.Sprintf("[%s]", logger.LightYellow(fmt.Sprintf("Version:%s", v))) - + result.IdentifyBool = true + result.Identify = append(result.Identify, model.HintFinger{ + Name: "mssql", + Version: v, + }) } - result["banner.string"] = parse.ByteToStringParse1(reply) - result["banner.byte"] = reply + result.Banner = parse.ByteToStringParse1(reply) + result.BannerB = reply return true } @@ -68,4 +68,4 @@ func getVersion(reply []byte) (string, bool) { } v := fmt.Sprintf("%d.%d.%d", m, s, r) return v, true -} \ No newline at end of file +} diff --git a/internal/protocol/judge/tcp_mysql.go b/internal/protocol/judge/tcp_mysql.go index 2429432..d819201 100644 --- a/internal/protocol/judge/tcp_mysql.go +++ b/internal/protocol/judge/tcp_mysql.go @@ -1,19 +1,21 @@ package judge import ( - "github.com/zhzyker/dismap/pkg/logger" "regexp" + + "github.com/zhzyker/dismap/internal/model" + "github.com/zhzyker/dismap/pkg/logger" ) -func TcpMysql(result map[string]interface{}) bool { +func TcpMysql(result *model.Result) bool { var buff []byte - buff, _ = result["banner.byte"].([]byte) + buff = result.BannerB ok, err := regexp.Match(`(mysql_native_password|MySQL server|MariaDB server|mysqladmin flush-hosts)`, buff) if logger.DebugError(err) { return false } if ok { - result["protocol"] = "mysql" + result.Protocol = "mysql" return true } return false diff --git a/internal/protocol/judge/tcp_oracle.go b/internal/protocol/judge/tcp_oracle.go index 2496b81..0afffaf 100644 --- a/internal/protocol/judge/tcp_oracle.go +++ b/internal/protocol/judge/tcp_oracle.go @@ -4,17 +4,20 @@ import ( "bytes" "encoding/hex" "fmt" + "regexp" + "strconv" + + "github.com/zhzyker/dismap/internal/flag" + "github.com/zhzyker/dismap/internal/model" "github.com/zhzyker/dismap/internal/parse" "github.com/zhzyker/dismap/internal/proxy" "github.com/zhzyker/dismap/pkg/logger" - "regexp" - "strconv" ) -func TcpOracle(result map[string]interface{}, Args map[string]interface{}) bool { - timeout := Args["FlagTimeout"].(int) - host := result["host"].(string) - port := result["port"].(int) +func TcpOracle(result *model.Result) bool { + timeout := flag.Timeout + host := result.Host + port := result.Port conn, err := proxy.ConnProxyTcp(host, port, timeout) if logger.DebugError(err) { @@ -33,9 +36,9 @@ func TcpOracle(result map[string]interface{}, Args map[string]interface{}) bool _ = conn.Close() } - ok, err := regexp.Match(`\(DESCRIPTION=`, result["banner.byte"].([]byte)) + ok, err := regexp.Match(`\(DESCRIPTION=`, result.BannerB) if ok { - result["protocol"] = "oracle" + result.Protocol = "oracle" } else { var buffer [256]byte if bytes.Equal(reply[:], buffer[:]) { @@ -43,7 +46,7 @@ func TcpOracle(result map[string]interface{}, Args map[string]interface{}) bool } else if hex.EncodeToString(reply[0:8]) != "0065000004000000" { return false } else { - result["protocol"] = "oracle" + result.Protocol = "oracle" } } var vsnnum string @@ -52,7 +55,7 @@ func TcpOracle(result map[string]interface{}, Args map[string]interface{}) bool vsnnum = grep.FindStringSubmatch(banStr)[1] v, err := strconv.ParseInt(vsnnum, 10, 64) if logger.DebugError(err) { - result["identify.bool"] = false + result.IdentifyBool = false } hexVsnnum := strconv.FormatInt(v, 16) @@ -65,18 +68,16 @@ func TcpOracle(result map[string]interface{}, Args map[string]interface{}) bool var version string if err == nil { version = fmt.Sprintf("%s.%s.%s.%s.%s", - strconv.FormatUint(maj,10), - strconv.FormatUint(min,10), - strconv.FormatUint(a,10), - strconv.FormatUint(b,10), - strconv.FormatUint(c,10), + strconv.FormatUint(maj, 10), + strconv.FormatUint(min, 10), + strconv.FormatUint(a, 10), + strconv.FormatUint(b, 10), + strconv.FormatUint(c, 10), ) - } else { - result["identify.bool"] = false } - result["identify.bool"] = true - result["identify.string"] = fmt.Sprintf("[%s]", logger.LightYellow(fmt.Sprintf("Version:%s", version))) - result["banner.string"] = banStr - result["banner.byte"] = reply + result.IdentifyBool = true + result.IdentifyStr = fmt.Sprintf("[%s]", logger.LightYellow(fmt.Sprintf("Version:%s", version))) + result.Banner = banStr + result.BannerB = reply return true } diff --git a/internal/protocol/judge/tcp_pop3.go b/internal/protocol/judge/tcp_pop3.go index b6ba414..6755e0b 100644 --- a/internal/protocol/judge/tcp_pop3.go +++ b/internal/protocol/judge/tcp_pop3.go @@ -1,20 +1,22 @@ package judge import ( - "github.com/zhzyker/dismap/pkg/logger" "regexp" + + "github.com/zhzyker/dismap/internal/model" + "github.com/zhzyker/dismap/pkg/logger" ) -func TcpPOP3(result map[string]interface{}) bool { +func TcpPOP3(result *model.Result) bool { var buff []byte - buff, _ = result["banner.byte"].([]byte) + buff = result.BannerB ok, err := regexp.Match(`^\+OK`, buff) if logger.DebugError(err) { return false } if ok { - result["protocol"] = "pop3" + result.Protocol = "pop3" return true } return false -} \ No newline at end of file +} diff --git a/internal/protocol/judge/tcp_rdp.go b/internal/protocol/judge/tcp_rdp.go index 170b789..cfc948b 100644 --- a/internal/protocol/judge/tcp_rdp.go +++ b/internal/protocol/judge/tcp_rdp.go @@ -3,32 +3,30 @@ package judge import ( "bytes" "encoding/hex" + + "github.com/zhzyker/dismap/internal/flag" + "github.com/zhzyker/dismap/internal/model" "github.com/zhzyker/dismap/internal/proxy" - "github.com/zhzyker/dismap/pkg/logger" ) -func TcpRDP(result map[string]interface{}, Args map[string]interface{}) bool { - timeout := Args["FlagTimeout"].(int) - host := result["host"].(string) - port := result["port"].(int) - - conn, err := proxy.ConnProxyTcp(host, port, timeout) - if logger.DebugError(err) { +func TcpRDP(result *model.Result) bool { + conn, err := proxy.ConnProxyTcp(result.Host, result.Port, flag.Timeout) + if err != nil { return false } //msg1 := "\x03\x00\x00\x13\x0e\xe0\x00\x00\x00\x00\x00\x01\x00\x08\x00\x03\x00\x00\x00" msg2 := "\x03\x00\x00\x2b\x26\xe0\x00\x00\x00\x00\x00\x43\x6f\x6f\x6b\x69\x65\x3a\x20\x6d\x73\x74\x73\x68\x61\x73\x68\x3d\x75\x73\x65\x72\x30\x0d\x0a\x01\x00\x08\x00\x00\x00\x00\x00" _, err = conn.Write([]byte(msg2)) - if logger.DebugError(err) { + if err != nil { return false } reply := make([]byte, 256) _, _ = conn.Read(reply) if conn != nil { - _ = conn.Close() - } + _ = conn.Close() + } var buffer [256]byte if bytes.Equal(reply[:], buffer[:]) { @@ -36,7 +34,7 @@ func TcpRDP(result map[string]interface{}, Args map[string]interface{}) bool { } else if hex.EncodeToString(reply[0:8]) != "030000130ed00000" { return false } else { - result["protocol"] = "rdp" + result.Protocol = "rdp" } os := map[string]string{} @@ -44,22 +42,22 @@ func TcpRDP(result map[string]interface{}, Args map[string]interface{}) bool { os["030000130ed000001234000209080002000000"]="Windows 7/Windows Server 2008" os["030000130ed00000123400021f080002000000"]="Windows 10/Windows Server 2019" os["030000130ed00000123400020f080002000000"]="Windows 8.1/Windows Server 2012 R2" - */ - os["030000130ed000001234000209080000000000"]="Windows 7/Windows Server 2008 R2" - os["030000130ed000001234000200080000000000"]="Windows 7/Windows Server 2008" - os["030000130ed000001234000201080000000000"]="Windows Server 2008 R2" - os["030000130ed000001234000207080000000000"]="Windows 8/Windows server 2012" - os["030000130ed00000123400020f080000000000"]="Windows 8.1/Windows Server 2012 R2" - os["030000130ed000001234000300080001000000"]="Windows 10/Windows Server 2016" - os["030000130ed000001234000300080005000000"]="Windows 10/Windows 11/Windows Server 2019" + */ + os["030000130ed000001234000209080000000000"] = "Windows 7/Windows Server 2008 R2" + os["030000130ed000001234000200080000000000"] = "Windows 7/Windows Server 2008" + os["030000130ed000001234000201080000000000"] = "Windows Server 2008 R2" + os["030000130ed000001234000207080000000000"] = "Windows 8/Windows server 2012" + os["030000130ed00000123400020f080000000000"] = "Windows 8.1/Windows Server 2012 R2" + os["030000130ed000001234000300080001000000"] = "Windows 10/Windows Server 2016" + os["030000130ed000001234000300080005000000"] = "Windows 10/Windows 11/Windows Server 2019" for k, v := range os { if k == hex.EncodeToString(reply[0:19]) { - result["banner.string"] = v + result.Banner = v return true } } - result["banner.string"] = hex.EncodeToString(reply[0:19]) - result["banner.byte"] = reply + result.Banner = hex.EncodeToString(reply[0:19]) + result.BannerB = reply return true } diff --git a/internal/protocol/judge/tcp_redis.go b/internal/protocol/judge/tcp_redis.go index 7cc398d..552ff03 100644 --- a/internal/protocol/judge/tcp_redis.go +++ b/internal/protocol/judge/tcp_redis.go @@ -1,20 +1,22 @@ package judge import ( - "github.com/zhzyker/dismap/pkg/logger" "regexp" + + "github.com/zhzyker/dismap/internal/model" + "github.com/zhzyker/dismap/pkg/logger" ) -func TcpRedis(result map[string]interface{}) bool { +func TcpRedis(result *model.Result) bool { var buff []byte - buff, _ = result["banner.byte"].([]byte) + buff = result.BannerB ok, err := regexp.Match(`(^-ERR(.*)command|^-DENIED.Redis)`, buff) if logger.DebugError(err) { return false } if ok { - result["protocol"] = "redis" + result.Protocol = "redis" return true } return false -} \ No newline at end of file +} diff --git a/internal/protocol/judge/tcp_rmi.go b/internal/protocol/judge/tcp_rmi.go index df71b2e..1dee547 100644 --- a/internal/protocol/judge/tcp_rmi.go +++ b/internal/protocol/judge/tcp_rmi.go @@ -3,15 +3,18 @@ package judge import ( "bytes" "encoding/hex" + + "github.com/zhzyker/dismap/internal/flag" + "github.com/zhzyker/dismap/internal/model" "github.com/zhzyker/dismap/internal/parse" "github.com/zhzyker/dismap/internal/proxy" "github.com/zhzyker/dismap/pkg/logger" ) -func TcpRMI(result map[string]interface{}, Args map[string]interface{}) bool { - timeout := Args["FlagTimeout"].(int) - host := result["host"].(string) - port := result["port"].(int) +func TcpRMI(result *model.Result) bool { + timeout := flag.Timeout + host := result.Host + port := result.Port conn, err := proxy.ConnProxyTcp(host, port, timeout) if logger.DebugError(err) { @@ -36,8 +39,8 @@ func TcpRMI(result map[string]interface{}, Args map[string]interface{}) bool { } else if hex.EncodeToString(reply[0:1]) != "4e" { return false } - result["protocol"] = "rmi" - result["banner.string"] = parse.ByteToStringParse1(reply) - result["banner.byte"] = reply + result.Protocol = "rmi" + result.Banner = parse.ByteToStringParse1(reply) + result.BannerB = reply return true -} \ No newline at end of file +} diff --git a/internal/protocol/judge/tcp_rtsp.go b/internal/protocol/judge/tcp_rtsp.go index 22f1b49..c11f023 100644 --- a/internal/protocol/judge/tcp_rtsp.go +++ b/internal/protocol/judge/tcp_rtsp.go @@ -4,46 +4,42 @@ import ( "bytes" "encoding/hex" "fmt" - "github.com/zhzyker/dismap/internal/parse" - "github.com/zhzyker/dismap/internal/proxy" - "github.com/zhzyker/dismap/pkg/logger" "net" "regexp" "strconv" + + "github.com/zhzyker/dismap/internal/flag" + "github.com/zhzyker/dismap/internal/model" + "github.com/zhzyker/dismap/internal/parse" + "github.com/zhzyker/dismap/internal/proxy" ) -func TcpRTSP(result map[string]interface{}, Args map[string]interface{}) bool { - var buff []byte - buff, _ = result["banner.byte"].([]byte) - ok, err := regexp.Match(`^RTSP/`, buff) - if logger.DebugError(err) { +func TcpRTSP(result *model.Result) bool { + ok, err := regexp.Match(`^RTSP/`, result.BannerB) + if err != nil { return false } if ok { - result["protocol"] = "rtsp" + result.Protocol = "rtsp" return true } - if rtsp(result, Args) { + if rtsp(result) { return true } return false } -func rtsp(result map[string]interface{}, Args map[string]interface{}) bool { - timeout := Args["FlagTimeout"].(int) - host := result["host"].(string) - port := result["port"].(int) - - address := net.JoinHostPort(host, strconv.Itoa(port)) - conn, err := proxy.ConnProxyTcp(host, port, timeout) - if logger.DebugError(err) { +func rtsp(result *model.Result) bool { + address := net.JoinHostPort(result.Host, strconv.Itoa(result.Port)) + conn, err := proxy.ConnProxyTcp(result.Host, result.Port, flag.Timeout) + if err != nil { return false } msg := fmt.Sprintf("OPTIONS rtsp://%s RTSP/1.0\r\nCSeq:1\r\n\r\n", address) _, err = conn.Write([]byte(msg)) - if logger.DebugError(err) { + if err != nil { return false } @@ -59,8 +55,8 @@ func rtsp(result map[string]interface{}, Args map[string]interface{}) bool { } else if hex.EncodeToString(reply[0:4]) != "52545350" { return false } - result["protocol"] = "rtsp" - result["banner.string"] = parse.ByteToStringParse1(reply) - result["banner.byte"] = reply + result.Protocol = "rtsp" + result.Banner = parse.ByteToStringParse1(reply) + result.BannerB = reply return true -} \ No newline at end of file +} diff --git a/internal/protocol/judge/tcp_smb.go b/internal/protocol/judge/tcp_smb.go index d0de473..6ecd1d8 100644 --- a/internal/protocol/judge/tcp_smb.go +++ b/internal/protocol/judge/tcp_smb.go @@ -5,24 +5,23 @@ import ( "encoding/binary" "encoding/hex" "fmt" - "github.com/zhzyker/dismap/internal/proxy" - "github.com/zhzyker/dismap/pkg/logger" "io" "net" "strings" "time" + "github.com/zhzyker/dismap/internal/flag" + "github.com/zhzyker/dismap/internal/model" + "github.com/zhzyker/dismap/internal/proxy" + crand "crypto/rand" ) -func TcpSMB(result map[string]interface{}, Args map[string]interface{}) bool { - timeout := Args["FlagTimeout"].(int) - host := result["host"].(string) - port := result["port"].(int) - if smbPublic(result, host, port, timeout) { +func TcpSMB(result *model.Result) bool { + if smbPublic(result, result.Host, result.Port, flag.Timeout) { return true } - res, data, err := smb2(host, port, timeout) + res, data, err := smb2(result.Host, result.Port, flag.Timeout) if err != nil || res["ntlmssp.Version"] == "" { return false } else { @@ -31,24 +30,24 @@ func TcpSMB(result map[string]interface{}, Args map[string]interface{}) bool { res["ntlmssp.DNSComputer"], res["ntlmssp.TargetName"], res["ntlmssp.NetbiosComputer"], - ) - result["banner.string"] = banner - result["protocol"] = "smb" - result["banner.byte"] = data + ) + result.Banner = banner + result.Protocol = "smb" + result.BannerB = data return true } } -func smbPublic(result map[string]interface{}, host string, port int, timeout int) bool { +func smbPublic(result *model.Result, host string, port int, timeout int) bool { conn, err := proxy.ConnProxyTcp(host, port, timeout) - if logger.DebugError(err) { + if err != nil { return false } msg1 := "\x00\x00\x00\x85\xff\x53\x4d\x42\x72\x00\x00\x00\x00\x18\x53\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xfe\x00\x00\x40\x00\x00\x62\x00\x02\x50\x43\x20\x4e\x45\x54\x57\x4f\x52\x4b\x20\x50\x52\x4f\x47\x52\x41\x4d\x20\x31\x2e\x30\x00\x02\x4c\x41\x4e\x4d\x41\x4e\x31\x2e\x30\x00\x02\x57\x69\x6e\x64\x6f\x77\x73\x20\x66\x6f\x72\x20\x57\x6f\x72\x6b\x67\x72\x6f\x75\x70\x73\x20\x33\x2e\x31\x61\x00\x02\x4c\x4d\x31\x2e\x32\x58\x30\x30\x32\x00\x02\x4c\x41\x4e\x4d\x41\x4e\x32\x2e\x31\x00\x02\x4e\x54\x20\x4c\x4d\x20\x30\x2e\x31\x32\x00" msg2 := "\x00\x00\x00\x88\xff\x53\x4d\x42\x73\x00\x00\x00\x00\x18\x07\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xfe\x00\x00\x40\x00\x0d\xff\x00\x88\x00\x04\x11\x0a\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xd4\x00\x00\x00\x4b\x00\x00\x00\x00\x00\x00\x57\x00\x69\x00\x6e\x00\x64\x00\x6f\x00\x77\x00\x73\x00\x20\x00\x32\x00\x30\x00\x30\x00\x30\x00\x20\x00\x32\x00\x31\x00\x39\x00\x35\x00\x00\x00\x57\x00\x69\x00\x6e\x00\x64\x00\x6f\x00\x77\x00\x73\x00\x20\x00\x32\x00\x30\x00\x30\x00\x30\x00\x20\x00\x35\x00\x2e\x00\x30\x00\x00\x00" _, err = conn.Write([]byte(msg1)) - if logger.DebugError(err) { + if err != nil { return false } reply1 := make([]byte, 256) @@ -58,18 +57,18 @@ func smbPublic(result map[string]interface{}, host string, port int, timeout int return false } _, err = conn.Write([]byte(msg2)) - if logger.DebugError(err) { + if err != nil { return false } reply2 := make([]byte, 512) _, _ = conn.Read(reply2) if conn != nil { - _ = conn.Close() - } + _ = conn.Close() + } var buffer bytes.Buffer for i := 0; i < len(reply2[46:]); { - b := reply2[46:][i:i+2] + b := reply2[46:][i : i+2] i += 2 if 46+i == len(reply2[46:]) { break @@ -79,19 +78,19 @@ func smbPublic(result map[string]interface{}, host string, port int, timeout int break } buffer.Write([]byte("\x7C\x7C")) - result["banner.string"] = strings.Join([]string{string(buffer.Bytes())}, ",") + result.Banner = strings.Join([]string{buffer.String()}, ",") continue } buffer.Write(b[0:1]) - result["banner.string"] = strings.Join([]string{string(buffer.Bytes())}, ",") + result.Banner = strings.Join([]string{buffer.String()}, ",") } var ban [512]byte if bytes.Equal(reply2[:], ban[:]) { return false } else { - result["protocol"] = "smb" - result["banner.byte"] = reply2 + result.Protocol = "smb" + result.BannerB = reply2 return true } } @@ -131,25 +130,25 @@ func smb2(host string, port int, timeout int) (map[string]string, []byte, error) info := make(map[string]string) conn, err := proxy.ConnProxyTcp(host, port, timeout) - if logger.DebugError(err) { + if err != nil { return info, []byte{}, err } err = SMBSendData(conn, smb1NegotiateProtocolRequest, timeout) - if logger.DebugError(err) { + if err != nil { return info, []byte{}, err } - data, err := SMBReadFrame(conn, timeout) - if logger.DebugError(err) { + _, err = SMBReadFrame(conn, timeout) + if err != nil { return info, []byte{}, err } err = SMBSendData(conn, SMB2NegotiateProtocolRequest(host), timeout) - if logger.DebugError(err) { + if err != nil { return info, []byte{}, err } - data, _ = SMBReadFrame(conn, timeout) + data, _ := SMBReadFrame(conn, timeout) SMB2ExtractFieldsFromNegotiateReply(data, info) // SMB2SessionSetupNTLMSSP is a SMB2 SessionSetup NTLMSSP request @@ -184,7 +183,7 @@ func smb2(host string, port int, timeout int) (map[string]string, []byte, error) binary.LittleEndian.PutUint16(setup[4+32:], 0xfeff) err = SMBSendData(conn, setup, timeout) - if logger.DebugError(err) { + if err != nil { return info, []byte{}, err } @@ -198,14 +197,14 @@ func smb2(host string, port int, timeout int) (map[string]string, []byte, error) // RandomBytes generates a random byte sequence of the requested length func RandomBytes(numBytes int) []byte { randBytes := make([]byte, numBytes) - err := binary.Read(crand.Reader, binary.BigEndian, &randBytes) - logger.DebugError(err) + // err := binary.Read(crand.Reader, binary.BigEndian, &randBytes) + binary.Read(crand.Reader, binary.BigEndian, &randBytes) return randBytes } // SMBReadFrame reads the netBios header then the full response func SMBReadFrame(conn net.Conn, t int) ([]byte, error) { - timeout := time.Now().Add(time.Duration(t)*time.Second) + timeout := time.Now().Add(time.Duration(t) * time.Second) res := []byte{} nbh := make([]byte, 4) @@ -417,7 +416,7 @@ func SMB2ParseNegotiateContext(t int, data []byte, info map[string]string) { // SMBSendData writes a SMB request to a socket func SMBSendData(conn net.Conn, data []byte, timeout int) error { - err := conn.SetWriteDeadline(time.Now().Add(time.Duration(timeout)*time.Second)) + err := conn.SetWriteDeadline(time.Now().Add(time.Duration(timeout) * time.Second)) if err != nil { return err } @@ -654,4 +653,4 @@ func SMB2NegotiateProtocolRequest(dst string) []byte { binary.BigEndian.PutUint32(nbhd, uint32(len(base))) nbhd = append(nbhd, base...) return nbhd -} \ No newline at end of file +} diff --git a/internal/protocol/judge/tcp_smtp.go b/internal/protocol/judge/tcp_smtp.go index 0393b56..db4873a 100644 --- a/internal/protocol/judge/tcp_smtp.go +++ b/internal/protocol/judge/tcp_smtp.go @@ -1,20 +1,22 @@ package judge import ( - "github.com/zhzyker/dismap/pkg/logger" "regexp" + + "github.com/zhzyker/dismap/internal/model" + "github.com/zhzyker/dismap/pkg/logger" ) -func TcpSMTP(result map[string]interface{}) bool { +func TcpSMTP(result *model.Result) bool { var buff []byte - buff, _ = result["banner.byte"].([]byte) + buff = result.BannerB ok, err := regexp.Match(`(^220[ -](.*)ESMTP|^421(.*)Service not available|^554 )`, buff) if logger.DebugError(err) { return false } if ok { - result["protocol"] = "smtp" + result.Protocol = "smtp" return true } return false -} \ No newline at end of file +} diff --git a/internal/protocol/judge/tcp_snmp.go b/internal/protocol/judge/tcp_snmp.go index 6d159ac..d3ccb5a 100644 --- a/internal/protocol/judge/tcp_snmp.go +++ b/internal/protocol/judge/tcp_snmp.go @@ -2,19 +2,21 @@ package judge import ( "bytes" + + "github.com/zhzyker/dismap/internal/model" ) -func TcpSNMP(result map[string]interface{}) bool { - b := result["banner.byte"].([]byte) +func TcpSNMP(result *model.Result) bool { + b := result.BannerB if bytes.Equal(b[:], make([]byte, 0)[:]) { return false } buff := []byte{0x41, 0x01, 0x02} - snmp := result["banner.byte"].([]byte)[0:3] + snmp := result.BannerB[0:3] if bytes.Equal(buff[:], snmp[:]) { - result["protocol"] = "snmp" + result.Protocol = "snmp" return true } return false -} \ No newline at end of file +} diff --git a/internal/protocol/judge/tcp_socks.go b/internal/protocol/judge/tcp_socks.go index 279e723..90b702a 100644 --- a/internal/protocol/judge/tcp_socks.go +++ b/internal/protocol/judge/tcp_socks.go @@ -4,31 +4,34 @@ import ( "bytes" "encoding/hex" "fmt" + "regexp" + "strconv" + + "github.com/zhzyker/dismap/internal/flag" + "github.com/zhzyker/dismap/internal/model" "github.com/zhzyker/dismap/internal/parse" "github.com/zhzyker/dismap/internal/proxy" "github.com/zhzyker/dismap/pkg/logger" - "regexp" - "strconv" ) -func TcpSocks(result map[string]interface{}, Args map[string]interface{}) bool { - timeout := Args["FlagTimeout"].(int) +func TcpSocks(result *model.Result) bool { + timeout := flag.Timeout if socks4(result, timeout) { - result["protocol"] = "socks4" + result.Protocol = "socks4" return true } if socks5(result, timeout) { - result["protocol"] = "socks5" + result.Protocol = "socks5" return true } return false } -func socks5(result map[string]interface{}, timeout int) bool { - host := result["host"].(string) - port := result["port"].(int) +func socks5(result *model.Result, timeout int) bool { + host := result.Host + port := result.Port conn, err := proxy.ConnProxyTcp(host, port, timeout) if logger.DebugError(err) { return false @@ -64,16 +67,16 @@ func socks5(result map[string]interface{}, timeout int) bool { if string(reply[1]) == "\x02" { buffer.WriteString(fmt.Sprintf("[%s]", logger.LightYellow("Method:Username/Password(\\x02)"))) } - result["identify.bool"] = true - result["identify.string"] = buffer.String() - result["banner.string"] = parse.ByteToStringParse2(reply[0:2]) - result["banner.byte"] = reply + result.IdentifyBool = true + result.IdentifyStr = buffer.String() + result.Banner = parse.ByteToStringParse2(reply[0:2]) + result.BannerB = reply return true } -func socks4(result map[string]interface{}, timeout int) bool { - host := result["host"].(string) - port := result["port"].(int) +func socks4(result *model.Result, timeout int) bool { + host := result.Host + port := result.Port conn, err := proxy.ConnProxyTcp(host, port, timeout) if logger.DebugError(err) { return false @@ -81,7 +84,7 @@ func socks4(result map[string]interface{}, timeout int) bool { p1 := strconv.FormatInt(int64(port/256), 16) if p1str, _ := strconv.Atoi(p1); p1str < 10 { - p1 = fmt.Sprintf("0%s",p1) + p1 = fmt.Sprintf("0%s", p1) } p1byte, err := hex.DecodeString(p1) if logger.DebugError(err) { @@ -89,13 +92,13 @@ func socks4(result map[string]interface{}, timeout int) bool { } p2 := strconv.FormatInt(int64(port%256), 16) if p2str, _ := strconv.Atoi(p2); p2str < 10 { - p2 = fmt.Sprintf("0%s",p2) + p2 = fmt.Sprintf("0%s", p2) } p2byte, err := hex.DecodeString(p2) if logger.DebugError(err) { return false } - msgByte := []byte {0x04, 0x01} + msgByte := []byte{0x04, 0x01} msgByte = append(msgByte, p1byte[0]) msgByte = append(msgByte, p2byte[0]) msgStr := hex.EncodeToString(msgByte) @@ -111,7 +114,7 @@ func socks4(result map[string]interface{}, timeout int) bool { n := strconv.FormatInt(i64, 16) if len(n) != 2 { - n = fmt.Sprintf("0%s",n) + n = fmt.Sprintf("0%s", n) } msgStr += n } @@ -129,9 +132,9 @@ func socks4(result map[string]interface{}, timeout int) bool { } if string(reply[1]) == "\x5b" { - result["banner.string"] = parse.ByteToStringParse2(reply[0:8]) - result["banner.byte"] = reply + result.Banner = parse.ByteToStringParse2(reply[0:8]) + result.BannerB = reply return true } return false -} \ No newline at end of file +} diff --git a/internal/protocol/judge/tcp_ssh.go b/internal/protocol/judge/tcp_ssh.go index 804665f..99e7119 100644 --- a/internal/protocol/judge/tcp_ssh.go +++ b/internal/protocol/judge/tcp_ssh.go @@ -1,23 +1,25 @@ package judge import ( - "github.com/zhzyker/dismap/pkg/logger" "regexp" "strings" + + "github.com/zhzyker/dismap/internal/model" + "github.com/zhzyker/dismap/pkg/logger" ) -func TcpSSH(result map[string]interface{}) bool { +func TcpSSH(result *model.Result) bool { var buff []byte - buff, _ = result["banner.byte"].([]byte) + buff = result.BannerB ok, err := regexp.Match(`^SSH.\d`, buff) if logger.DebugError(err) { return false } if ok { - str := result["banner.string"].(string) - result["banner.string"] = strings.Split(str, "\\x0d\\x0a")[0] - result["protocol"] = "ssh" + str := result.Banner + result.Banner = strings.Split(str, "\\x0d\\x0a")[0] + result.Protocol = "ssh" return true } return false -} \ No newline at end of file +} diff --git a/internal/protocol/judge/tcp_telnet.go b/internal/protocol/judge/tcp_telnet.go index 291cb70..afc1379 100644 --- a/internal/protocol/judge/tcp_telnet.go +++ b/internal/protocol/judge/tcp_telnet.go @@ -2,23 +2,24 @@ package judge import ( "encoding/hex" - "github.com/zhzyker/dismap/pkg/logger" "regexp" "strings" + + "github.com/zhzyker/dismap/internal/model" + "github.com/zhzyker/dismap/pkg/logger" ) -func TcpTelnet(result map[string]interface{}) bool { - var buff []byte - buff, _ = result["banner.byte"].([]byte) +func TcpTelnet(result *model.Result) bool { + var buff = result.BannerB ok, err := regexp.Match(`(Telnet>|^BeanShell)`, buff) if logger.DebugError(err) { return false } if ok { - result["protocol"] = "telnet" + result.Protocol = "telnet" return true } else if strings.Contains(hex.EncodeToString(buff[0:2]), "fffb") { - result["protocol"] = "telnet" + result.Protocol = "telnet" return true } return false diff --git a/internal/protocol/judge/tcp_vnc.go b/internal/protocol/judge/tcp_vnc.go index ea3e31d..fe64e77 100644 --- a/internal/protocol/judge/tcp_vnc.go +++ b/internal/protocol/judge/tcp_vnc.go @@ -1,20 +1,22 @@ package judge import ( - "github.com/zhzyker/dismap/pkg/logger" "regexp" + + "github.com/zhzyker/dismap/internal/model" + "github.com/zhzyker/dismap/pkg/logger" ) -func TcpVNC(result map[string]interface{}) bool { +func TcpVNC(result *model.Result) bool { var buff []byte - buff, _ = result["banner.byte"].([]byte) + buff = result.BannerB ok, err := regexp.Match(`^RFB \d`, buff) if logger.DebugError(err) { return false } if ok { - result["protocol"] = "vnc" + result.Protocol = "vnc" return true } return false -} \ No newline at end of file +} diff --git a/internal/protocol/judge/tls_https.go b/internal/protocol/judge/tls_https.go index 7921720..2202f56 100644 --- a/internal/protocol/judge/tls_https.go +++ b/internal/protocol/judge/tls_https.go @@ -2,45 +2,46 @@ package judge import ( "fmt" - "github.com/zhzyker/dismap/pkg/logger" "net/url" "regexp" + + "github.com/zhzyker/dismap/internal/model" + "github.com/zhzyker/dismap/pkg/logger" ) -func TlsHTTPS(result map[string]interface{}, Args map[string]interface{}) bool { - var buff []byte - buff, _ = result["banner.byte"].([]byte) +func TlsHTTPS(result *model.Result) bool { + var buff = result.BannerB ok, err := regexp.Match(`^HTTP/\d.\d \d*`, buff) if logger.DebugError(err) { return false } if ok { - result["protocol"] = "https" - httpResult, httpErr := httpIdentifyResult(result, Args) + result.Protocol = "https" + httpResult, fpHints, httpErr := httpIdentifyResult(result) if logger.DebugError(httpErr) { - result["banner.string"] = "None" + result.Identify = fpHints + result.Banner = "None" return true } - result["banner.string"] = httpResult["http.title"].(string) - u, err := url.Parse(httpResult["http.target"].(string)) + result.Identify = fpHints + result.Banner = httpResult.Title + u, err := url.Parse(httpResult.Url) if err != nil { - result["path"] = "" + result.Path = "" } else { - result["path"] = u.Path + result.Path = u.Path } - r := httpResult["http.result"].(string) - c := fmt.Sprintf("[%s]", logger.Purple(httpResult["http.code"].(string))) + r := httpResult.Result + c := fmt.Sprintf("[%s]", logger.Purple(httpResult.StatusCode)) + result.IdentifyBool = true + result.Note = httpResult.Url if len(r) != 0 { - result["identify.bool"] = true - result["identify.string"] = fmt.Sprintf("%s %s", c, r) - result["note"] = httpResult["http.target"].(string) + result.IdentifyStr = fmt.Sprintf("%s %s", c, r) return true } else { - result["identify.bool"] = true - result["identify.string"] = c - result["note"] = httpResult["http.target"].(string) + result.IdentifyStr = c return true } } return false -} \ No newline at end of file +} diff --git a/internal/protocol/judge/tls_rdp.go b/internal/protocol/judge/tls_rdp.go index 7cc2b33..25a5ba9 100644 --- a/internal/protocol/judge/tls_rdp.go +++ b/internal/protocol/judge/tls_rdp.go @@ -1,8 +1,10 @@ package judge -func TlsRDP(result map[string]interface{}, Args map[string]interface{}) bool { - if TcpRDP(result, Args) { +import "github.com/zhzyker/dismap/internal/model" + +func TlsRDP(result *model.Result) bool { + if TcpRDP(result) { return true } return false -} \ No newline at end of file +} diff --git a/internal/protocol/judge/tls_redis_ssl.go b/internal/protocol/judge/tls_redis_ssl.go index defd280..4905af0 100644 --- a/internal/protocol/judge/tls_redis_ssl.go +++ b/internal/protocol/judge/tls_redis_ssl.go @@ -1,20 +1,21 @@ package judge import ( - "github.com/zhzyker/dismap/pkg/logger" "regexp" + + "github.com/zhzyker/dismap/internal/model" + "github.com/zhzyker/dismap/pkg/logger" ) -func TlsRedisSsl(result map[string]interface{}) bool { - var buff []byte - buff, _ = result["banner.byte"].([]byte) +func TlsRedisSsl(result *model.Result) bool { + var buff = result.BannerB ok, err := regexp.Match(`(^-ERR(.*)command|^-(.*).Redis)`, buff) if logger.DebugError(err) { return false } if ok { - result["protocol"] = "redis-ssl" + result.Protocol = "redis-ssl" return true } return false -} \ No newline at end of file +} diff --git a/internal/protocol/judge/udp_nbns.go b/internal/protocol/judge/udp_nbns.go index 6ea106d..aae1875 100644 --- a/internal/protocol/judge/udp_nbns.go +++ b/internal/protocol/judge/udp_nbns.go @@ -3,37 +3,38 @@ package judge import ( "bytes" "fmt" - "github.com/zhzyker/dismap/internal/proxy" - "github.com/zhzyker/dismap/pkg/logger" "strconv" "strings" "time" + + "github.com/zhzyker/dismap/internal/flag" + "github.com/zhzyker/dismap/internal/model" + "github.com/zhzyker/dismap/internal/proxy" + "github.com/zhzyker/dismap/pkg/logger" ) -func UdpNbns(result map[string]interface{}, Args map[string]interface{}) bool { - var status string - status, _ = result["status"].(string) - if status == "open" { - if nbnsIdentifyResult(result, Args) { +func UdpNbns(result *model.Result) bool { + if result.Status == "open" { + if nbnsIdentifyResult(result) { return true } } return false } -func nbnsIdentifyResult(result map[string]interface{}, Args map[string]interface{}) bool { - host := result["host"].(string) - port := result["port"].(int) - timeout := Args["FlagTimeout"].(int) +func nbnsIdentifyResult(result *model.Result) bool { + host := result.Host + port := result.Port + timeout := flag.Timeout conn, err := proxy.ConnProxyUdp(host, port, timeout) if logger.DebugError(err) { return false } msg := []byte{ - 0x0,0x00,0x0,0x10,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x43,0x4b,0x41,0x41, - 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41, - 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x0,0x0, - 0x21,0x0,0x1, + 0x0, 0x00, 0x0, 0x10, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x43, 0x4b, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x0, 0x0, + 0x21, 0x0, 0x1, } _, err = conn.Write(msg) if logger.DebugError(err) { @@ -52,27 +53,27 @@ func nbnsIdentifyResult(result map[string]interface{}, Args map[string]interface } _, _ = conn.Read(reply) if conn != nil { - _ = conn.Close() - } + _ = conn.Close() + } var buffer [256]byte if bytes.Equal(reply[:], buffer[:]) { return false } /* - Re: https://en.wikipedia.org/wiki/NetBIOS#NetBIOS_Suffixes - For unique names: - 00: Workstation Service (workstation name) - 03: Windows Messenger service - 06: Remote Access Service - 20: File Service (also called Host Record) - 21: Remote Access Service client - 1B: Domain Master Browser – Primary Domain Controller for a domain - 1D: Master Browser - For group names: - 00: Workstation Service (workgroup/domain name) - 1C: Domain Controllers for a domain (group record with up to 25 IP addresses) - 1E: Browser Service Elections + Re: https://en.wikipedia.org/wiki/NetBIOS#NetBIOS_Suffixes + For unique names: + 00: Workstation Service (workstation name) + 03: Windows Messenger service + 06: Remote Access Service + 20: File Service (also called Host Record) + 21: Remote Access Service client + 1B: Domain Master Browser – Primary Domain Controller for a domain + 1D: Master Browser + For group names: + 00: Workstation Service (workgroup/domain name) + 1C: Domain Controllers for a domain (group record with up to 25 IP addresses) + 1E: Browser Service Elections */ var n int NumberFoNames, _ := strconv.Atoi(convert([]byte{reply[56:57][0]}[:])) @@ -81,7 +82,7 @@ func nbnsIdentifyResult(result map[string]interface{}, Args map[string]interface var flagDC string for i := 0; i < NumberFoNames; i++ { - data := reply[n+57+18*i:n+57+18*i+18] + data := reply[n+57+18*i : n+57+18*i+18] if string(data[16:17]) == "\x84" || string(data[16:17]) == "\xC4" { if string(data[15:16]) == "\x1C" { flagDC = "Domain Controllers" @@ -109,24 +110,24 @@ func nbnsIdentifyResult(result map[string]interface{}, Args map[string]interface return false } - result["banner.string"] = flagGroup+"\\"+flagUnique - result["identify.string"] = fmt.Sprintf("[%s]", logger.LightRed(flagDC)) + result.Banner = flagGroup + "\\" + flagUnique + result.Banner = fmt.Sprintf("[%s]", logger.LightRed(flagDC)) if len(flagDC) != 0 { - result["identify.bool"] = true + result.IdentifyBool = true } else { - result["identify.bool"] = false + result.IdentifyBool = false } - result["protocol"] = "nbns" - result["banner.byte"] = reply + result.Protocol = "nbns" + result.BannerB = reply return true } -func convert( b []byte ) string { - s := make([]string,len(b)) +func convert(b []byte) string { + s := make([]string, len(b)) for i := range b { s[i] = strconv.Itoa(int(b[i])) } - return strings.Join(s,"") + return strings.Join(s, "") } func nbnsByteToStringParse(p []byte) string { @@ -140,4 +141,4 @@ func nbnsByteToStringParse(p []byte) string { } res = strings.Join(w, "") return res -} \ No newline at end of file +} diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go index 4b393e8..a9caa48 100644 --- a/pkg/logger/logger.go +++ b/pkg/logger/logger.go @@ -2,27 +2,28 @@ package logger import ( "fmt" - flag "github.com/zhzyker/dismap/internal/flag" "os" "regexp" "runtime" "time" + "github.com/zhzyker/dismap/internal/flag" + "github.com/gookit/color" ) var ( - Red = color.Red.Render - Cyan = color.Cyan.Render - Yellow = color.Yellow.Render - White = color.White.Render - Blue = color.Blue.Render - Purple = color.Style{color.Magenta, color.OpBold}.Render - LightRed = color.Style{color.Red, color.OpBold}.Render - LightGreen = color.Style{color.Green, color.OpBold}.Render - LightWhite = color.Style{color.White, color.OpBold}.Render - LightCyan = color.Style{color.Cyan, color.OpBold}.Render - LightYellow = color.Style{color.Yellow, color.OpBold}.Render + Red = color.Red.Render + Cyan = color.Cyan.Render + Yellow = color.Yellow.Render + White = color.White.Render + Blue = color.Blue.Render + Purple = color.Style{color.Magenta, color.OpBold}.Render + LightRed = color.Style{color.Red, color.OpBold}.Render + LightGreen = color.Style{color.Green, color.OpBold}.Render + LightWhite = color.Style{color.White, color.OpBold}.Render + LightCyan = color.Style{color.Cyan, color.OpBold}.Render + LightYellow = color.Style{color.Yellow, color.OpBold}.Render //LightBlue = color.Style{color.Blue, color.OpBold}.Render ) @@ -106,9 +107,9 @@ func DebugError(err error) bool { pc, _, line, _ := runtime.Caller(1) Debug(fmt.Sprintf("%s%s%s", White(runtime.FuncForPC(pc).Name()), - LightWhite(fmt.Sprintf(" line:%d ",line)), + LightWhite(fmt.Sprintf(" line:%d ", line)), White(err))) - return true + return true } return false } @@ -118,4 +119,4 @@ func Clean(str string) string { const ansi = "[\u001B\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\u0007)|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))" var re = regexp.MustCompile(ansi) return re.ReplaceAllString(str, "") -} \ No newline at end of file +}