diff --git a/module.go b/module.go index 4b8010a..efce70c 100644 --- a/module.go +++ b/module.go @@ -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 diff --git a/modules/bacnet/scanner.go b/modules/bacnet/scanner.go index 586d293..23bc2be 100644 --- a/modules/bacnet/scanner.go +++ b/modules/bacnet/scanner.go @@ -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) } @@ -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. diff --git a/modules/banner/scanner.go b/modules/banner/scanner.go index a1af4a5..7418f41 100644 --- a/modules/banner/scanner.go +++ b/modules/banner/scanner.go @@ -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) } @@ -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 "" diff --git a/modules/dnp3/scanner.go b/modules/dnp3/scanner.go index 5d73fab..93ec535 100644 --- a/modules/dnp3/scanner.go +++ b/modules/dnp3/scanner.go @@ -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) } @@ -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. diff --git a/modules/fox/scanner.go b/modules/fox/scanner.go index b64630b..910aa40 100644 --- a/modules/fox/scanner.go +++ b/modules/fox/scanner.go @@ -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) } @@ -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. diff --git a/modules/ftp/scanner.go b/modules/ftp/scanner.go index 2070fca..f27be77 100644 --- a/modules/ftp/scanner.go +++ b/modules/ftp/scanner.go @@ -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) } @@ -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 diff --git a/modules/http/scanner.go b/modules/http/scanner.go index e8033a7..0025a40 100644 --- a/modules/http/scanner.go +++ b/modules/http/scanner.go @@ -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 @@ -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) } diff --git a/modules/imap/scanner.go b/modules/imap/scanner.go index 02c13c5..145e856 100644 --- a/modules/imap/scanner.go +++ b/modules/imap/scanner.go @@ -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. @@ -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) } @@ -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. diff --git a/modules/ipp/scanner.go b/modules/ipp/scanner.go index 9da9a39..d04825d 100644 --- a/modules/ipp/scanner.go +++ b/modules/ipp/scanner.go @@ -7,6 +7,7 @@ import ( "crypto/sha256" "encoding/binary" "errors" + //"fmt" "io" "io/ioutil" @@ -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} ) @@ -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"` } @@ -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) } @@ -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. @@ -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 @@ -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 { @@ -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 @@ -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) @@ -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 @@ -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) diff --git a/modules/modbus/scanner.go b/modules/modbus/scanner.go index cb8a023..2f7033e 100644 --- a/modules/modbus/scanner.go +++ b/modules/modbus/scanner.go @@ -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) } @@ -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. diff --git a/modules/mongodb/scanner.go b/modules/mongodb/scanner.go index 69d5b71..fef8750 100644 --- a/modules/mongodb/scanner.go +++ b/modules/mongodb/scanner.go @@ -1,11 +1,12 @@ package mongodb import ( - "fmt" - "encoding/hex" "encoding/binary" - "github.com/zmap/zgrab2" + "encoding/hex" + "fmt" + log "github.com/sirupsen/logrus" + "github.com/zmap/zgrab2" "gopkg.in/mgo.v2/bson" ) @@ -20,10 +21,10 @@ type Flags struct { // Scanner implements the zgrab2.Scanner interface type Scanner struct { - config *Flags - isMasterMsg []byte - buildInfoCommandMsg []byte - buildInfoOpMsg []byte + config *Flags + isMasterMsg []byte + buildInfoCommandMsg []byte + buildInfoOpMsg []byte } // scan holds the state for the scan of an individual target @@ -42,7 +43,7 @@ func (scan *scan) Close() { // getCommandMsg returns a mongodb message containing the specified BSON-encoded command. // metdata and commandArgs expected to be BSON byte arrays. -func getCommandMsg(database string, commandName string, metadata []byte, commandArgs []byte) ([]byte) { +func getCommandMsg(database string, commandName string, metadata []byte, commandArgs []byte) []byte { dblen := len(database) + 1 cnlen := len(commandName) + 1 mdlen := len(metadata) @@ -67,8 +68,8 @@ func getCommandMsg(database string, commandName string, metadata []byte, command // getIsMasterMsg returns a mongodb message containing isMaster command. // https://docs.mongodb.com/manual/reference/command/isMaster/ -func getIsMasterMsg() ([]byte) { - query, err := bson.Marshal(bson.M{ "isMaster": 1 }) +func getIsMasterMsg() []byte { + query, err := bson.Marshal(bson.M{"isMaster": 1}) if err != nil { // programmer error log.Fatalf("Invalid BSON: %v", err) @@ -78,8 +79,8 @@ func getIsMasterMsg() ([]byte) { } // getBuildInfoCommandMsg returns a mongodb message containing a command to retrieve MongoDB build info. -func getBuildInfoCommandMsg() ([]byte) { - metaData, err := bson.Marshal(bson.M{ "buildInfo": 1 }) +func getBuildInfoCommandMsg() []byte { + metaData, err := bson.Marshal(bson.M{"buildInfo": 1}) if err != nil { // programmer error log.Fatalf("Invalid BSON: %v", err) @@ -96,7 +97,7 @@ func getBuildInfoCommandMsg() ([]byte) { // getOpQuery returns a mongodb OP_QUERY message containing the specified BSON-encoded query. // query expected to be BSON byte array. -func getOpQuery(collname string, query []byte) ([]byte) { +func getOpQuery(collname string, query []byte) []byte { flagslen := 4 collname_len := len(collname) + 1 nskiplen := 4 @@ -119,7 +120,7 @@ func getOpQuery(collname string, query []byte) ([]byte) { // getOpMsg returns a mongodb OP_MSG message containing the specified BSON-encoded command. // section expected to be BSON byte array. -func getOpMsg(section []byte) ([]byte) { +func getOpMsg(section []byte) []byte { flagslen := 4 slen := len(section) msglen := MSGHEADER_LEN + flagslen + slen @@ -134,14 +135,14 @@ func getOpMsg(section []byte) ([]byte) { } // getBuildInfoOpMsg returns a mongodb "OP" message containing query to retrieve MongoDB build info. -func getBuildInfoOpMsg() ([]byte) { +func getBuildInfoOpMsg() []byte { // gleaned from tshark - section_payload, err := bson.Marshal(bson.M{ "buildinfo": 1, "$db": "admin" }) + section_payload, err := bson.Marshal(bson.M{"buildinfo": 1, "$db": "admin"}) if err != nil { // programmer error log.Fatalf("Invalid BSON: %v", err) } - section := make([]byte, len(section_payload) + 1) + section := make([]byte, len(section_payload)+1) copy(section[1:], section_payload) op_msg := getOpMsg(section) return op_msg @@ -149,39 +150,39 @@ func getBuildInfoOpMsg() ([]byte) { // BuildEnvironment_t holds build environment information returned by scan. type BuildEnvironment_t struct { - Distmod string `bson:"distmod,omitempty" json:"dist_mod,omitempty"` - Distarch string `bson:"distarch,omitempty" json:"dist_arch,omitempty"` - Cc string `bson:"cc,omitempty" json:"cc,omitempty"` - CcFlags string `bson:"ccflags,omitempty" json:"cc_flags,omitempty"` - Cxx string `bson:"cxx,omitempty" json:"cxx,omitempty"` - CxxFlags string `bson:"cxxflags,omitempty" json:"cxx_flags,omitempty"` - LinkFlags string `bson:"linkflags,omitempty" json:"link_flags,omitempty"` + Distmod string `bson:"distmod,omitempty" json:"dist_mod,omitempty"` + Distarch string `bson:"distarch,omitempty" json:"dist_arch,omitempty"` + Cc string `bson:"cc,omitempty" json:"cc,omitempty"` + CcFlags string `bson:"ccflags,omitempty" json:"cc_flags,omitempty"` + Cxx string `bson:"cxx,omitempty" json:"cxx,omitempty"` + CxxFlags string `bson:"cxxflags,omitempty" json:"cxx_flags,omitempty"` + LinkFlags string `bson:"linkflags,omitempty" json:"link_flags,omitempty"` TargetArch string `bson:"target_arch,omitempty" json:"target_arch,omitempty"` - TargetOS string `bson:"target_os,omitempty" json:"target_os,omitempty"` + TargetOS string `bson:"target_os,omitempty" json:"target_os,omitempty"` } // BuildInfo_t holds the data returned by the the buildInfo query type BuildInfo_t struct { - Version string `bson:"version,omitempty" json:"version,omitempty"` - GitVersion string `bson:"gitVersion,omitempty" json:"git_version,omitempty"` + Version string `bson:"version,omitempty" json:"version,omitempty"` + GitVersion string `bson:"gitVersion,omitempty" json:"git_version,omitempty"` BuildEnvironment BuildEnvironment_t `bson:"buildEnvironment,omitempty" json:"build_environment,omitempty"` } // IsMaster_t holds the data returned by an isMaster query type IsMaster_t struct { - IsMaster bool `bson:"ismaster" json:"is_master"` - MaxWireVersion int32 `bson:"maxWireVersion,omitempty" json:"max_wire_version,omitempty"` - MinWireVersion int32 `bson:"minWireVersion,omitempty" json:"min_wire_version,omitempty"` - MaxBsonObjectSize int32 `bson:"maxBsonObjectSize,omitempty" json:"max_bson_object_size,omitempty"` - MaxWriteBatchSize int32 `bson:"maxWriteBatchSize,omitempty" json:"max_write_batch_size,omitempty"` + IsMaster bool `bson:"ismaster" json:"is_master"` + MaxWireVersion int32 `bson:"maxWireVersion,omitempty" json:"max_wire_version,omitempty"` + MinWireVersion int32 `bson:"minWireVersion,omitempty" json:"min_wire_version,omitempty"` + MaxBsonObjectSize int32 `bson:"maxBsonObjectSize,omitempty" json:"max_bson_object_size,omitempty"` + MaxWriteBatchSize int32 `bson:"maxWriteBatchSize,omitempty" json:"max_write_batch_size,omitempty"` LogicalSessionTimeoutMinutes int32 `bson:"logicalSessionTimeoutMinutes,omitempty" json:"logical_session_timeout_minutes,omitempty"` - MaxMessageSizeBytes int32 `bson:"maxMessageSizeBytes,omitempty" json:"max_message_size_bytes,omitempty"` - ReadOnly bool `bson:"readOnly" json:"read_only"` + MaxMessageSizeBytes int32 `bson:"maxMessageSizeBytes,omitempty" json:"max_message_size_bytes,omitempty"` + ReadOnly bool `bson:"readOnly" json:"read_only"` } // Result holds the data returned by a scan type Result struct { - IsMaster *IsMaster_t `json:"is_master,omitempty"` + IsMaster *IsMaster_t `json:"is_master,omitempty"` BuildInfo *BuildInfo_t `json:"build_info,omitempty"` } @@ -235,6 +236,11 @@ func (module *Module) NewScanner() zgrab2.Scanner { return new(Scanner) } +// Description returns an overview of this module. +func (module *Module) Description() string { + return "Perform a handshake with a MongoDB server" +} + // StartScan opens a connection to the target and sets up a scan instance for it. func (scanner *Scanner) StartScan(target *zgrab2.ScanTarget) (*scan, error) { conn, err := target.Open(&scanner.config.BaseFlags) @@ -265,25 +271,25 @@ func getIsMaster(conn *Connection) (*IsMaster_t, error) { return nil, err } - if len(msg) < doc_offset + 4 { + if len(msg) < doc_offset+4 { err = fmt.Errorf("Server truncated message - no query reply (%d bytes: %s)", len(msg), hex.EncodeToString(msg)) return nil, err } - respFlags := binary.LittleEndian.Uint32(msg[MSGHEADER_LEN:MSGHEADER_LEN + 4]) - if respFlags & QUERY_RESP_FAILED != 0 { + respFlags := binary.LittleEndian.Uint32(msg[MSGHEADER_LEN : MSGHEADER_LEN+4]) + if respFlags&QUERY_RESP_FAILED != 0 { err = fmt.Errorf("isMaster query failed") return nil, err } - doclen := int(binary.LittleEndian.Uint32(msg[doc_offset:doc_offset + 4])) + doclen := int(binary.LittleEndian.Uint32(msg[doc_offset : doc_offset+4])) if len(msg[doc_offset:]) < doclen { err = fmt.Errorf("Server truncated BSON reply doc (%d bytes: %s)", - len(msg[doc_offset:]), hex.EncodeToString(msg)) + len(msg[doc_offset:]), hex.EncodeToString(msg)) return nil, err } err = bson.Unmarshal(msg[doc_offset:], &document) if err != nil { err = fmt.Errorf("Server sent invalid BSON reply doc (%d bytes: %s)", - len(msg[doc_offset:]), hex.EncodeToString(msg)) + len(msg[doc_offset:]), hex.EncodeToString(msg)) return nil, err } return document, nil @@ -309,7 +315,7 @@ func (scanner *Scanner) Scan(target zgrab2.ScanTarget) (zgrab2.ScanStatus, inter // Gleaned from wireshark - if "MaxWireVersion" is less than 7, then // "build info" command should be sent in an OP_COMMAND with the query sent - // and response retrieved at "metadata" offset. At 7 and above, should + // and response retrieved at "metadata" offset. At 7 and above, should // be sent as an OP_MSG in the "section" field, and response is at "body" offset if result.IsMaster.MaxWireVersion < 7 { query = scanner.buildInfoCommandMsg @@ -327,15 +333,15 @@ func (scanner *Scanner) Scan(target zgrab2.ScanTarget) (zgrab2.ScanStatus, inter return zgrab2.TryGetScanStatus(err), &result, err } - if len(msg) < MSGHEADER_LEN + resplen_offset { + if len(msg) < MSGHEADER_LEN+resplen_offset { err = fmt.Errorf("Server truncated message - no metadata doc (%d bytes: %s)", len(msg), hex.EncodeToString(msg)) return zgrab2.SCAN_PROTOCOL_ERROR, &result, err } - responselen := int(binary.LittleEndian.Uint32(msg[MSGHEADER_LEN:MSGHEADER_LEN + resplen_offset])) + responselen := int(binary.LittleEndian.Uint32(msg[MSGHEADER_LEN : MSGHEADER_LEN+resplen_offset])) if len(msg[MSGHEADER_LEN:]) < responselen { - err = fmt.Errorf("Server truncated BSON response doc (%d bytes: %s)", - len(msg[MSGHEADER_LEN:]), hex.EncodeToString(msg)) + err = fmt.Errorf("Server truncated BSON response doc (%d bytes: %s)", + len(msg[MSGHEADER_LEN:]), hex.EncodeToString(msg)) return zgrab2.SCAN_PROTOCOL_ERROR, &result, err } bson.Unmarshal(msg[MSGHEADER_LEN+resp_offset:], &result.BuildInfo) @@ -346,7 +352,7 @@ func (scanner *Scanner) Scan(target zgrab2.ScanTarget) (zgrab2.ScanStatus, inter // RegisterModule registers the zgrab2 module. func RegisterModule() { var module Module - _, err := zgrab2.AddCommand("mongodb", "mongodb", "Probe for mongodb", 27017, &module) + _, err := zgrab2.AddCommand("mongodb", "mongodb", module.Description(), 27017, &module) if err != nil { log.Fatal(err) } diff --git a/modules/mssql/scanner.go b/modules/mssql/scanner.go index db5f97f..708fa96 100644 --- a/modules/mssql/scanner.go +++ b/modules/mssql/scanner.go @@ -12,9 +12,10 @@ package mssql import ( + "strings" + log "github.com/sirupsen/logrus" "github.com/zmap/zgrab2" - "strings" ) // ScanResults contains detailed information about each step of the @@ -68,6 +69,11 @@ func (module *Module) NewScanner() zgrab2.Scanner { return new(Scanner) } +// Description returns an overview of this module. +func (module *Module) Description() string { + return "Perform a handshake for MSSQL databases" +} + // Validate does nothing in this module. func (flags *Flags) Validate(args []string) error { return nil @@ -172,7 +178,7 @@ func (scanner *Scanner) Scan(target zgrab2.ScanTarget) (zgrab2.ScanStatus, inter // RegisterModule is called by modules/mssql.go's init() func RegisterModule() { var module Module - _, err := zgrab2.AddCommand("mssql", "MSSQL", "Grab a mssql handshake", 1433, &module) + _, err := zgrab2.AddCommand("mssql", "MSSQL", module.Description(), 1433, &module) if err != nil { log.Fatal(err) } diff --git a/modules/mysql/scanner.go b/modules/mysql/scanner.go index fc8171c..6a45543 100644 --- a/modules/mysql/scanner.go +++ b/modules/mysql/scanner.go @@ -149,7 +149,7 @@ type Scanner struct { // RegisterModule is called by modules/mysql.go to register the scanner. func RegisterModule() { var module Module - _, err := zgrab2.AddCommand("mysql", "MySQL", "Grab a MySQL handshake", 3306, &module) + _, err := zgrab2.AddCommand("mysql", "MySQL", module.Description(), 3306, &module) if err != nil { log.Fatal(err) } @@ -165,6 +165,11 @@ func (m *Module) NewScanner() zgrab2.Scanner { return new(Scanner) } +// Description returns an overview of this module. +func (m *Module) Description() string { + return "Perform a handshake with a MySQL database" +} + // Validate validates the flags and returns nil on success. func (f *Flags) Validate(args []string) error { return nil diff --git a/modules/ntp/scanner.go b/modules/ntp/scanner.go index b52fafc..083af17 100644 --- a/modules/ntp/scanner.go +++ b/modules/ntp/scanner.go @@ -815,7 +815,7 @@ type Scanner struct { // RegisterModule registers the module with zgrab2 func RegisterModule() { var module Module - _, err := zgrab2.AddCommand("ntp", "NTP", "Scan for NTP", 123, &module) + _, err := zgrab2.AddCommand("ntp", "NTP", module.Description(), 123, &module) if err != nil { log.Fatal(err) } @@ -831,6 +831,11 @@ func (module *Module) NewScanner() zgrab2.Scanner { return new(Scanner) } +// Description returns an overview of this module. +func (module *Module) Description() string { + return "Scan for NTP" +} + // Validate checks that the flags are valid func (cfg *Flags) Validate(args []string) error { return nil diff --git a/modules/oracle/scanner.go b/modules/oracle/scanner.go index 1ab212d..752e512 100644 --- a/modules/oracle/scanner.go +++ b/modules/oracle/scanner.go @@ -106,7 +106,7 @@ type Scanner struct { // RegisterModule registers the zgrab2 module. func RegisterModule() { var module Module - _, err := zgrab2.AddCommand("oracle", "oracle", "Probe for oracle", 1521, &module) + _, err := zgrab2.AddCommand("oracle", "oracle", module.Description(), 1521, &module) if err != nil { log.Fatal(err) } @@ -122,6 +122,11 @@ func (module *Module) NewScanner() zgrab2.Scanner { return new(Scanner) } +// Description returns an overview of this module. +func (module *Module) Description() string { + return "Perform a handshake with Oracle database servers" +} + // Validate checks that the flags are valid. // On success, returns nil. // On failure, returns an error instance describing the error. diff --git a/modules/pop3/scanner.go b/modules/pop3/scanner.go index 47c9490..cd1ed26 100644 --- a/modules/pop3/scanner.go +++ b/modules/pop3/scanner.go @@ -28,9 +28,10 @@ package pop3 import ( "fmt" + "strings" + log "github.com/sirupsen/logrus" "github.com/zmap/zgrab2" - "strings" ) // ScanResults instances are returned by the module's Scan function. @@ -91,7 +92,7 @@ type Scanner struct { // RegisterModule registers the zgrab2 module. func RegisterModule() { var module Module - _, err := zgrab2.AddCommand("pop3", "pop3", "Probe for pop3", 110, &module) + _, err := zgrab2.AddCommand("pop3", "pop3", module.Description(), 110, &module) if err != nil { log.Fatal(err) } @@ -107,6 +108,11 @@ func (module *Module) NewScanner() zgrab2.Scanner { return new(Scanner) } +// Description returns an overview of this module. +func (module *Module) Description() string { + return "Fetch POP3 banners, optionally over TLS" +} + // Validate checks that the flags are valid. // On success, returns nil. // On failure, returns an error instance describing the error. diff --git a/modules/postgres/scanner.go b/modules/postgres/scanner.go index 783d84b..8e0beca 100644 --- a/modules/postgres/scanner.go +++ b/modules/postgres/scanner.go @@ -16,6 +16,7 @@ import ( "strings" "encoding/json" + log "github.com/sirupsen/logrus" "github.com/zmap/zgrab2" ) @@ -279,6 +280,11 @@ func (m *Module) NewScanner() zgrab2.Scanner { return new(Scanner) } +// Description returns an overview of this module. +func (m *Module) Description() string { + return "Perform a handshake with a PostgreSQL server" +} + // Validate checks the arguments; on success, returns nil. func (f *Flags) Validate(args []string) error { return nil @@ -533,7 +539,7 @@ func (s *Scanner) Scan(t zgrab2.ScanTarget) (status zgrab2.ScanStatus, result in // the postgres module with the zgrab2 framework. func RegisterModule() { var module Module - _, err := zgrab2.AddCommand("postgres", "Postgres", "Grab a Postgres handshake", 5432, &module) + _, err := zgrab2.AddCommand("postgres", "Postgres", module.Description(), 5432, &module) if err != nil { log.Fatal(err) } diff --git a/modules/redis/scanner.go b/modules/redis/scanner.go index d115f87..567576b 100644 --- a/modules/redis/scanner.go +++ b/modules/redis/scanner.go @@ -159,7 +159,7 @@ type Result struct { // RegisterModule registers the zgrab2 module func RegisterModule() { var module Module - _, err := zgrab2.AddCommand("redis", "redis", "Probe for redis", 6379, &module) + _, err := zgrab2.AddCommand("redis", "redis", module.Description(), 6379, &module) if err != nil { log.Fatal(err) } @@ -175,6 +175,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 Redis" +} + // Validate checks that the flags are valid func (flags *Flags) Validate(args []string) error { return nil diff --git a/modules/siemens/scanner.go b/modules/siemens/scanner.go index e4f4673..03112d0 100644 --- a/modules/siemens/scanner.go +++ b/modules/siemens/scanner.go @@ -4,9 +4,10 @@ package siemens import ( + "net" + log "github.com/sirupsen/logrus" "github.com/zmap/zgrab2" - "net" ) // Flags holds the command-line configuration for the siemens scan module. @@ -29,7 +30,7 @@ type Scanner struct { // RegisterModule registers the zgrab2 module. func RegisterModule() { var module Module - _, err := zgrab2.AddCommand("siemens", "siemens", "Probe for Siemens S7", 102, &module) + _, err := zgrab2.AddCommand("siemens", "siemens", module.Description(), 102, &module) if err != nil { log.Fatal(err) } @@ -45,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 Siemens S7 devices" +} + // Validate checks that the flags are valid. // On success, returns nil. // On failure, returns an error instance describing the error. diff --git a/modules/smb/scanner.go b/modules/smb/scanner.go index f0cf32b..851185b 100644 --- a/modules/smb/scanner.go +++ b/modules/smb/scanner.go @@ -32,7 +32,7 @@ type Scanner struct { // RegisterModule registers the zgrab2 module. func RegisterModule() { var module Module - _, err := zgrab2.AddCommand("smb", "smb", "Probe for smb", 445, &module) + _, err := zgrab2.AddCommand("smb", "smb", module.Description(), 445, &module) if err != nil { log.Fatal(err) } @@ -48,6 +48,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 SMB servers (Windows filesharing / SAMBA)" +} + // Validate checks that the flags are valid. // On success, returns nil. // On failure, returns an error instance describing the error. diff --git a/modules/smtp/scanner.go b/modules/smtp/scanner.go index 9ff5d7d..281c6f7 100644 --- a/modules/smtp/scanner.go +++ b/modules/smtp/scanner.go @@ -108,7 +108,7 @@ type Scanner struct { // RegisterModule registers the zgrab2 module. func RegisterModule() { var module Module - _, err := zgrab2.AddCommand("smtp", "smtp", "Probe for smtp", 25, &module) + _, err := zgrab2.AddCommand("smtp", "smtp", module.Description(), 25, &module) if err != nil { log.Fatal(err) } @@ -124,6 +124,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 SMTP server banner, optionally over TLS" +} + // Validate checks that the flags are valid. // On success, returns nil. // On failure, returns an error instance describing the error. diff --git a/modules/ssh.go b/modules/ssh.go index 860211b..5248c38 100644 --- a/modules/ssh.go +++ b/modules/ssh.go @@ -33,7 +33,7 @@ type SSHScanner struct { func init() { var sshModule SSHModule - cmd, err := zgrab2.AddCommand("ssh", "SSH Banner Grab", "Grab a banner over SSH", 22, &sshModule) + cmd, err := zgrab2.AddCommand("ssh", "SSH Banner Grab", sshModule.Description(), 22, &sshModule) if err != nil { log.Fatal(err) } @@ -51,6 +51,11 @@ func (m *SSHModule) NewScanner() zgrab2.Scanner { return new(SSHScanner) } +// Description returns an overview of this module. +func (m *SSHModule) Description() string { + return "Fetch an SSH server banner and collect key exchange information" +} + func (f *SSHFlags) Validate(args []string) error { return nil } diff --git a/modules/telnet/scanner.go b/modules/telnet/scanner.go index e427409..b5f68ee 100644 --- a/modules/telnet/scanner.go +++ b/modules/telnet/scanner.go @@ -36,7 +36,7 @@ type Scanner struct { // RegisterModule registers the zgrab2 module. func RegisterModule() { var module Module - _, err := zgrab2.AddCommand("telnet", "telnet", "Probe for telnet", 23, &module) + _, err := zgrab2.AddCommand("telnet", "telnet", module.Description(), 23, &module) if err != nil { log.Fatal(err) } @@ -52,6 +52,11 @@ func (module *Module) NewScanner() zgrab2.Scanner { return new(Scanner) } +// Description returns an overview of this module. +func (module *Module) Description() string { + return "Fetch a telnet banner" +} + // Validate checks that the flags are valid. // On success, returns nil. // On failure, returns an error instance describing the error. diff --git a/modules/tls.go b/modules/tls.go index 5dc6ccd..7f8c48d 100644 --- a/modules/tls.go +++ b/modules/tls.go @@ -19,7 +19,7 @@ type TLSScanner struct { func init() { var tlsModule TLSModule - _, err := zgrab2.AddCommand("tls", "TLS Banner Grab", "Grab banner over TLS", 443, &tlsModule) + _, err := zgrab2.AddCommand("tls", "TLS Banner Grab", tlsModule.Description(), 443, &tlsModule) if err != nil { log.Fatal(err) } @@ -33,6 +33,11 @@ func (m *TLSModule) NewScanner() zgrab2.Scanner { return new(TLSScanner) } +// Description returns an overview of this module. +func (m *TLSModule) Description() string { + return "Perform a TLS handshake" +} + func (f *TLSFlags) Validate(args []string) error { return nil }