From a38194a7fdf57073735ebe3df64f5354c1229e3b Mon Sep 17 00:00:00 2001 From: Jeff Cody Date: Wed, 21 Aug 2019 14:53:56 -0400 Subject: [PATCH 1/2] Add `port` to ScanTarget{} that overrides Config The port field is tied to the configuration of each instance of `Scanner` struct. However, applications using zgrab2 scan modules may want to specify specific ports to scan, without needing to initialize a whole new module. This patch adds a pointer to a uint describing a port to `ScanTarget{}`. If that is nil, the specified port will override the port in the Config. --- processing.go | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/processing.go b/processing.go index 64b6c40..30859fc 100644 --- a/processing.go +++ b/processing.go @@ -22,6 +22,7 @@ type ScanTarget struct { IP net.IP Domain string Tag string + Port *uint } func (target ScanTarget) String() string { @@ -56,7 +57,15 @@ func (target *ScanTarget) Host() string { // Open connects to the ScanTarget using the configured flags, and returns a net.Conn that uses the configured timeouts for Read/Write operations. func (target *ScanTarget) Open(flags *BaseFlags) (net.Conn, error) { - address := net.JoinHostPort(target.Host(), fmt.Sprintf("%d", flags.Port)) + var port uint + // If the port is supplied in ScanTarget, let that override the cmdline option + if target.Port != nil { + port = *target.Port + } else { + port = flags.Port + } + + address := net.JoinHostPort(target.Host(), fmt.Sprintf("%d", port)) return DialTimeoutConnection("tcp", address, flags.Timeout, flags.BytesReadLimit) } @@ -75,7 +84,14 @@ func (target *ScanTarget) OpenTLS(baseFlags *BaseFlags, tlsFlags *TLSFlags) (*TL // OpenUDP connects to the ScanTarget using the configured flags, and returns a net.Conn that uses the configured timeouts for Read/Write operations. // Note that the UDP "connection" does not have an associated timeout. func (target *ScanTarget) OpenUDP(flags *BaseFlags, udp *UDPFlags) (net.Conn, error) { - address := net.JoinHostPort(target.Host(), fmt.Sprintf("%d", flags.Port)) + var port uint + // If the port is supplied in ScanTarget, let that override the cmdline option + if target.Port != nil { + port = *target.Port + } else { + port = flags.Port + } + address := net.JoinHostPort(target.Host(), fmt.Sprintf("%d", port)) var local *net.UDPAddr if udp != nil && (udp.LocalAddress != "" || udp.LocalPort != 0) { local = &net.UDPAddr{} From fb49609733a13647542f5ed92cfff0cac0861623 Mon Sep 17 00:00:00 2001 From: Jeff Cody Date: Wed, 21 Aug 2019 14:55:14 -0400 Subject: [PATCH 2/2] Remove `GetPort()` from modules The previous patch allows the port to be specified in the `ScanTarget{}`. Since the port option in the Config may not be the port currently being scanned, delete the `GetPort()` function provided by each module. The `GetPort()` function is also not used. While we could just change the meaning of this function, to mean "Return the port in the Config", it is probably better to go ahead and just remove all references to it as there are no users. --- integration_tests/.template/module/scanner.go | 5 ----- modules/bacnet/scanner.go | 5 ----- modules/banner/scanner.go | 5 ----- modules/dnp3/scanner.go | 5 ----- modules/fox/scanner.go | 5 ----- modules/ftp/scanner.go | 5 ----- modules/imap/scanner.go | 5 ----- modules/ipp/scanner.go | 5 ----- modules/modbus/scanner.go | 5 ----- modules/mongodb/scanner.go | 5 ----- modules/mssql/scanner.go | 5 ----- modules/mysql/scanner.go | 5 ----- modules/ntp/scanner.go | 5 ----- modules/oracle/scanner.go | 5 ----- modules/pop3/scanner.go | 5 ----- modules/postgres/scanner.go | 5 ----- modules/redis/scanner.go | 5 ----- modules/siemens/scanner.go | 5 ----- modules/smb/scanner.go | 5 ----- modules/smtp/scanner.go | 5 ----- modules/ssh.go | 11 +++++++++-- modules/telnet/scanner.go | 5 ----- 22 files changed, 9 insertions(+), 107 deletions(-) diff --git a/integration_tests/.template/module/scanner.go b/integration_tests/.template/module/scanner.go index 2e1bbdc..f86e60f 100644 --- a/integration_tests/.template/module/scanner.go +++ b/integration_tests/.template/module/scanner.go @@ -95,11 +95,6 @@ func (scanner *Scanner) Protocol() string { return "#{MODULE_NAME}" } -// GetPort returns the port being scanned. -func (scanner *Scanner) GetPort() uint { - return scanner.config.Port -} - // Scan TODO: describe what is scanned func (scanner *Scanner) Scan(target zgrab2.ScanTarget) (zgrab2.ScanStatus, interface{}, error) { conn, err := target.Open(&scanner.config.BaseFlags) diff --git a/modules/bacnet/scanner.go b/modules/bacnet/scanner.go index 57f68a5..586d293 100644 --- a/modules/bacnet/scanner.go +++ b/modules/bacnet/scanner.go @@ -87,11 +87,6 @@ func (scanner *Scanner) Protocol() string { return "bacnet" } -// GetPort returns the port being scanned. -func (scanner *Scanner) GetPort() uint { - return scanner.config.Port -} - // Scan probes for a BACNet service. // Behavior taken from original zgrab. // Connects to the configured port over UDP (default 47808/0xBAC0). diff --git a/modules/banner/scanner.go b/modules/banner/scanner.go index 5d36350..a1af4a5 100644 --- a/modules/banner/scanner.go +++ b/modules/banner/scanner.go @@ -68,11 +68,6 @@ func (scanner *Scanner) Protocol() string { return "banner" } -// GetPort returns the port being scanned. -func (scanner *Scanner) GetPort() uint { - return scanner.config.Port -} - // InitPerSender initializes the scanner for a given sender. func (scanner *Scanner) InitPerSender(senderID int) error { return nil diff --git a/modules/dnp3/scanner.go b/modules/dnp3/scanner.go index 782dcff..5d73fab 100644 --- a/modules/dnp3/scanner.go +++ b/modules/dnp3/scanner.go @@ -85,11 +85,6 @@ func (scanner *Scanner) Protocol() string { return "dnp3" } -// GetPort returns the port being scanned. -func (scanner *Scanner) GetPort() uint { - return scanner.config.Port -} - // Scan probes for a DNP3 service. // Connects to the configured TCP port (default 20000) and reads the banner. func (scanner *Scanner) Scan(target zgrab2.ScanTarget) (zgrab2.ScanStatus, interface{}, error) { diff --git a/modules/fox/scanner.go b/modules/fox/scanner.go index d8feb68..b64630b 100644 --- a/modules/fox/scanner.go +++ b/modules/fox/scanner.go @@ -85,11 +85,6 @@ func (scanner *Scanner) Protocol() string { return "fox" } -// GetPort returns the port being scanned. -func (scanner *Scanner) GetPort() uint { - return scanner.config.Port -} - // Scan probes for a Tridium Fox service. // 1. Opens a TCP connection to the configured port (default 1911) // 2. Sends a static query diff --git a/modules/ftp/scanner.go b/modules/ftp/scanner.go index 54e522d..2070fca 100644 --- a/modules/ftp/scanner.go +++ b/modules/ftp/scanner.go @@ -126,11 +126,6 @@ func (scanner *Scanner) GetTrigger() string { return scanner.config.Trigger } -// GetPort returns the configured port for the Scanner. -func (s *Scanner) GetPort() uint { - return s.config.Port -} - // ftpEndRegex matches zero or more lines followed by a numeric FTP status code and linebreak, e.g. "200 OK\r\n" var ftpEndRegex = regexp.MustCompile(`^(?:.*\r?\n)*([0-9]{3})( [^\r\n]*)?\r?\n$`) diff --git a/modules/imap/scanner.go b/modules/imap/scanner.go index c8aeba0..02c13c5 100644 --- a/modules/imap/scanner.go +++ b/modules/imap/scanner.go @@ -135,11 +135,6 @@ func (scanner *Scanner) Protocol() string { return "imap" } -// GetPort returns the port being scanned. -func (scanner *Scanner) GetPort() uint { - return scanner.config.Port -} - func getIMAPError(response string) error { if strings.HasPrefix(response, "a001 OK") { return nil diff --git a/modules/ipp/scanner.go b/modules/ipp/scanner.go index 097c3cf..fcf5a70 100644 --- a/modules/ipp/scanner.go +++ b/modules/ipp/scanner.go @@ -177,11 +177,6 @@ func (scanner *Scanner) Protocol() string { return "ipp" } -// GetPort returns the port being scanned. -func (scanner *Scanner) GetPort() uint { - return scanner.config.Port -} - // FIXME: Add some error handling somewhere in here, unless errors should just be ignored and we get what we get func storeBody(res *http.Response, scanner *Scanner) { b := bufferFromBody(res, scanner) diff --git a/modules/modbus/scanner.go b/modules/modbus/scanner.go index d1f23b7..cb8a023 100644 --- a/modules/modbus/scanner.go +++ b/modules/modbus/scanner.go @@ -113,11 +113,6 @@ func (scanner *Scanner) Protocol() string { return "modbus" } -// GetPort returns the port being scanned. -func (scanner *Scanner) GetPort() uint { - return scanner.config.Port -} - // Conn wraps the connection state (more importantly, it provides the interface used by the old zgrab code, so that it // could be taken over as-is). type Conn struct { diff --git a/modules/mongodb/scanner.go b/modules/mongodb/scanner.go index fbcf72a..69d5b71 100644 --- a/modules/mongodb/scanner.go +++ b/modules/mongodb/scanner.go @@ -215,11 +215,6 @@ func (scanner *Scanner) GetTrigger() string { return scanner.config.Trigger } -// GetPort returns the port being scanned -func (scanner *Scanner) GetPort() uint { - return scanner.config.Port -} - // Validate checks that the flags are valid func (flags *Flags) Validate(args []string) error { return nil diff --git a/modules/mssql/scanner.go b/modules/mssql/scanner.go index afd2bb9..db5f97f 100644 --- a/modules/mssql/scanner.go +++ b/modules/mssql/scanner.go @@ -108,11 +108,6 @@ func (scanner *Scanner) GetTrigger() string { return scanner.config.Trigger } -// GetPort returns the configured scanner port. -func (scanner *Scanner) GetPort() uint { - return scanner.config.Port -} - // Scan performs the MSSQL scan. // 1. Open a TCP connection to the target port (default 1433). // 2. Send a PRELOGIN packet to the server. diff --git a/modules/mysql/scanner.go b/modules/mysql/scanner.go index 0c36d71..fc8171c 100644 --- a/modules/mysql/scanner.go +++ b/modules/mysql/scanner.go @@ -205,11 +205,6 @@ func (scanner *Scanner) GetTrigger() string { return scanner.config.Trigger } -// GetPort returns the port that is being scanned. -func (s *Scanner) GetPort() uint { - return s.config.Port -} - // Scan probles the target for a MySQL server. // 1. Connects and waits to receive the handshake packet. // 2. If the server supports SSL, send an SSLRequest packet, then diff --git a/modules/ntp/scanner.go b/modules/ntp/scanner.go index 2fc243e..b52fafc 100644 --- a/modules/ntp/scanner.go +++ b/modules/ntp/scanner.go @@ -868,11 +868,6 @@ func (scanner *Scanner) GetTrigger() string { return scanner.config.Trigger } -// GetPort returns the port that is being scanned -func (scanner *Scanner) GetPort() uint { - return scanner.config.Port -} - // SendAndReceive is a rough version of ntpdc.c's doquery(), except it only supports a single packet response func (scanner *Scanner) SendAndReceive(impl ImplNumber, req RequestCode, body []byte, sock net.Conn) (*PrivatePacketHeader, []byte, error) { outHeader, err := (&PrivatePacketHeader{ diff --git a/modules/oracle/scanner.go b/modules/oracle/scanner.go index 584fe15..1ab212d 100644 --- a/modules/oracle/scanner.go +++ b/modules/oracle/scanner.go @@ -183,11 +183,6 @@ func (scanner *Scanner) Protocol() string { return "oracle" } -// GetPort returns the port being scanned. -func (scanner *Scanner) GetPort() uint { - return scanner.config.Port -} - func (scanner *Scanner) getTNSDriver() *TNSDriver { mode := TNSModeOld if scanner.config.NewTNS { diff --git a/modules/pop3/scanner.go b/modules/pop3/scanner.go index 934a0a3..47c9490 100644 --- a/modules/pop3/scanner.go +++ b/modules/pop3/scanner.go @@ -150,11 +150,6 @@ func (scanner *Scanner) Protocol() string { return "pop3" } -// GetPort returns the port being scanned. -func (scanner *Scanner) GetPort() uint { - return scanner.config.Port -} - func getPOP3Error(response string) error { if !strings.HasPrefix(response, "-") { return nil diff --git a/modules/postgres/scanner.go b/modules/postgres/scanner.go index 31815d1..783d84b 100644 --- a/modules/postgres/scanner.go +++ b/modules/postgres/scanner.go @@ -319,11 +319,6 @@ func (s *Scanner) GetTrigger() string { return s.Config.Trigger } -// GetPort returns the port being scanned. -func (s *Scanner) GetPort() uint { - return s.Config.Port -} - // DoSSL attempts to upgrade the connection to SSL, returning an error on failure. func (s *Scanner) DoSSL(sql *Connection) error { var conn *zgrab2.TLSConnection diff --git a/modules/redis/scanner.go b/modules/redis/scanner.go index e4cb08c..d115f87 100644 --- a/modules/redis/scanner.go +++ b/modules/redis/scanner.go @@ -211,11 +211,6 @@ func (scanner *Scanner) GetTrigger() string { return scanner.config.Trigger } -// GetPort returns the port being scanned -func (scanner *Scanner) GetPort() uint { - return scanner.config.Port -} - // Close cleans up the scanner. func (scan *scan) Close() { defer scan.close() diff --git a/modules/siemens/scanner.go b/modules/siemens/scanner.go index 04cd40a..e4f4673 100644 --- a/modules/siemens/scanner.go +++ b/modules/siemens/scanner.go @@ -84,11 +84,6 @@ func (scanner *Scanner) Protocol() string { return "siemens" } -// GetPort returns the port being scanned. -func (scanner *Scanner) GetPort() uint { - return scanner.config.Port -} - // Scan probes for Siemens S7 services. // 1. Connect to TCP port 102 // 2. Send a COTP connection packet with destination TSAP 0x0102, source TSAP 0x0100 diff --git a/modules/smb/scanner.go b/modules/smb/scanner.go index 0080c32..f0cf32b 100644 --- a/modules/smb/scanner.go +++ b/modules/smb/scanner.go @@ -87,11 +87,6 @@ func (scanner *Scanner) Protocol() string { return "smb" } -// GetPort returns the port being scanned. -func (scanner *Scanner) GetPort() uint { - return scanner.config.Port -} - // Scan performs the following: // 1. Connect to the TCP port (default 445). // 2. Send a negotiation packet with the default values: diff --git a/modules/smtp/scanner.go b/modules/smtp/scanner.go index dae8088..3c9cc82 100644 --- a/modules/smtp/scanner.go +++ b/modules/smtp/scanner.go @@ -176,11 +176,6 @@ func (scanner *Scanner) Protocol() string { return "smtp" } -// GetPort returns the port being scanned. -func (scanner *Scanner) GetPort() uint { - return scanner.config.Port -} - func getSMTPCode(response string) (int, error) { if len(response) < 5 { return 0, ErrInvalidResponse diff --git a/modules/ssh.go b/modules/ssh.go index e225e17..860211b 100644 --- a/modules/ssh.go +++ b/modules/ssh.go @@ -80,8 +80,15 @@ func (s *SSHScanner) GetTrigger() string { func (s *SSHScanner) Scan(t zgrab2.ScanTarget) (zgrab2.ScanStatus, interface{}, error) { data := new(ssh.HandshakeLog) - port := strconv.FormatUint(uint64(s.config.Port), 10) - rhost := net.JoinHostPort(t.Host(), port) + var port uint + // If the port is supplied in ScanTarget, let that override the cmdline option + if t.Port != nil { + port = *t.Port + } else { + port = s.config.Port + } + portStr := strconv.FormatUint(uint64(port), 10) + rhost := net.JoinHostPort(t.Host(), portStr) sshConfig := ssh.MakeSSHConfig() sshConfig.Timeout = s.config.Timeout diff --git a/modules/telnet/scanner.go b/modules/telnet/scanner.go index 3a79768..e427409 100644 --- a/modules/telnet/scanner.go +++ b/modules/telnet/scanner.go @@ -91,11 +91,6 @@ func (scanner *Scanner) Protocol() string { return "telnet" } -// GetPort returns the port being scanned. -func (scanner *Scanner) GetPort() uint { - return scanner.config.Port -} - // Scan connects to the target (default port TCP 23) and attempts to grab the Telnet banner. func (scanner *Scanner) Scan(target zgrab2.ScanTarget) (zgrab2.ScanStatus, interface{}, error) { conn, err := target.Open(&scanner.config.BaseFlags)