diff --git a/modules/syn_scan/banner_grabbing.go b/modules/syn_scan/banner_grabbing.go index db96343b..9ff219f7 100644 --- a/modules/syn_scan/banner_grabbing.go +++ b/modules/syn_scan/banner_grabbing.go @@ -1,6 +1,7 @@ package syn_scan import ( + "fmt" "github.com/bettercap/bettercap/network" "github.com/evilsocket/islazy/async" @@ -13,13 +14,6 @@ type grabberJob struct { Port *OpenPort } -var tcpBannerGrabbers = map[int]bannerGrabberFn{ - 80: httpGrabber, - 8080: httpGrabber, - 443: httpGrabber, - 8443: httpGrabber, -} - func (mod *SynScanner) bannerGrabber(arg async.Job) { job := arg.(grabberJob) if job.Port.Proto != "tcp" { @@ -28,9 +22,11 @@ func (mod *SynScanner) bannerGrabber(arg async.Job) { ip := job.Host.IpAddress port := job.Port.Port - fn, found := tcpBannerGrabbers[port] - if !found { - fn = tcpGrabber + sport := fmt.Sprintf("%d", port) + + fn := tcpGrabber + if port == 80 || port == 443 || sport[0] == '8' { + fn = httpGrabber } mod.Debug("grabbing banner for %s:%d", ip, port) diff --git a/modules/syn_scan/http_grabber.go b/modules/syn_scan/http_grabber.go index 5eaa1291..d1cf5aa5 100644 --- a/modules/syn_scan/http_grabber.go +++ b/modules/syn_scan/http_grabber.go @@ -38,7 +38,8 @@ func httpGrabber(mod *SynScanner, ip string, port int) string { }, } - if port == 443 || port == 8443 { + sport := fmt.Sprintf("%d", port) + if strings.Contains(sport, "443") { schema = "https" client = &http.Client{ Timeout: timeout, diff --git a/modules/syn_scan/syn_scan.go b/modules/syn_scan/syn_scan.go index 4bf447f3..0033e650 100644 --- a/modules/syn_scan/syn_scan.go +++ b/modules/syn_scan/syn_scan.go @@ -36,6 +36,7 @@ type SynScanner struct { progressEvery time.Duration stats synScannerStats waitGroup *sync.WaitGroup + scanQueue *async.WorkQueue bannerQueue *async.WorkQueue } @@ -47,7 +48,9 @@ func NewSynScanner(s *session.Session) *SynScanner { progressEvery: time.Duration(1) * time.Second, } + mod.scanQueue = async.NewQueue(0, mod.scanWorker) mod.bannerQueue = async.NewQueue(4, mod.bannerGrabber) + mod.State.Store("scanning", &mod.addresses) mod.State.Store("progress", 0.0) @@ -184,6 +187,37 @@ func (mod *SynScanner) Stop() error { }) } +type scanJob struct { + Address net.IP + Mac net.HardwareAddr +} + +func (mod *SynScanner) scanWorker(job async.Job) { + scan := job.(scanJob) + + for dstPort := mod.startPort; dstPort < mod.endPort+1; dstPort++ { + if !mod.Running() { + break + } + + atomic.AddUint64(&mod.stats.doneProbes, 1) + + err, raw := packets.NewTCPSyn(mod.Session.Interface.IP, mod.Session.Interface.HW, scan.Address, scan.Mac, synSourcePort, dstPort) + if err != nil { + mod.Error("error creating SYN packet: %s", err) + continue + } + + if err := mod.Session.Queue.Send(raw); err != nil { + mod.Error("error sending SYN packet: %s", err) + } else { + mod.Debug("sent %d bytes of SYN packet to %s for port %d", len(raw), scan.Address.String(), dstPort) + } + + time.Sleep(time.Duration(15) * time.Millisecond) + } +} + func (mod *SynScanner) synScan() error { mod.SetRunning(true, func() { defer mod.SetRunning(false, func() { @@ -241,28 +275,13 @@ func (mod *SynScanner) synScan() error { continue } - for dstPort := mod.startPort; dstPort < mod.endPort+1; dstPort++ { - if !mod.Running() { - break - } - - atomic.AddUint64(&mod.stats.doneProbes, 1) - - err, raw := packets.NewTCPSyn(mod.Session.Interface.IP, mod.Session.Interface.HW, address, mac, synSourcePort, dstPort) - if err != nil { - mod.Error("error creating SYN packet: %s", err) - continue - } - - if err := mod.Session.Queue.Send(raw); err != nil { - mod.Error("error sending SYN packet: %s", err) - } else { - mod.Debug("sent %d bytes of SYN packet to %s for port %d", len(raw), address.String(), dstPort) - } - - time.Sleep(time.Duration(25) * time.Millisecond) - } + mod.scanQueue.Add(async.Job(scanJob{ + Address: address, + Mac: mac, + })) } + + mod.scanQueue.WaitDone() }) return nil diff --git a/modules/syn_scan/tcp_grabber.go b/modules/syn_scan/tcp_grabber.go index 965e80aa..598361b8 100644 --- a/modules/syn_scan/tcp_grabber.go +++ b/modules/syn_scan/tcp_grabber.go @@ -4,15 +4,25 @@ import ( "bufio" "fmt" "net" + "strconv" "strings" ) +func cleanBanner(banner string) string { + clean := "" + for _, c := range banner { + if strconv.IsPrint(c) { + clean += string(c) + } + } + return clean +} + func tcpGrabber(mod *SynScanner, ip string, port int) string { if conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", ip, port)); err == nil { defer conn.Close() msg, _ := bufio.NewReader(conn).ReadString('\n') - return strings.Trim(msg, "\r\n\t ") + return cleanBanner(strings.Trim(msg, "\r\n\t ")) } - return "" }