<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
---
name: performing-ics-asset-inventory
description: >-
  Discover and inventory all OT assets including PLCs, RTUs, HMIs, historians, and
  network infrastructure using passive and active techniques across ICS protocols
  (Modbus, DNP3, OPC-UA, S7comm, EtherNet/IP, BACnet).
domain: cybersecurity
subdomain: ot-ics-security
tags:
  - asset-inventory
  - ics
  - scada
  - ot-discovery
  - nmap
  - zeek
  - passive-recon
version: "1.0"
author: defconxt
license: AGPL-3.0
compatibility: Designed for Claude Code, GitHub Copilot, OpenAI Codex, Cursor, Gemini CLI, and any agentskills.io-compatible agent.
metadata:
  mitre-attack: ["T0840", "T0846"]
  nist-csf: ["ID.AM-1", "ID.AM-2", "ID.AM-4"]
  iec-62443: ["SR 7.8"]
  uuid: a1b2c3d4-1009-4000-a009-000000000009
---

# Performing ICS Asset Inventory

## Overview

You cannot protect what you do not know exists. OT environments frequently contain
undocumented legacy devices, shadow PLCs added during expansions, and forgotten
engineering workstations with direct PLC access. Comprehensive asset inventory is the
foundation of ICS security — required by IEC 62443 and NIST SP 800-82. Passive
techniques are preferred for production; active scanning is lab-only unless explicitly
authorized with safety assessment.

Mode: `[MODE: RECON]` for discovery; `[MODE: ARCHITECT]` for inventory management.

## Prerequisites

| Requirement | Details |
|---|---|
| Network tap or SPAN port on OT VLANs | Required |
| Zeek 6.0+ with ICS protocol analyzers | Required |
| nmap 7.90+ with ICS NSE scripts (lab only) | Required |
| `arp-scan`, `tcpdump` for passive discovery | Required |
| Spreadsheet or CMDB for asset tracking | Required |

## Key Concepts

### Passive Discovery (Safe for Production)

```bash
# Capture OT network traffic (non-intrusive)
tcpdump -i eth1 -w ot_passive_capture.pcap -c 1000000

# ARP table for all devices on local segment
arp -an | sort -t. -k1,1n -k2,2n -k3,3n -k4,4n > arp_inventory.txt

# Passive OS fingerprinting with p0f
p0f -i eth1 -o p0f_results.txt &

# Zeek passive protocol identification
zeek -r ot_passive_capture.pcap local modbus dnp3 s7comm

# Extract unique hosts and services
cat conn.log | zeek-cut id.orig_h id.resp_h id.resp_p service | sort -u > services.txt
cat modbus.log | zeek-cut id.resp_h unit_id | sort -u > modbus_devices.txt
cat dnp3.log | zeek-cut id.resp_h | sort -u > dnp3_devices.txt

# MAC vendor lookup for device identification
cat arp_inventory.txt | awk '{print $4}' | while read mac; do
  vendor=$(grep -i "${mac:0:8}" /usr/share/nmap/nmap-mac-prefixes 2>/dev/null | cut -d' ' -f2-)
  echo "$mac $vendor"
done > mac_vendors.txt
```

### Active Discovery (Lab/Authorized Only)

```bash
# ⚠️ Active scanning can crash PLCs — lab environment only
# ICS service scan on common ports
nmap -sV -p 102,502,20000,44818,4840,47808,1911,2222 10.0.0.0/24 \
  -oA ics_scan --open

# Port reference:
# 102   = S7comm (Siemens)
# 502   = Modbus TCP
# 20000 = DNP3
# 44818 = EtherNet/IP (CIP)
# 4840  = OPC-UA
# 47808 = BACnet
# 1911  = Niagara Fox
# 2222  = EtherNet/IP (explicit)

# ICS-specific NSE scripts
nmap --script modbus-discover -p 502 10.0.0.0/24
nmap --script s7-info -p 102 10.0.0.0/24
nmap --script dnp3-info -p 20000 10.0.0.0/24
nmap --script bacnet-info -p 47808 10.0.0.0/24
nmap --script enip-info -p 44818 10.0.0.0/24

# Combine results into inventory
grep "open" ics_scan.gnmap | awk '{print $2, $0}' | sort > active_inventory.txt
```

### Device Identification

```bash
# Identify device vendor/model from Modbus Device ID
python3 -c "
from pymodbus.client import ModbusTcpClient
client = ModbusTcpClient('10.0.0.1', port=502)
client.connect()
# Read Device Identification (FC 43 / MEI 14)
from pymodbus.mei_message import ReadDeviceInformationRequest
req = ReadDeviceInformationRequest(read_code=0x01, unit=1)
resp = client.execute(req)
if resp and not resp.isError():
    for obj_id, value in resp.information.items():
        print(f'  Object {obj_id}: {value}')
client.close()
"

# S7comm device identification
python3 -c "
import snap7
client = snap7.client.Client()
client.connect('10.0.0.1', 0, 1)
info = client.get_cpu_info()
print(f'Module: {info.ModuleTypeName}')
print(f'Serial: {info.SerialNumber}')
print(f'Name: {info.ASName}')
"
```

## Workflow

### Step 1: Passive Collection (Week 1)

```bash
# Deploy network tap and capture traffic for 7 days
tcpdump -i eth1 -w /data/passive_week.pcap -G 86400 -W 7
zeek -r /data/passive_week.pcap local modbus dnp3 s7comm
```

### Step 2: Compile Inventory

```bash
# Merge passive and active (if authorized) discovery
# Build asset register with fields:
# IP | MAC | Vendor | Model | Firmware | Purdue Level | Protocols | Owner
```

### Step 3: Validate and Maintain

```bash
# Compare discovered assets against documented inventory
comm -13 <(sort documented_assets.txt) <(sort discovered_assets.txt)
# New assets = undocumented devices requiring investigation
```

## Verification

- [ ] All OT VLANs scanned (passive minimum, active if authorized)
- [ ] Every discovered device assigned Purdue Model level
- [ ] Vendor, model, and firmware version recorded per device
- [ ] Undocumented devices investigated and documented
- [ ] Asset inventory loaded into CMDB or tracking system
- [ ] Automated periodic re-discovery scheduled

## Detection Opportunities

- New MAC addresses on OT VLANs → rogue device introduction
- Undocumented devices with ICS protocol services → shadow infrastructure
- Devices responding to scans with unexpected services → misconfiguration or compromise
- Firmware versions with known CVEs → vulnerability management priority

```yaml
title: Ics Asset Inventory Detection
id: 47ee08c9-1a42-4dbb-b8d7-81eeed87fc63
status: experimental
description: Detects suspicious activity related to performing ics asset inventory techniques in ot ics security context
logsource:
  category: process_creation
  product: windows
detection:
  selection:
    CommandLine: "*performing*ics*"
  condition: selection
level: medium
tags:
  - attack.t0840
  - attack.t0846
  - attack.lateral_movement
falsepositives:
  - Industrial control system maintenance by authorized engineering staff
```

## References

- IEC 62443-2-1 §4.2.3.4: Asset Identification
- NIST SP 800-82 Rev 3 §5.1: OT Asset Management
- CISA: OT Asset Discovery Recommendations
- NIST Cybersecurity Framework: ID.AM-1, ID.AM-2
