Modbus Banner Grabbing - Metasploit
This page contains detailed information about how to use the auxiliary/scanner/scada/modbus_banner_grabbing metasploit module. For list of all metasploit modules, visit the Metasploit Module Library.
Module Overview
Name: Modbus Banner Grabbing
Module: auxiliary/scanner/scada/modbus_banner_grabbing
Source code: modules/auxiliary/scanner/scada/modbus_banner_grabbing.rb
Disclosure date: -
Last modification time: 2021-08-27 17:15:33 +0000
Supported architecture(s): -
Supported platform(s): -
Target service / protocol: -
Target network port(s): 502
List of CVEs: -
This module grabs the banner of any device running the Modbus protocol by sending a request with Modbus Function Code 43 (Read Device Identification). Modbus is a data communications protocol originally published by Modicon (now Schneider Electric) in 1979 for use with its programmable logic controllers (PLCs).
Module Ranking and Traits
Module Ranking:
- normal: The exploit is otherwise reliable, but depends on a specific version and can't (or doesn't) reliably autodetect. More information about ranking can be found here.
Basic Usage
This module is a scanner module, and is capable of testing against multiple hosts.
msf > use auxiliary/scanner/scada/modbus_banner_grabbing
msf auxiliary(modbus_banner_grabbing) > show options
... show and set options ...
msf auxiliary(modbus_banner_grabbing) > set RHOSTS ip-range
msf auxiliary(modbus_banner_grabbing) > exploit
Other examples of setting the RHOSTS option:
Example 1:
msf auxiliary(modbus_banner_grabbing) > set RHOSTS 192.168.1.3-192.168.1.200
Example 2:
msf auxiliary(modbus_banner_grabbing) > set RHOSTS 192.168.1.1/24
Example 3:
msf auxiliary(modbus_banner_grabbing) > set RHOSTS file:/tmp/ip_list.txt
Required Options
- RHOSTS: The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
Knowledge Base
Vulnerable Application
This module will perform banner grabbing on devices that use the Modbus protocol by sending a payload with the function code 43 to read the target device's identification information. For more technical information, you can refer to this link: https://en.wikipedia.org/wiki/Modbus#Available_function/command_codes.
By default the service is running on port 502, so any device with this port open could be a potential target.
Verification Steps
- Do:
use auxiliary/scanner/scada/modbus_banner_grabbing
- Do:
set RHOST <IP>
where IP is the IP address of the target. - Do:
run
The response from the target device may contain several objects. Some of these objects can be seen below:
vendor name, product code, revision number (in *major version*.*minor version* format), vendor url, product name, model name
If the target was unable to process the Modbus message, a Modbus exception message will be returned from the target, which will then be output to the screen.
Successful results from the scan will be stored as a note
in the framework. You can access these notes by typing note
in the console.
msf5 auxiliary(scanner/scada/modbus_banner_grabbing) > notes
Notes
=====
Time Host Service Port Protocol Type Data
---- ---- ------- ---- -------- ---- ----
2020-07-06 13:25:50 UTC 192.168.1.1 modbus 502 tcp modbus.vendorname "Schneider Electric"
2020-07-06 13:25:50 UTC 192.168.1.1 modbus 502 tcp modbus.productcode "BMX NOE 0100"
2020-07-06 13:25:50 UTC 192.168.1.1 modbus 502 tcp modbus.revision "V3.10"
Options
There are no non-default options for this module.
Scenarios
The following scenarios describe some of the responses you may receive from the target:
Schneider Electric BMX NOE 0100 - Successful Response
msf6 > use auxiliary/scanner/scada/modbus_banner_grabbing
msf6 auxiliary(scanner/scada/modbus_banner_grabbing) > set RHOSTS 192.168.1.1
RHOSTS => 192.168.1.1
msf6 auxiliary(scanner/scada/modbus_banner_grabbing) > run
[*] 192.168.1.1:502 - Number of Objects: 3
[+] 192.168.1.1:502 - VendorName: Schneider Electric
[+] 192.168.1.1:502 - ProductCode: BMX NOE 0100
[+] 192.168.1.1:502 - Revision: V3.10
[*] 192.168.1.1:502 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
Schneider Electric BMX NOE 0100 - No Reply
The target never replied to the attacker's request.
msf6 > use auxiliary/scanner/scada/modbus_banner_grabbing
msf6 auxiliary(scanner/scada/modbus_banner_grabbing) > set RHOSTS 192.168.1.2
RHOSTS => 192.168.1.2
msf6 auxiliary(scanner/scada/modbus_banner_grabbing) > run
[-] 192.168.1.2:502 - MODBUS - No reply
[*] 192.168.1.2:502 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
Schneider Electric BMX NOE 0100 - Network Error
Some network error occurred, such as a connection error, a network timeout, or the connection was refused. Alternatively, the host may be unreachable.
msf6 > use auxiliary/scanner/scada/modbus_banner_grabbing
msf6 auxiliary(scanner/scada/modbus_banner_grabbing) > set RHOSTS 192.168.1.3
RHOSTS => 192.168.1.3
msf6 auxiliary(scanner/scada/modbus_banner_grabbing) > run
[-] 192.168.1.3:502 - MODBUS - Network error during payload: The connection timed out (217.71.253.52:502).
[*] 192.168.1.3:502 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
Schneider Electric BMX NOE 0100 - Modbus Exception Code (i.e. Memory Parity Error)
msf6 > use auxiliary/scanner/scada/modbus_banner_grabbing
msf6 auxiliary(scanner/scada/modbus_banner_grabbing) > set RHOSTS 192.168.1.4
RHOSTS => 192.168.1.4
msf6 auxiliary(scanner/scada/modbus_banner_grabbing) > run
[-] 192.168.1.4:502 - Memory Parity Error: Slave detected a parity error in memory.
[*] 192.168.1.4:502 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
Go back to menu.
Msfconsole Usage
Here is how the scanner/scada/modbus_banner_grabbing auxiliary module looks in the msfconsole:
msf6 > use auxiliary/scanner/scada/modbus_banner_grabbing
msf6 auxiliary(scanner/scada/modbus_banner_grabbing) > show info
Name: Modbus Banner Grabbing
Module: auxiliary/scanner/scada/modbus_banner_grabbing
License: Metasploit Framework License (BSD)
Rank: Normal
Provided by:
Juan Escobar <[email protected]>
Ezequiel Fernandez
Check supported:
No
Basic options:
Name Current Setting Required Description
---- --------------- -------- -----------
RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 502 yes The target port (TCP)
THREADS 1 yes The number of concurrent threads (max one per host)
TIMEOUT 2 yes Timeout for the network probe
Description:
This module grabs the banner of any device running the Modbus
protocol by sending a request with Modbus Function Code 43 (Read
Device Identification). Modbus is a data communications protocol
originally published by Modicon (now Schneider Electric) in 1979 for
use with its programmable logic controllers (PLCs).
References:
https://modbus.org/docs/Modbus_Messaging_Implementation_Guide_V1_0b.pdf
https://en.wikipedia.org/wiki/Modbus#Modbus_TCP_frame_format_(primarily_used_on_Ethernet_networks)
https://github.com/industrialarmy/Hello_Proto
Module Options
This is a complete list of options available in the scanner/scada/modbus_banner_grabbing auxiliary module:
msf6 auxiliary(scanner/scada/modbus_banner_grabbing) > show options
Module options (auxiliary/scanner/scada/modbus_banner_grabbing):
Name Current Setting Required Description
---- --------------- -------- -----------
RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 502 yes The target port (TCP)
THREADS 1 yes The number of concurrent threads (max one per host)
TIMEOUT 2 yes Timeout for the network probe
Advanced Options
Here is a complete list of advanced options supported by the scanner/scada/modbus_banner_grabbing auxiliary module:
msf6 auxiliary(scanner/scada/modbus_banner_grabbing) > show advanced
Module advanced options (auxiliary/scanner/scada/modbus_banner_grabbing):
Name Current Setting Required Description
---- --------------- -------- -----------
CHOST no The local client address
CPORT no The local client port
ConnectTimeout 10 yes Maximum number of seconds to establish a TCP connection
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
SSL false no Negotiate SSL/TLS for outgoing connections
SSLCipher no String for SSL cipher - "DHE-RSA-AES256-SHA" or "ADH"
SSLVerifyMode PEER no SSL verification method (Accepted: CLIENT_ONCE, FAIL_IF_NO_PEER_CERT, NONE, PEER)
SSLVersion Auto yes Specify the version of SSL/TLS to be used (Auto, TLS and SSL23 are auto-negotiate) (Accepted: Auto, TLS, SSL23, SSL3, TLS1, TLS1.1, TLS1.2)
ShowProgress true yes Display progress messages during a scan
ShowProgressPercent 10 yes The interval in percent that progress should be shown
VERBOSE false no Enable detailed status messages
WORKSPACE no Specify the workspace for this module
Auxiliary Actions
This is a list of all auxiliary actions that the scanner/scada/modbus_banner_grabbing module can do:
msf6 auxiliary(scanner/scada/modbus_banner_grabbing) > show actions
Auxiliary actions:
Name Description
---- -----------
Evasion Options
Here is the full list of possible evasion options supported by the scanner/scada/modbus_banner_grabbing auxiliary module in order to evade defenses (e.g. Antivirus, EDR, Firewall, NIDS etc.):
msf6 auxiliary(scanner/scada/modbus_banner_grabbing) > show evasion
Module evasion options:
Name Current Setting Required Description
---- --------------- -------- -----------
TCP::max_send_size 0 no Maxiumum tcp segment size. (0 = disable)
TCP::send_delay 0 no Delays inserted before every send. (0 = disable)
Go back to menu.
Error Messages
This module may fail with the following error messages:
- Illegal Function: The function code received in the query is not recognized or allowed by the slave.
- Illegal Data Address: Data address of some or all the required entities are not allowed or do not exist in slave.
- Illegal Data Value: Value is not accepted by slave.
- Slave Device Failure: Unrecoverable error occurred while slave was attempting to perform requested action.
- Acknowledge: Slave has accepted the request and is processing it, but requires a long period of time to process it.
- Slave Device Busy: Slave is engaged in processing a long-duration program command.
- Negative Acknowledge: Slave cannot perform the programming function recieved in the query.
- Memory Parity Error: Slave detected a parity error in memory.
- Gateway Path Unavailable: The gateway was likely misconfigured or is overloaded as it was unable to internally connect the input and output channels.
- Gateway Target Device Failed to Respond: Gateway could not find the target device on the network or the target device didn't respond.
- MODBUS - received incorrect data.
- MODBUS - No data was received from the target machine, its possible it may be offline or not responding.
- MODBUS - Interrupt during payload
- MODBUS - Network error during payload: <E>
- MODBUS - No reply
Check for the possible causes from the code snippets below found in the module source code. This can often times help in identifying the root cause of the problem.
Illegal Function: The function code received in the query is not recognized or allowed by the slave.
Here is a relevant code snippet related to the "Illegal Function: The function code received in the query is not recognized or allowed by the slave." error message:
43:
44: # Main Modbus exception codes
45: def handle_exception_codes(code)
46: case code
47: when "\xab\x01"
48: print_error('Illegal Function: The function code received in the query is not recognized or allowed by the slave.')
49: when "\xab\x02"
50: print_error('Illegal Data Address: Data address of some or all the required entities are not allowed or do not exist in slave.')
51: when "\xab\x03"
52: print_error('Illegal Data Value: Value is not accepted by slave.')
53: when "\xab\x04"
Illegal Data Address: Data address of some or all the required entities are not allowed or do not exist in slave.
Here is a relevant code snippet related to the "Illegal Data Address: Data address of some or all the required entities are not allowed or do not exist in slave." error message:
45: def handle_exception_codes(code)
46: case code
47: when "\xab\x01"
48: print_error('Illegal Function: The function code received in the query is not recognized or allowed by the slave.')
49: when "\xab\x02"
50: print_error('Illegal Data Address: Data address of some or all the required entities are not allowed or do not exist in slave.')
51: when "\xab\x03"
52: print_error('Illegal Data Value: Value is not accepted by slave.')
53: when "\xab\x04"
54: print_error('Slave Device Failure: Unrecoverable error occurred while slave was attempting to perform requested action.')
55: when "\xab\x05"
Illegal Data Value: Value is not accepted by slave.
Here is a relevant code snippet related to the "Illegal Data Value: Value is not accepted by slave." error message:
47: when "\xab\x01"
48: print_error('Illegal Function: The function code received in the query is not recognized or allowed by the slave.')
49: when "\xab\x02"
50: print_error('Illegal Data Address: Data address of some or all the required entities are not allowed or do not exist in slave.')
51: when "\xab\x03"
52: print_error('Illegal Data Value: Value is not accepted by slave.')
53: when "\xab\x04"
54: print_error('Slave Device Failure: Unrecoverable error occurred while slave was attempting to perform requested action.')
55: when "\xab\x05"
56: print_error('Acknowledge: Slave has accepted the request and is processing it, but requires a long period of time to process it.')
57: when "\xab\x06"
Slave Device Failure: Unrecoverable error occurred while slave was attempting to perform requested action.
Here is a relevant code snippet related to the "Slave Device Failure: Unrecoverable error occurred while slave was attempting to perform requested action." error message:
49: when "\xab\x02"
50: print_error('Illegal Data Address: Data address of some or all the required entities are not allowed or do not exist in slave.')
51: when "\xab\x03"
52: print_error('Illegal Data Value: Value is not accepted by slave.')
53: when "\xab\x04"
54: print_error('Slave Device Failure: Unrecoverable error occurred while slave was attempting to perform requested action.')
55: when "\xab\x05"
56: print_error('Acknowledge: Slave has accepted the request and is processing it, but requires a long period of time to process it.')
57: when "\xab\x06"
58: print_error('Slave Device Busy: Slave is engaged in processing a long-duration program command.')
59: when "\xab\x07"
Acknowledge: Slave has accepted the request and is processing it, but requires a long period of time to process it.
Here is a relevant code snippet related to the "Acknowledge: Slave has accepted the request and is processing it, but requires a long period of time to process it." error message:
51: when "\xab\x03"
52: print_error('Illegal Data Value: Value is not accepted by slave.')
53: when "\xab\x04"
54: print_error('Slave Device Failure: Unrecoverable error occurred while slave was attempting to perform requested action.')
55: when "\xab\x05"
56: print_error('Acknowledge: Slave has accepted the request and is processing it, but requires a long period of time to process it.')
57: when "\xab\x06"
58: print_error('Slave Device Busy: Slave is engaged in processing a long-duration program command.')
59: when "\xab\x07"
60: print_error('Negative Acknowledge: Slave cannot perform the programming function recieved in the query.')
61: when "\xab\x08"
Slave Device Busy: Slave is engaged in processing a long-duration program command.
Here is a relevant code snippet related to the "Slave Device Busy: Slave is engaged in processing a long-duration program command." error message:
53: when "\xab\x04"
54: print_error('Slave Device Failure: Unrecoverable error occurred while slave was attempting to perform requested action.')
55: when "\xab\x05"
56: print_error('Acknowledge: Slave has accepted the request and is processing it, but requires a long period of time to process it.')
57: when "\xab\x06"
58: print_error('Slave Device Busy: Slave is engaged in processing a long-duration program command.')
59: when "\xab\x07"
60: print_error('Negative Acknowledge: Slave cannot perform the programming function recieved in the query.')
61: when "\xab\x08"
62: print_error('Memory Parity Error: Slave detected a parity error in memory.')
63: when "\xab\x0a"
Negative Acknowledge: Slave cannot perform the programming function recieved in the query.
Here is a relevant code snippet related to the "Negative Acknowledge: Slave cannot perform the programming function recieved in the query." error message:
55: when "\xab\x05"
56: print_error('Acknowledge: Slave has accepted the request and is processing it, but requires a long period of time to process it.')
57: when "\xab\x06"
58: print_error('Slave Device Busy: Slave is engaged in processing a long-duration program command.')
59: when "\xab\x07"
60: print_error('Negative Acknowledge: Slave cannot perform the programming function recieved in the query.')
61: when "\xab\x08"
62: print_error('Memory Parity Error: Slave detected a parity error in memory.')
63: when "\xab\x0a"
64: print_error('Gateway Path Unavailable: The gateway was likely misconfigured or is overloaded as it was unable to internally connect the input and output channels.')
65: when "\xab\x0b"
Memory Parity Error: Slave detected a parity error in memory.
Here is a relevant code snippet related to the "Memory Parity Error: Slave detected a parity error in memory." error message:
57: when "\xab\x06"
58: print_error('Slave Device Busy: Slave is engaged in processing a long-duration program command.')
59: when "\xab\x07"
60: print_error('Negative Acknowledge: Slave cannot perform the programming function recieved in the query.')
61: when "\xab\x08"
62: print_error('Memory Parity Error: Slave detected a parity error in memory.')
63: when "\xab\x0a"
64: print_error('Gateway Path Unavailable: The gateway was likely misconfigured or is overloaded as it was unable to internally connect the input and output channels.')
65: when "\xab\x0b"
66: print_error("Gateway Target Device Failed to Respond: Gateway could not find the target device on the network or the target device didn't respond.")
67: else
Gateway Path Unavailable: The gateway was likely misconfigured or is overloaded as it was unable to internally connect the input and output channels.
Here is a relevant code snippet related to the "Gateway Path Unavailable: The gateway was likely misconfigured or is overloaded as it was unable to internally connect the input and output channels." error message:
59: when "\xab\x07"
60: print_error('Negative Acknowledge: Slave cannot perform the programming function recieved in the query.')
61: when "\xab\x08"
62: print_error('Memory Parity Error: Slave detected a parity error in memory.')
63: when "\xab\x0a"
64: print_error('Gateway Path Unavailable: The gateway was likely misconfigured or is overloaded as it was unable to internally connect the input and output channels.')
65: when "\xab\x0b"
66: print_error("Gateway Target Device Failed to Respond: Gateway could not find the target device on the network or the target device didn't respond.")
67: else
68: print_error('MODBUS - received incorrect data.')
69: end
Gateway Target Device Failed to Respond: Gateway could not find the target device on the network or the target device didn't respond.
Here is a relevant code snippet related to the "Gateway Target Device Failed to Respond: Gateway could not find the target device on the network or the target device didn't respond." error message:
61: when "\xab\x08"
62: print_error('Memory Parity Error: Slave detected a parity error in memory.')
63: when "\xab\x0a"
64: print_error('Gateway Path Unavailable: The gateway was likely misconfigured or is overloaded as it was unable to internally connect the input and output channels.')
65: when "\xab\x0b"
66: print_error("Gateway Target Device Failed to Respond: Gateway could not find the target device on the network or the target device didn't respond.")
67: else
68: print_error('MODBUS - received incorrect data.')
69: end
70: end
71:
MODBUS - received incorrect data.
Here is a relevant code snippet related to the "MODBUS - received incorrect data." error message:
63: when "\xab\x0a"
64: print_error('Gateway Path Unavailable: The gateway was likely misconfigured or is overloaded as it was unable to internally connect the input and output channels.')
65: when "\xab\x0b"
66: print_error("Gateway Target Device Failed to Respond: Gateway could not find the target device on the network or the target device didn't respond.")
67: else
68: print_error('MODBUS - received incorrect data.')
69: end
70: end
71:
72: def run_host(ip)
73: object_name = {
MODBUS - No data was received from the target machine, its possible it may be offline or not responding.
Here is a relevant code snippet related to the "MODBUS - No data was received from the target machine, its possible it may be offline or not responding." error message:
130: end
131:
132: num_objects = data[mbtcp['num_objects']['start'], mbtcp['num_objects']['bytes']]
133:
134: if num_objects.nil?
135: print_error('MODBUS - No data was received from the target machine, its possible it may be offline or not responding.')
136: return
137: end
138:
139: num_objects = num_objects.unpack1('C')
140: print_status("Number of Objects: #{num_objects}")
MODBUS - Interrupt during payload
Here is a relevant code snippet related to the "MODBUS - Interrupt during payload" error message:
162: type: "modbus.#{object['name'].downcase}",
163: data: object['str_value']
164: )
165: end
166: rescue ::Interrupt
167: print_error('MODBUS - Interrupt during payload')
168: raise $ERROR_INFO
169: rescue ::Rex::HostUnreachable, ::Rex::ConnectionError, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused => e
170: print_error("MODBUS - Network error during payload: #{e}")
171: return
172: rescue ::EOFError
MODBUS - Network error during payload: <E>
Here is a relevant code snippet related to the "MODBUS - Network error during payload: <E>" error message:
165: end
166: rescue ::Interrupt
167: print_error('MODBUS - Interrupt during payload')
168: raise $ERROR_INFO
169: rescue ::Rex::HostUnreachable, ::Rex::ConnectionError, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused => e
170: print_error("MODBUS - Network error during payload: #{e}")
171: return
172: rescue ::EOFError
173: print_error('MODBUS - No reply')
174: return
175: end
MODBUS - No reply
Here is a relevant code snippet related to the "MODBUS - No reply" error message:
168: raise $ERROR_INFO
169: rescue ::Rex::HostUnreachable, ::Rex::ConnectionError, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused => e
170: print_error("MODBUS - Network error during payload: #{e}")
171: return
172: rescue ::EOFError
173: print_error('MODBUS - No reply')
174: return
175: end
176: end
177:
178: def cleanup
Go back to menu.
Related Pull Requests
- #15192 Merged Pull Request: Enforce Style/RedundantBegin for new modules
- #14806 Merged Pull Request: Rubocop recently landed modules continued
- #14734 Merged Pull Request: Rubocop recently landed modules
- #13836 Merged Pull Request: Add Modbus banner grabbing module
References
- CVE: Not available
- https://modbus.org/docs/Modbus_Messaging_Implementation_Guide_V1_0b.pdf
- https://en.wikipedia.org/wiki/Modbus#Modbus_TCP_frame_format_(primarily_used_on_Ethernet_networks)
- https://github.com/industrialarmy/Hello_Proto
See Also
Check also the following modules related to this module:
- auxiliary/scanner/scada/modbus_findunitid
- auxiliary/scanner/scada/bacnet_l3
- auxiliary/scanner/scada/digi_addp_reboot
- auxiliary/scanner/scada/digi_addp_version
- auxiliary/scanner/scada/digi_realport_serialport_scan
- auxiliary/scanner/scada/digi_realport_version
- auxiliary/scanner/scada/indusoft_ntwebserver_fileaccess
- auxiliary/scanner/scada/koyo_login
- auxiliary/scanner/scada/modbusclient
- auxiliary/scanner/scada/modbusdetect
- auxiliary/scanner/scada/moxa_discover
- auxiliary/scanner/scada/pcomclient
- auxiliary/scanner/scada/profinet_siemens
- auxiliary/scanner/scada/sielco_winlog_fileaccess
- auxiliary/analyze/modbus_zip
- auxiliary/admin/scada/advantech_webaccess_dbvisitor_sqli
- auxiliary/admin/scada/ge_proficy_substitute_traversal
- auxiliary/admin/scada/modicon_command
- auxiliary/admin/scada/modicon_password_recovery
- auxiliary/admin/scada/modicon_stux_transfer
- auxiliary/admin/scada/moxa_credentials_recovery
- auxiliary/admin/scada/multi_cip_command
- auxiliary/admin/scada/pcom_command
- auxiliary/admin/scada/phoenix_command
- auxiliary/admin/scada/yokogawa_bkbcopyd_client
- auxiliary/dos/scada/allen_bradley_pccc
- auxiliary/dos/scada/beckhoff_twincat
- auxiliary/dos/scada/d20_tftp_overflow
- auxiliary/dos/scada/igss9_dataserver
- auxiliary/dos/scada/siemens_siprotec4
- auxiliary/dos/scada/yokogawa_logsvr
- exploit/unix/webapp/openx_banner_edit
- exploit/windows/ftp/proftp_banner
Authors
- Juan Escobar <juan[at]null-life.com>
- Ezequiel Fernandez
Version
This page has been produced using Metasploit Framework version 6.2.23-dev. For more modules, visit the Metasploit Module Library.
Go back to menu.