Skip to content

Commit

Permalink
Add Description() to ScanModule (zmap#248)
Browse files Browse the repository at this point in the history
This abstracts more of the help text into the ScanModule definition,
removing some more of the need for `zgrab2.AddCommand()`

zmap#248
  • Loading branch information
dadrian authored and AnthraX1 committed Jul 21, 2020
1 parent 8084b4f commit b1f8352
Show file tree
Hide file tree
Showing 24 changed files with 213 additions and 87 deletions.
4 changes: 4 additions & 0 deletions module.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ type ScanModule interface {
// NewScanner is called by the framework for each time an individual scan is specified in the config or on
// the command-line. The framework will then call scanner.Init(name, flags).
NewScanner() Scanner

// Description returns a string suitable for use as an overview of this
// module within usage text.
Description() string
}

// ScanFlags is an interface which must be implemented by all types sent to
Expand Down
7 changes: 6 additions & 1 deletion modules/bacnet/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ type Scanner struct {
// RegisterModule registers the zgrab2 module.
func RegisterModule() {
var module Module
_, err := zgrab2.AddCommand("bacnet", "bacnet", "Probe for bacnet", 0xBAC0, &module)
_, err := zgrab2.AddCommand("bacnet", "bacnet", module.Description(), 0xBAC0, &module)
if err != nil {
log.Fatal(err)
}
Expand All @@ -48,6 +48,11 @@ func (module *Module) NewScanner() zgrab2.Scanner {
return new(Scanner)
}

// Description returns text uses in the help for this module.
func (module *Module) Description() string {
return "Probe for devices that speak Bacnet, commonly used for HVAC control."
}

// Validate checks that the flags are valid.
// On success, returns nil.
// On failure, returns an error instance describing the error.
Expand Down
7 changes: 6 additions & 1 deletion modules/banner/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ type Results struct {
// RegisterModule is called by modules/banner.go to register the scanner.
func RegisterModule() {
var module Module
_, err := zgrab2.AddCommand("banner", "Banner", "Grab banner by sending probe and match with regexp", 80, &module)
_, err := zgrab2.AddCommand("banner", "Banner", module.Description(), 80, &module)
if err != nil {
log.Fatal(err)
}
Expand Down Expand Up @@ -83,6 +83,11 @@ func (f *Flags) Validate(args []string) error {
return nil
}

// Description returns an overview of this module.
func (module *Module) Description() string {
return "Fetch a raw banner by sending a static probe and checking the result against a regular expression"
}

// Help returns the module's help string.
func (f *Flags) Help() string {
return ""
Expand Down
7 changes: 6 additions & 1 deletion modules/dnp3/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type Scanner struct {
// RegisterModule registers the zgrab2 module.
func RegisterModule() {
var module Module
_, err := zgrab2.AddCommand("dnp3", "dnp3", "Probe for dnp3", 20000, &module)
_, err := zgrab2.AddCommand("dnp3", "dnp3", module.Description(), 20000, &module)
if err != nil {
log.Fatal(err)
}
Expand All @@ -46,6 +46,11 @@ func (module *Module) NewScanner() zgrab2.Scanner {
return new(Scanner)
}

// Description returns an overview of this module.
func (module *Module) Description() string {
return "Probe for DNP3, a SCADA protocol"
}

// Validate checks that the flags are valid.
// On success, returns nil.
// On failure, returns an error instance describing the error.
Expand Down
7 changes: 6 additions & 1 deletion modules/fox/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type Scanner struct {
// RegisterModule registers the zgrab2 module.
func RegisterModule() {
var module Module
_, err := zgrab2.AddCommand("fox", "fox", "Probe for Tridium Fox", 1911, &module)
_, err := zgrab2.AddCommand("fox", "fox", module.Description(), 1911, &module)
if err != nil {
log.Fatal(err)
}
Expand All @@ -46,6 +46,11 @@ func (module *Module) NewScanner() zgrab2.Scanner {
return new(Scanner)
}

// Description returns an overview of this module.
func (module *Module) Description() string {
return "Probe for Tridium Fox"
}

// Validate checks that the flags are valid.
// On success, returns nil.
// On failure, returns an error instance describing the error.
Expand Down
7 changes: 6 additions & 1 deletion modules/ftp/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ type Connection struct {
// RegisterModule registers the ftp zgrab2 module.
func RegisterModule() {
var module Module
_, err := zgrab2.AddCommand("ftp", "FTP", "Grab an FTP banner", 21, &module)
_, err := zgrab2.AddCommand("ftp", "FTP", module.Description(), 21, &module)
if err != nil {
log.Fatal(err)
}
Expand All @@ -88,6 +88,11 @@ func (m *Module) NewScanner() zgrab2.Scanner {
return new(Scanner)
}

// Description returns an overview of this module.
func (m *Module) Description() string {
return "Grab an FTP banner"
}

// Validate does nothing in this module.
func (f *Flags) Validate(args []string) error {
return nil
Expand Down
7 changes: 6 additions & 1 deletion modules/http/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ func (module *Module) NewScanner() zgrab2.Scanner {
return new(Scanner)
}

// Description returns an overview of this module.
func (module *Module) Description() string {
return "Send an HTTP request and read the response, optionally following redirects."
}

// Validate performs any needed validation on the arguments
func (flags *Flags) Validate(args []string) error {
return nil
Expand Down Expand Up @@ -401,7 +406,7 @@ func (scanner *Scanner) Scan(t zgrab2.ScanTarget) (zgrab2.ScanStatus, interface{
func RegisterModule() {
var module Module

_, err := zgrab2.AddCommand("http", "HTTP Banner Grab", "Grab a banner over HTTP", 80, &module)
_, err := zgrab2.AddCommand("http", "HTTP Banner Grab", module.Description(), 80, &module)
if err != nil {
log.Fatal(err)
}
Expand Down
10 changes: 8 additions & 2 deletions modules/imap/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ package imap
import (
"fmt"

"strings"

log "github.com/sirupsen/logrus"
"github.com/zmap/zgrab2"
"strings"
)

// ScanResults instances are returned by the module's Scan function.
Expand Down Expand Up @@ -76,7 +77,7 @@ type Scanner struct {
// RegisterModule registers the zgrab2 module.
func RegisterModule() {
var module Module
_, err := zgrab2.AddCommand("imap", "imap", "Probe for IMAP", 143, &module)
_, err := zgrab2.AddCommand("imap", "imap", module.Description(), 143, &module)
if err != nil {
log.Fatal(err)
}
Expand All @@ -92,6 +93,11 @@ func (module *Module) NewScanner() zgrab2.Scanner {
return new(Scanner)
}

// Description returns an overview of this module.
func (module *Module) Description() string {
return "Fetch an IMAP banner, optionally over TLS"
}

// Validate checks that the flags are valid.
// On success, returns nil.
// On failure, returns an error instance describing the error.
Expand Down
36 changes: 21 additions & 15 deletions modules/ipp/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"crypto/sha256"
"encoding/binary"
"errors"

//"fmt"
"io"
"io/ioutil"
Expand Down Expand Up @@ -40,7 +41,7 @@ var (
// TODO: Explain this error
ErrVersionNotSupported = errors.New("IPP version not supported")

Versions = []version{{Major: 2, Minor: 1}, {Major: 2, Minor: 0}, {Major: 1, Minor: 1}, {Major: 1, Minor: 0}}
Versions = []version{{Major: 2, Minor: 1}, {Major: 2, Minor: 0}, {Major: 1, Minor: 1}, {Major: 1, Minor: 0}}
AttributesCharset = []byte{0x47, 0x00, 0x12, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2d, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74}
)

Expand Down Expand Up @@ -70,9 +71,9 @@ type ScanResults struct {
CUPSVersion string `json:"cups_version,omitempty"`

Attributes []*Attribute `json:"attributes,omitempty"`
AttributeCUPSVersion string `json:"attr_cups_version,omitempty"`
AttributeIPPVersions []string `json:"attr_ipp_versions,omitempty"`
AttributePrinterURIs []string `json:"attr_printer_uris,omitempty"`
AttributeCUPSVersion string `json:"attr_cups_version,omitempty"`
AttributeIPPVersions []string `json:"attr_ipp_versions,omitempty"`
AttributePrinterURIs []string `json:"attr_printer_uris,omitempty"`

TLSLog *zgrab2.TLSLog `json:"tls,omitempty"`
}
Expand Down Expand Up @@ -117,7 +118,7 @@ type Scanner struct {
// RegisterModule registers the zgrab2 module.
func RegisterModule() {
var module Module
_, err := zgrab2.AddCommand("ipp", "ipp", "Probe for ipp", 631, &module)
_, err := zgrab2.AddCommand("ipp", "ipp", module.Description(), 631, &module)
if err != nil {
log.Fatal(err)
}
Expand All @@ -133,6 +134,11 @@ func (module *Module) NewScanner() zgrab2.Scanner {
return new(Scanner)
}

// Description returns an overview of this module.
func (module *Module) Description() string {
return "Probe for printers via IPP"
}

// Validate checks that the flags are valid.
// On success, returns nil.
// On failure, returns an error instance describing the error.
Expand Down Expand Up @@ -206,13 +212,13 @@ type Value struct {
}

type Attribute struct {
Name string `json:"name,omitempty"`
Values []Value `json:"values,omitempty"`
ValueTag byte `json:"tag,omitempty"`
Name string `json:"name,omitempty"`
Values []Value `json:"values,omitempty"`
ValueTag byte `json:"tag,omitempty"`
}

func shouldReturnAttrs(length, soFar, size, upperBound int) (bool, error) {
if soFar + length > size {
if soFar+length > size {
// Size should never exceed upperBound in practice because of truncation, but this is more general
if size >= upperBound {
return true, nil
Expand Down Expand Up @@ -260,9 +266,9 @@ func readAllAttributes(body []byte, scanner *Scanner) ([]*Attribute, error) {
buf := bytes.NewBuffer(body)
// Each field of this struct is exported to avoid binary.Read panicking
var start struct {
Version int16
Version int16
StatusCode int16
ReqID int32
ReqID int32
}
// Read in pre-attribute part of body to ignore it
if err := binary.Read(buf, binary.BigEndian, &start); err != nil {
Expand Down Expand Up @@ -299,7 +305,7 @@ func readAllAttributes(body []byte, scanner *Scanner) ([]*Attribute, error) {
}
bytesRead += 2
// If reading the name would entail reading past body, check whether body was truncated
if should, err := shouldReturnAttrs(int(nameLength), bytesRead, len(body), scanner.config.MaxSize * 1024); should {
if should, err := shouldReturnAttrs(int(nameLength), bytesRead, len(body), scanner.config.MaxSize*1024); should {
// If body was truncated, return all attributes so far without error
// Otherwise, return a protocol error because name-length should indicate the
// length of the following name when obeying the protocol's encoding
Expand All @@ -311,7 +317,7 @@ func readAllAttributes(body []byte, scanner *Scanner) ([]*Attribute, error) {
// an additional value for the former, so we read and append another value for that attr
if tag == lastTag && nameLength == 0 {
attr = attrs[len(attrs)-1]
// Otherwise, create a new attribute and read in its name
// Otherwise, create a new attribute and read in its name
} else {
attr = &Attribute{ValueTag: tag}
attrs = append(attrs, attr)
Expand All @@ -332,7 +338,7 @@ func readAllAttributes(body []byte, scanner *Scanner) ([]*Attribute, error) {
}
bytesRead += 2
// If reading the name would entail reading past body, check whether body was truncated
if should, err := shouldReturnAttrs(int(length), bytesRead, len(body), scanner.config.MaxSize * 1024); should {
if should, err := shouldReturnAttrs(int(length), bytesRead, len(body), scanner.config.MaxSize*1024); should {
// If body was truncated, return all attributes so far without error
// Otherwise, return a protocol error because name-length should indicate the
// length of the following name when obeying the protocol's encoding
Expand Down Expand Up @@ -366,7 +372,7 @@ func (scanner *Scanner) tryReadAttributes(resp *http.Response, scan *scan) *zgra
// Therefore, an HTTP Status Code other than 200 indicates the response is not a well-formed IPP response.
// RFC 8010 Section 3.4.3 Source: https://tools.ietf.org/html/rfc8010#section-3.4.3
if resp.StatusCode != 200 {
return zgrab2.NewScanError(zgrab2.SCAN_APPLICATION_ERROR, errors.New("Response returned with status " + resp.Status))
return zgrab2.NewScanError(zgrab2.SCAN_APPLICATION_ERROR, errors.New("Response returned with status "+resp.Status))
}

// Reject successful responses which specify non-IPP MIME mediatype (ie: text/html)
Expand Down
7 changes: 6 additions & 1 deletion modules/modbus/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ type Scanner struct {
// RegisterModule registers the zgrab2 module.
func RegisterModule() {
var module Module
_, err := zgrab2.AddCommand("modbus", "modbus", "Probe for modbus", 502, &module)
_, err := zgrab2.AddCommand("modbus", "modbus", module.Description(), 502, &module)
if err != nil {
log.Fatal(err)
}
Expand All @@ -68,6 +68,11 @@ func (module *Module) NewScanner() zgrab2.Scanner {
return new(Scanner)
}

// Description returns an overview of this module.
func (module *Module) Description() string {
return "Probe for Modbus devices, usually PLCs as part of a SCADA system"
}

// Validate checks that the flags are valid.
// On success, returns nil.
// On failure, returns an error instance describing the error.
Expand Down
Loading

0 comments on commit b1f8352

Please sign in to comment.