From e74d45d0736afc38f6892c44da1670867e8b204f Mon Sep 17 00:00:00 2001 From: hanc00l Date: Thu, 29 Apr 2021 10:38:50 +0800 Subject: [PATCH] =?UTF-8?q?Update:=20=E4=BF=AE=E6=94=B9=E8=BE=93=E5=87=BA?= =?UTF-8?q?=E7=BB=93=E6=9E=9C=E7=9A=84=E6=98=BE=E7=A4=BA=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/Ginfo/Ghttp/Ghttp.go | 58 ++++++++++------------- pkg/Ginfo/Gnbtscan/Gnbtscan.go | 73 +++++++++++++++++++++++++++++ pkg/Ginfo/Gnbtscan/Gnbtscan_test.go | 26 ++++++++++ pkg/output/format_screen.go | 36 ++++++++------ 4 files changed, 145 insertions(+), 48 deletions(-) create mode 100644 pkg/Ginfo/Gnbtscan/Gnbtscan.go create mode 100644 pkg/Ginfo/Gnbtscan/Gnbtscan_test.go diff --git a/pkg/Ginfo/Ghttp/Ghttp.go b/pkg/Ginfo/Ghttp/Ghttp.go index b8bad7c..8e5ca42 100644 --- a/pkg/Ginfo/Ghttp/Ghttp.go +++ b/pkg/Ginfo/Ghttp/Ghttp.go @@ -71,8 +71,6 @@ retry: URL = fmt.Sprintf("%s://%s:%d", protocol, domain, port) } - - var client *http.Client //DEBUG := false //if DEBUG { @@ -149,7 +147,6 @@ retry: builder.WriteRune(']') } - defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { @@ -244,22 +241,17 @@ func (r *Result) ToString() string { } else { builder.WriteString("[") builder.WriteString(color.GreenString(conversion.ToString(r.StatusCode))) - if r.ContentLength != -1 { - builder.WriteString("|") - builder.WriteString(color.YellowString(conversion.ToString(r.ContentLength))) + builder.WriteString("] ") + if r.WebServer != "" { + builder.WriteString("[") + builder.WriteString(color.GreenString(r.WebServer)) + builder.WriteString("] ") } - builder.WriteString("]") - - if r.Title !=""{ + if r.Title != "" { builder.WriteString("[") builder.WriteString(color.GreenString(r.Title)) - builder.WriteString("]") - }else{ - builder.WriteString("[") - builder.WriteString(color.GreenString(r.str[:10])) - builder.WriteString("]") + builder.WriteString("] ") } - } return builder.String() @@ -314,8 +306,8 @@ func (h *hostinfo) getCerts(timeout time.Duration) error { } func CertInfo(host string, port string, timeout time.Duration) (commonName string, dnsNames []string, err error) { - port_int,err := strconv.Atoi(port) - if err != nil{ + port_int, err := strconv.Atoi(port) + if err != nil { return commonName, dnsNames, err } info := hostinfo{Host: host, Port: port_int} @@ -331,20 +323,20 @@ func CertInfo(host string, port string, timeout time.Duration) (commonName strin return commonName, dnsNames, errors.New("not found") } -func GetCert(domain string, port int)(string,error){ - var CN string - var DN []string - var ret string - var err error - if port > 0 { - CN, DN, err = CertInfo(domain, strconv.Itoa(port), 5*time.Second) - }else{ - CN, DN, err = CertInfo(domain, "443", 5*time.Second) - } - ret = "CommonName:"+CN+"; " - if len(DN)>0 { - ret = ret + "DNSName:" - ret = ret + DN[0] - } - return ret,err +func GetCert(domain string, port int) (string, error) { + var CN string + var DN []string + var ret string + var err error + if port > 0 { + CN, DN, err = CertInfo(domain, strconv.Itoa(port), 5*time.Second) + } else { + CN, DN, err = CertInfo(domain, "443", 5*time.Second) + } + ret = "CommonName:" + CN + "; " + if len(DN) > 0 { + ret = ret + "DNSName:" + ret = ret + DN[0] + } + return ret, err } diff --git a/pkg/Ginfo/Gnbtscan/Gnbtscan.go b/pkg/Ginfo/Gnbtscan/Gnbtscan.go new file mode 100644 index 0000000..0074235 --- /dev/null +++ b/pkg/Ginfo/Gnbtscan/Gnbtscan.go @@ -0,0 +1,73 @@ +package Gnbtscan + +import ( + "bytes" + "fmt" + "net" + "time" +) + +func Scan(ip string) (string, error) { + payload := []byte{ + // see https://blog.skullsecurity.org/2009/nbstatnse-a-replacement-for-nbtscan-and-others + 0x13, 0x37, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, + 0x00, 0x00, 0x21, 0x00, 0x01, + } + + conn, err := net.Dial("udp", fmt.Sprintf("%s:137", ip)) + if err != nil { + return "", err + } + defer conn.Close() + + conn.SetDeadline(time.Now().Add(2 * time.Second)) + if _, err := conn.Write(payload); err != nil { + return "", err + } + + buffer := make([]byte, 256) + bufferLen, err := conn.Read(buffer) + if err != nil { + return "", err + } + + if bufferLen < 12 { + return "", fmt.Errorf("invalid header") + } + + body := buffer[:bufferLen] + if body[6] == byte(0x00) && body[7] == byte(0x00) { + return "", fmt.Errorf("no answer to our request") + } + + body = body[12:] // remove header + offset := 0 + for body[offset] != 0 { + offset++ + if offset == len(body) { + return "", fmt.Errorf("invalid payload") + } + } + + body = body[offset+1:] + if len(body) < 12 { + return "", fmt.Errorf("no answer to our request") + } + + nameCnt := body[10] + if nameCnt == 0 { + return "", fmt.Errorf("no names available") + } + + offset = 0 + names := body[11:] + for names[offset] != 0 { + offset++ + if offset == len(names) { + break + } + } + return string(bytes.TrimSpace(names[:offset])), nil +} diff --git a/pkg/Ginfo/Gnbtscan/Gnbtscan_test.go b/pkg/Ginfo/Gnbtscan/Gnbtscan_test.go new file mode 100644 index 0000000..817538f --- /dev/null +++ b/pkg/Ginfo/Gnbtscan/Gnbtscan_test.go @@ -0,0 +1,26 @@ +package Gnbtscan + +import ( + "fmt" + "sync" + "testing" +) + +func TestNbtscan(t *testing.T){ + ipList := make([]int,255) + wg := sync.WaitGroup{} + wg.Add(255) + for index := range ipList { + ip := fmt.Sprintf("192.168.120.%d",index) + go func(){ + result,err :=Scan(ip) + if err !=nil{ + //t.Log(err) + }else{ + t.Log(fmt.Sprintf("%s -> %s",ip,result)) + } + wg.Done() + }() + } + wg.Wait() +} diff --git a/pkg/output/format_screen.go b/pkg/output/format_screen.go index 1e6b581..b4663d6 100644 --- a/pkg/output/format_screen.go +++ b/pkg/output/format_screen.go @@ -5,37 +5,43 @@ import ( "github.com/4dogs-cn/TXPortMap/pkg/Ginfo/Ghttp" "github.com/4dogs-cn/TXPortMap/pkg/conversion" "github.com/fatih/color" + "strings" ) // formatScreen formats the output for showing on screen. func (w *StandardWriter) formatScreen(output *ResultEvent) []byte { builder := &bytes.Buffer{} - builder.WriteRune('[') - builder.WriteString(color.CyanString(output.Time.Format("2006-01-02 15:04:05"))) - builder.WriteString("] ") - builder.WriteRune('[') builder.WriteString(color.RedString(output.Target)) - builder.WriteString("] ") - builder.WriteRune('[') + builder.WriteString(" ") builder.WriteString(color.YellowString(output.Info.Service)) - builder.WriteString("] ") if output.Info.Service == "ssl/tls" || output.Info.Service == "http"{ - builder.WriteRune('[') - builder.WriteString(color.YellowString(output.Info.Cert)) - builder.WriteString("] ") + if len(output.Info.Cert) > 0 { + builder.WriteString(" [") + builder.WriteString(color.YellowString(output.Info.Cert)) + builder.WriteString("]") + } } if output.WorkingEvent != nil{ switch tmp := output.WorkingEvent.(type) { case Ghttp.Result: - builder.WriteString(tmp.ToString()) + httpBanner := tmp.ToString() + if len(httpBanner)>0 { + builder.WriteString(" | ") + builder.WriteString(httpBanner) + } default: - builder.WriteString(conversion.ToString(tmp)) + result := conversion.ToString(tmp) + if strings.HasPrefix(result,"\\x") == false && len(result)>0 { + builder.WriteString(" | ") + builder.WriteString(result) + } } }else{ - builder.WriteRune('[') - builder.WriteString(color.GreenString(output.Info.Banner)) - builder.WriteString("] ") + if strings.HasPrefix(output.Info.Banner, "\\x") == false && len(output.Info.Banner)>0{ + builder.WriteString(" | ") + builder.WriteString(color.GreenString(output.Info.Banner)) + } } return builder.Bytes() }