zgrab2/processing.go

138 lines
3.1 KiB
Go
Raw Normal View History

package zgrab2
2017-07-14 20:44:36 +00:00
import (
2017-08-04 20:20:32 +00:00
"bufio"
2017-07-14 20:44:36 +00:00
"encoding/json"
"io"
2017-08-04 20:20:32 +00:00
"net"
2017-09-26 18:15:15 +00:00
"strings"
2017-07-14 20:44:36 +00:00
"sync"
log "github.com/sirupsen/logrus"
2017-07-14 20:44:36 +00:00
)
2017-10-04 03:57:56 +00:00
// Grab contains all scan responses for a single host
type Grab struct {
2017-09-26 18:02:27 +00:00
IP string `json:"ip,omitempty"`
Domain string `json:"domain,omitempty"`
Data map[string]ScanResponse `json:"data,omitempty"`
2017-07-14 20:44:36 +00:00
}
2017-10-04 03:57:56 +00:00
// ScanTarget is the host that will be scanned
2017-09-26 18:02:27 +00:00
type ScanTarget struct {
2017-08-04 20:20:32 +00:00
IP net.IP
Domain string
}
2017-10-04 03:57:56 +00:00
// ScanResponse is the result of a scan on a single host
2017-09-26 18:02:27 +00:00
type ScanResponse struct {
Result interface{} `json:"result,omitempty"`
Time string `json:"time,omitempty"`
Error *error `json:"error,omitempty"`
ErrorComponent string `json:"error_component,omitempty"`
2017-07-14 20:44:36 +00:00
}
2017-08-30 19:39:25 +00:00
// grabTarget calls handler for each action
2017-09-26 18:02:27 +00:00
func grabTarget(input ScanTarget, m *Monitor) []byte {
moduleResult := make(map[string]ScanResponse)
2017-09-26 18:02:27 +00:00
for _, scannerName := range orderedScanners {
scanner := scanners[scannerName]
name, res := RunModule(*scanner, m, input)
2017-08-09 20:13:18 +00:00
moduleResult[name] = res
if res.Error != nil && !config.Multiple.ContinueOnError {
break
2017-07-14 20:44:36 +00:00
}
}
2017-08-30 19:39:25 +00:00
var ipstr string
if input.IP == nil {
ipstr = ""
2017-08-04 20:20:32 +00:00
} else {
s := input.IP.String()
2017-08-30 19:39:25 +00:00
ipstr = s
2017-08-04 20:20:32 +00:00
}
2017-08-09 20:13:18 +00:00
a := Grab{IP: ipstr, Domain: input.Domain, Data: moduleResult}
2017-08-04 20:20:32 +00:00
result, err := json.Marshal(a)
if err != nil {
2017-08-30 19:39:25 +00:00
log.Fatalf("unable to marshal data: %s", err)
2017-08-04 20:20:32 +00:00
}
2017-07-14 20:44:36 +00:00
return result
}
// Process sets up an output encoder, input reader, and starts grab workers
func Process(mon *Monitor) {
workers := config.Senders
2017-09-26 18:02:27 +00:00
processQueue := make(chan ScanTarget, workers*4)
outputQueue := make(chan []byte, workers*4)
2017-07-14 20:44:36 +00:00
//Create wait groups
var workerDone sync.WaitGroup
var outputDone sync.WaitGroup
workerDone.Add(int(workers))
outputDone.Add(1)
// Start the output encoder
go func() {
out := bufio.NewWriter(config.outputFile)
defer outputDone.Done()
defer out.Flush()
2017-07-14 20:44:36 +00:00
for result := range outputQueue {
if _, err := out.Write(result); err != nil {
log.Fatal(err)
2017-07-14 20:44:36 +00:00
}
if err := out.WriteByte('\n'); err != nil {
log.Fatal(err)
2017-07-14 20:44:36 +00:00
}
}
}()
//Start all the workers
for i := 0; i < workers; i++ {
2017-07-14 20:44:36 +00:00
go func() {
for obj := range processQueue {
2017-09-05 02:31:44 +00:00
for run := uint(0); run < uint(config.ConnectionsPerHost); run++ {
2017-09-04 22:44:58 +00:00
result := grabTarget(obj, mon)
outputQueue <- result
}
2017-07-14 20:44:36 +00:00
}
workerDone.Done()
}()
}
// Read the input, send to workers
2017-08-04 20:20:32 +00:00
input := bufio.NewReader(config.inputFile)
2017-07-14 20:44:36 +00:00
for {
2017-08-04 20:20:32 +00:00
obj, err := input.ReadBytes('\n')
if err == io.EOF {
break
} else if err != nil {
log.Error(err)
}
2017-09-26 18:15:15 +00:00
st := strings.TrimSpace(string(obj))
ipnet, domain, err := ParseTarget(st)
2017-08-04 20:20:32 +00:00
if err != nil {
log.Error(err)
continue
}
2017-09-03 03:14:33 +00:00
var ip net.IP
if ipnet != nil {
2017-09-03 03:14:33 +00:00
if ipnet.Mask != nil {
for ip = ipnet.IP.Mask(ipnet.Mask); ipnet.Contains(ip); incrementIP(ip) {
2017-09-26 18:02:27 +00:00
processQueue <- ScanTarget{IP: duplicateIP(ip), Domain: domain}
2017-09-03 03:14:33 +00:00
}
continue
} else {
ip = ipnet.IP
2017-08-04 20:20:32 +00:00
}
2017-07-14 20:44:36 +00:00
}
2017-09-26 18:02:27 +00:00
processQueue <- ScanTarget{IP: ip, Domain: domain}
2017-07-14 20:44:36 +00:00
}
close(processQueue)
workerDone.Wait()
close(outputQueue)
outputDone.Wait()
}