package portScan
import (
"context"
"github.com/GhostTroops/scan4all/lib/goSqlite_gorm/lib/scan/Const"
"github.com/GhostTroops/scan4all/lib/goSqlite_gorm/pkg/models"
"github.com/GhostTroops/scan4all/lib/util"
"github.com/Ullaakut/nmap"
"io"
"log"
"time"
)
func init() {
util.RegInitFunc(func() {
util.EngineFuncFactory(Const.ScanType_Nmap, func(evt *models.EventData, args ...interface{}) {
var Targets []string = args[0].([]string)
var Ports []string = args[1].([]string)
x1 := &Scanner{Targets: Targets, Ports: Ports}
var streams []*Stream
_, err := x1.Scan(func(s *Stream) {
streams = append(streams, s)
})
if nil != err {
log.Println("nmap scan is error ", err)
}
util.SendEngineLog(evt, Const.ScanType_Nmap, streams)
})
})
}
type Stream struct {
Device string `json:"device"`
Username string `json:"username"`
Password string `json:"password"`
Routes []string `json:"route"`
Address string `json:"address" validate:"required"`
Port uint16 `json:"port" validate:"required"`
CredentialsFound bool `json:"credentials_found"`
RouteFound bool `json:"route_found"`
Available bool `json:"available"`
AuthenticationType int `json:"authentication_type"`
Service *nmap.Service
}
type Scanner struct {
Targets []string
Ports []string
}
func (s *Scanner) Scan(fnCbk func(*Stream)) ([]*Stream, error) {
log.Println("Scanning the network")
ctx, cancel := context.WithTimeout(context.Background(), 1800*time.Minute)
defer cancel()
var nmapScanner *nmap.Scanner
var err error
nmapScanner, err = nmap.NewScanner(
nmap.WithBinaryPath(util.GetVal("nmapScan")),
nmap.WithServiceInfo(),
nmap.WithMinRate(5000),
nmap.WithVersionIntensity(9),
nmap.WithDisabledDNSResolution(),
nmap.WithMinHostgroup(64),
nmap.WithMaxRetries(0),
nmap.WithHostTimeout(10),
nmap.WithPorts(s.Ports...),
nmap.WithTimingTemplate(nmap.Timing(4)),
nmap.WithTargets(s.Targets...),
nmap.WithContext(ctx),
)
if err != nil {
return nil, err
}
return s.scan(nmapScanner, fnCbk)
}
func (s *Scanner) scan(nmapScanner *nmap.Scanner, fnCbk func(*Stream)) ([]*Stream, error) {
err := nmapScanner.RunAsync()
if err != nil {
return nil, err
}
var streams []*Stream
x3 := nmapScanner.GetStderr()
go io.Copy(io.Discard, util.ScannerToReader(&x3))
scanner1 := nmapScanner.GetStdout()
for scanner1.Scan() {
s091 := scanner1.Text()
if r09, err := nmap.Parse([]byte(s091)); nil == err {
for _, host := range r09.Hosts {
if len(host.Ports) == 0 || len(host.Addresses) == 0 {
continue
}
for _, port := range host.Ports {
if port.Status() != "open" {
continue
}
for _, address := range host.Addresses {
sts := &Stream{
Device: port.Service.Product,
Address: address.Addr,
Port: port.ID,
Service: &port.Service,
}
if nil != fnCbk {
fnCbk(sts)
}
streams = append(streams, sts)
}
}
}
} else {
}
}
log.Printf("Found %d Real Time Streaming Protocol (RTSP)\n", len(streams))
return streams, nil
}