BACnet Scanner - Metasploit
This page contains detailed information about how to use the auxiliary/scanner/scada/bacnet_l3 metasploit module. For list of all metasploit modules, visit the Metasploit Module Library.
Module Overview
Name: BACnet Scanner
Module: auxiliary/scanner/scada/bacnet_l3
Source code: modules/auxiliary/scanner/scada/bacnet_l3.rb
Disclosure date: -
Last modification time: 2022-08-01 15:11:57 +0000
Supported architecture(s): -
Supported platform(s): -
Target service / protocol: -
Target network port(s): -
List of CVEs: -
Discover BACnet devices by broadcasting Who-is message, then poll discovered devices for properties including model name, software version, firmware revision and description.
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.
Reliability:
- unreliable-session: The module isn't expected to get a shell reliably (such as only once).
Stability:
- crash-safe: Module should not crash the service.
Side Effects:
- screen-effects: Module may show something on the screen (Example: a window pops up).
Basic Usage
msf > use auxiliary/scanner/scada/bacnet_l3
msf auxiliary(bacnet_l3) > show targets
... a list of targets ...
msf auxiliary(bacnet_l3) > set TARGET target-id
msf auxiliary(bacnet_l3) > show options
... show and set options ...
msf auxiliary(bacnet_l3) > exploit
Knowledge Base
Vulnerable Application
BACnet is a Data Communication Protocol for Building Automation and Control Networks. Developed under the auspices of the American Society of Heating, Refrigerating and Air-Conditioning Engineers (ASHRAE), BACnet is an American national standard, a European standard, a national standard in more than 30 countries, and an ISO global standard. The protocol is supported and maintained by ASHRAE Standing Standard Project Committee 135
This script polls bacnet devices with a l3 broadcast Who-is message and for each reply communicates further to discover more data and saves the data into metasploit. Each bacnet device responds with this data: - It's IP address, and BACnet/IP address (if the device is nested). - It's device number. - Model name. - Application software version. - Firmware revision. - Device description.
Verification Steps
- Start msfconsole.
- Do:
use auxiliary/scanner/scada/bacnet_l3
. - Do:
set INTERFACE
. - Do:
run
. - Devices running the BACnet protocol should respond with data.
Options
A user can choose between the interfaces of his host (e.g. eth1, ens192...), the number of Who-is packets to send - for reliability purposes, the time (in seconds) to wait for packets to arrive and the UDP port, the default is 47808.
The user can always check these options via the show options
command.
msf auxiliary(profinet_siemens) > show options
Module options (auxiliary/scanner/scada/bacnet_l3):
Name Current Setting Required Description
---- --------------- -------- -----------
COUNT 1 yes The number of times to send each packet
INTERFACE eth1 yes The interface to scan from
PORT 47808 yes BACnet/IP UDP port to scan (usually between 47808-47817)
TIMEOUT 1 yes The socket connect timeout in seconds
Scenarios
The following demonstrates a basic scenario, we "detect" two devices:
msf > use auxiliary/scanner/scada/bacnet_l3
msf auxiliary(auxiliary/scanner/scada/bacnet_l3) > run
[*] Broadcasting Who-is via eth1
[*] found 2 devices
[*] Querying device number 826001 in ip 192.168.13.11
[*] Querying device number 4194303 in ip 192.168.13.12
[*] Done scanning
[+] for asset number 826001:
model name: iSMA-B-4U4A-H-IP
firmware revision: 6.2
application software version: GC5 6.2
description: BACnet iSMA-B-4U4A-H-IP Module
[+] for asset number 4194303:
model name: PXG3.L-1
firmware revision: FW=01.21.30.38;WPC=1.4.131;SVS-300:SBC=13.21;
application software version:
description: BacnetRouter
[+] Successfully saved data to local store named bacnet-discovery.xml
[*] Done.
[*] Auxiliary module execution completed
Go back to menu.
Msfconsole Usage
Here is how the scanner/scada/bacnet_l3 auxiliary module looks in the msfconsole:
msf6 > use auxiliary/scanner/scada/bacnet_l3
msf6 auxiliary(scanner/scada/bacnet_l3) > show info
Name: BACnet Scanner
Module: auxiliary/scanner/scada/bacnet_l3
License: Metasploit Framework License (BSD)
Rank: Normal
Provided by:
Paz <Paz @ SCADAfence>
Module side effects:
screen-effects
Module stability:
crash-safe
Module reliability:
unreliable-session
Check supported:
No
Basic options:
Name Current Setting Required Description
---- --------------- -------- -----------
COUNT 1 yes The number of times to send each packet
INTERFACE eth1 yes The interface to scan from
PORT 47808 yes BACnet/IP UDP port to scan (usually between 47808-47817)
SNAPLEN 65535 yes The number of bytes to capture
TIMEOUT 1 yes The socket connect timeout in seconds
Description:
Discover BACnet devices by broadcasting Who-is message, then poll
discovered devices for properties including model name, software
version, firmware revision and description.
Module Options
This is a complete list of options available in the scanner/scada/bacnet_l3 auxiliary module:
msf6 auxiliary(scanner/scada/bacnet_l3) > show options
Module options (auxiliary/scanner/scada/bacnet_l3):
Name Current Setting Required Description
---- --------------- -------- -----------
COUNT 1 yes The number of times to send each packet
INTERFACE eth1 yes The interface to scan from
PORT 47808 yes BACnet/IP UDP port to scan (usually between 47808-47817)
SNAPLEN 65535 yes The number of bytes to capture
TIMEOUT 1 yes The socket connect timeout in seconds
Advanced Options
Here is a complete list of advanced options supported by the scanner/scada/bacnet_l3 auxiliary module:
msf6 auxiliary(scanner/scada/bacnet_l3) > show advanced
Module advanced options (auxiliary/scanner/scada/bacnet_l3):
Name Current Setting Required Description
---- --------------- -------- -----------
GATEWAY_PROBE_HOST 8.8.8.8 yes Send a TTL=1 random UDP datagram to this host to discover the default gateway's MAC
GATEWAY_PROBE_PORT no The port on GATEWAY_PROBE_HOST to send a random UDP probe to (random if 0 or unset)
SECRET 1297303073 yes A 32-bit cookie for probe requests.
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/bacnet_l3 module can do:
msf6 auxiliary(scanner/scada/bacnet_l3) > show actions
Auxiliary actions:
Name Description
---- -----------
Evasion Options
Here is the full list of possible evasion options supported by the scanner/scada/bacnet_l3 auxiliary module in order to evade defenses (e.g. Antivirus, EDR, Firewall, NIDS etc.):
msf6 auxiliary(scanner/scada/bacnet_l3) > show evasion
Module evasion options:
Name Current Setting Required Description
---- --------------- -------- -----------
Go back to menu.
Error Messages
This module may fail with the following error messages:
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.
Interface <INTERFACE> is down
Here is a relevant code snippet related to the "Interface <INTERFACE> is down" error message:
133: def broadcast_who_is
134: begin
135: broadcast_addr = get_ipv4_broadcast(datastore['INTERFACE'])
136: interface_addr = get_ipv4_addr(datastore['INTERFACE'])
137: rescue StandardError
138: raise StandardError, "Interface #{datastore['INTERFACE']} is down"
139: end
140: cap = []
141:
142: # Create a socket for broadcast response and a socket for unicast response.
143: lsocket = Rex::Socket::Udp.create({
Couldn't collect data for asset number <INSTANCE_NUMBER>.
Here is a relevant code snippet related to the "Couldn't collect data for asset number <INSTANCE_NUMBER>." error message:
272:
273: device['instance-number'] = instance_number.to_s
274: devices_by_ip[ip] = [] unless devices_by_ip[ip]
275: devices_by_ip[ip].append(device)
276: rescue StandardError
277: print_bad("Couldn't collect data for asset number #{instance_number}.")
278: end
279: end
280: devices_by_ip
281: end
282:
TIMEOUT
Here is a relevant code snippet related to the "TIMEOUT" error message:
367: devices
368: end
369:
370: def run
371: # Validate user input
372: raise Msf::OptionValidateError, ['TIMEOUT'] if datastore['TIMEOUT'].negative?
373: raise Msf::OptionValidateError, ['COUNT'] if datastore['COUNT'] < 1
374: raise Msf::OptionValidateError, ['INTERFACE'] if datastore['INTERFACE'].empty?
375:
376: begin
377: # Broadcast who-is and create request-property messages for detected devices.
COUNT
Here is a relevant code snippet related to the "COUNT" error message:
368: end
369:
370: def run
371: # Validate user input
372: raise Msf::OptionValidateError, ['TIMEOUT'] if datastore['TIMEOUT'].negative?
373: raise Msf::OptionValidateError, ['COUNT'] if datastore['COUNT'] < 1
374: raise Msf::OptionValidateError, ['INTERFACE'] if datastore['INTERFACE'].empty?
375:
376: begin
377: # Broadcast who-is and create request-property messages for detected devices.
378: print_status "Broadcasting Who-is via #{datastore['INTERFACE']}"
INTERFACE
Here is a relevant code snippet related to the "INTERFACE" error message:
369:
370: def run
371: # Validate user input
372: raise Msf::OptionValidateError, ['TIMEOUT'] if datastore['TIMEOUT'].negative?
373: raise Msf::OptionValidateError, ['COUNT'] if datastore['COUNT'] < 1
374: raise Msf::OptionValidateError, ['INTERFACE'] if datastore['INTERFACE'].empty?
375:
376: begin
377: # Broadcast who-is and create request-property messages for detected devices.
378: print_status "Broadcasting Who-is via #{datastore['INTERFACE']}"
379: capture = broadcast_who_is
No devices found. Exiting.
Here is a relevant code snippet related to the "No devices found. Exiting." error message:
387: devices_by_ip = get_properties_from_devices(messages)
388: print_status 'Done collecting data'
389: sleep(DEFAULT_SLEEP)
390: output_results(devices_by_ip)
391: else
392: fail_with(Failure::NotFound, 'No devices found. Exiting.')
393: end
394: rescue StandardError => e
395: fail_with(Failure::Unknown, e.message)
396: return
397: end
Go back to menu.
Related Pull Requests
Go back to menu.
See Also
Check also the following modules related to this module:
- 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/modbus_banner_grabbing
- auxiliary/scanner/scada/modbusclient
- auxiliary/scanner/scada/modbusdetect
- auxiliary/scanner/scada/modbus_findunitid
- auxiliary/scanner/scada/moxa_discover
- auxiliary/scanner/scada/pcomclient
- auxiliary/scanner/scada/profinet_siemens
- auxiliary/scanner/scada/sielco_winlog_fileaccess
- exploit/windows/fileformat/bacnet_csv
- auxiliary/admin/http/dlink_dsl320b_password_extractor
- 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
Authors
- Paz @ SCADAfence
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.