Converged Security Alert: Why Your PLC Changes Are Useless Without Badge Access Correlation + Video

Listen to this Post

Featured Image

Introduction:

In industrial control systems (ICS), security teams diligently monitor programmable logic controller (PLC) changes while physical access control systems (ACS) track who enters restricted zones. However, these two critical data streams almost never intersect, creating a blind spot where an attacker using a stolen badge can modify logic controllers without triggering any alarm. Converged security bridges this gap by correlating physical badge events with OT network activity, enabling defenders to detect unauthorized PLC modifications even when each individual log appears legitimate.

Learning Objectives:

  • Understand the fundamental security gap between physical access logs and OT device changes
  • Learn to correlate badge access timestamps with PLC configuration modifications using open-source tools
  • Implement a basic detection rule that flags PLC changes without corresponding physical presence

You Should Know:

  1. Extracting and Normalizing Badge Access Logs from Physical Security Systems

Most physical access control systems export logs in CSV or syslog format, but they rarely include standardized timestamps. To correlate with OT events, you must first normalize badge data into a machine-readable structure.

Step‑by‑step guide to parse badge logs on Linux:

Assume you have a raw badge log file `badge_access.log` with entries like:

2025-02-18 14:23:45, Zone 4B, Badge ID 8821, Engineer Doe, ACCESS_GRANTED
2025-02-18 14:33:12, Zone 4B, Badge ID 8821, Engineer Doe, ACCESS_GRANTED

Use `awk` to extract timestamp and zone:

awk -F', ' '{print $1 "," $2 "," $3}' badge_access.log > normalized_badge.csv

For real‑time monitoring on Windows, use PowerShell to pull events from a typical ACS API (e.g., Lenel OnGuard):

$badgeEvents = Invoke-RestMethod -Uri "http://acs-api.local/events?from=last15min" -Headers @{Authorization="Bearer $token"}
$badgeEvents | Where-Object {$_.status -eq "GRANTED"} | Export-Csv -Path "badge_alerts.csv"

What this does: It transforms raw, vendor‑specific access logs into a uniform CSV with timestamp and zone fields, enabling time‑based joins with OT logs. Without this normalization, manual correlation is impossible at scale.

  1. Capturing PLC Change Events from OT Network Traffic

PLCs typically communicate via Modbus/TCP, S7, or CIP. A configuration change often appears as a write operation to a specific register. You can passively monitor these changes using `nmap` scripts or tshark.

Step‑by‑step to capture Modbus writes on Linux:

Install `tshark` (Wireshark CLI) and capture traffic on the OT interface:

sudo tshark -i eth1 -Y "modbus.func_code == 16" -T fields -e frame.time -e ip.src -e modbus.register -e modbus.value -E separator=,

This command filters for Modbus function code 16 (Write Multiple Registers) and outputs timestamp, source IP, register address, and new value. Save to plc_changes.csv.

For S7comm (Siemens) on Windows using a Python script with scapy:

from scapy.all import 
def s7_monitor(pkt):
if pkt.haslayer(S7COMM) and pkt[bash].param == 0x04:  Write var
print(f"{pkt.time} S7 write from {pkt[bash].src}")
sniff(iface="eth1", prn=s7_monitor, filter="tcp port 102")

What this does: It passively listens to OT network traffic and extracts every PLC write operation, creating a log of process changes independent of proprietary engineering workstation logs. This is crucial because attackers often hide changes by bypassing the official HMI.

3. Time‑Correlation Script to Detect Unauthorized PLC Modifications

Once you have both badge logs and PLC change logs in timestamped CSV format, a simple Python script can detect mismatches: a PLC change that occurs without a badge grant in the same zone within a configurable window (e.g., 10 minutes).

Example correlation script (`correlate.py`):

import pandas as pd
from datetime import timedelta

badges = pd.read_csv('normalized_badge.csv', names=['timestamp','zone','badge_id'])
badges['timestamp'] = pd.to_datetime(badges['timestamp'])

plc_changes = pd.read_csv('plc_changes.csv', names=['timestamp','src_ip','register','value'])
plc_changes['timestamp'] = pd.to_datetime(plc_changes['timestamp'])

alert_window = timedelta(minutes=10)
alerts = []

for _, change in plc_changes.iterrows():
zone_mapping = {'192.168.1.100': 'Zone 4B'}  map PLC IP to physical zone
change_zone = zone_mapping.get(change['src_ip'])
prior_badge = badges[(badges['zone'] == change_zone) & 
(badges['timestamp'] >= change['timestamp'] - alert_window) &
(badges['timestamp'] <= change['timestamp'])]
if prior_badge.empty:
alerts.append(f"ALERT: PLC change at {change['timestamp']} with no prior badge access in {change_zone}")

for alert in alerts:
print(alert)

How to use: Run this script every 5 minutes via cron (Linux) or Task Scheduler (Windows). It will output an alert whenever a PLC write occurs without a corresponding badge swipe in the same zone within the last 10 minutes – a clear indicator of potential badge sharing or physical intrusion.

  1. Building a Detection Rule in a SIEM (Splunk/ELK)

For production environments, implement correlation as a SIEM rule. Below is an example for Elastic Stack using EQL (Event Query Language):

sequence by zone_id
[access where event.code == "badge_granted"] by badge_id
[ot where event.type == "plc_write"] by plc_ip
with maxspan=10m
where not access.badge_id == "maintenance_badge"  exclude planned work

Step‑by‑step to deploy in ELK:

  1. Ingest badge logs via Filebeat or API integration.
  2. Ingest OT syslog from a span port or industrial gateway.
  3. Create a new detection rule in Kibana → Security → Rules → Create new rule → Custom query.
  4. Set the EQL sequence as above and define an action (email, webhook, or ServiceNow ticket).

What this does: Automates real‑time alerting without custom scripts, leveraging SIEM correlation engines to handle millions of events. It also allows you to whitelist planned maintenance windows and specific badge IDs.

  1. Mitigation and Hardening: Enforcing Two‑Person Physical Presence for Critical PLC Changes

Detection alone is insufficient. You must enforce that critical PLC changes require either a second badge swipe or a work order linked to a maintenance window.

Linux/Windows commands to enforce badge+work order correlation using an API gateway:

Deploy a lightweight API that proxies all engineering workstation (EWS) traffic to PLCs. On Linux using mitmproxy:

mitmdump --mode reverse:http://plc-ip --listen-port 8080 --set block_global=false

Then write a Python addon that checks a Redis cache for active work orders keyed by badge ID:

from mitmproxy import http
import redis
r = redis.Redis(host='localhost', port=6379, db=0)
def request(flow: http.HTTPFlow) -> None:
badge_id = flow.request.headers.get("X-Badge-ID")
if not r.exists(f"workorder:{badge_id}"):
flow.response = http.Response.make(403, b"Unauthorized PLC change – no active work order")

On Windows, use a PowerShell proxy with `HttpListener` class to inspect Modbus/TCP packets and validate against a SQLite work order table.

How to use: Place this proxy between all engineering workstations and the OT network. It transparently blocks any PLC write unless the operator presents a valid badge ID (via an HTTP header) that has an associated work order created during a scheduled maintenance window.

  1. Simulating an Attack to Test Your Converged Security

To validate your detection, simulate a badge theft scenario using a Raspberry Pi with a cloned HID proximity card (for authorized testing only). Then use `modbus-tk` to write to a test PLC:

Attack simulation script (`simulate_unauth_change.py`):

from modbus_tk import modbus_tcp
import sys
master = modbus_tcp.TcpMaster(host="192.168.1.100", port=502)
master.set_timeout(5.0)
 Write 1 to holding register 40001 (simulate valve override)
master.execute(1, modbus_tcp.WRITE_SINGLE_REGISTER, 40001, output_value=1)
print("PLC change pushed without badge swipe – detection should trigger")

Run this from a laptop not associated with any recent badge swipe. Your correlation script should generate an alert within the polling interval. This test confirms that your converged security monitoring actually works.

  1. Cloud Hardening for Remote OT Access: Correlating VPN Logs with Badge Data

Many industrial environments now allow remote engineers via VPN. Converged security must extend to cloud identity logs. Correlate Azure AD sign‑ins with physical badge access using Azure Sentinel:

KQL query for Microsoft Sentinel:

let badgeAccess = AcessControlLogs | where TimeGenerated > ago(1h) | project badge_id, zone, TimeGenerated;
let vpnLogin = SigninLogs | where AppDisplayName == "Corporate VPN" | project user_principal_name, TimeGenerated;
badgeAccess | join kind=leftouter vpnLogin on $left.badge_id == $right.user_principal_name
| where vpnLogin_TimeGenerated > badgeAccess_TimeGenerated
| project Alert="Remote VPN login after badge swipe without physical re-entry"

Step‑by‑step:

  1. Ingest badge logs into Log Analytics workspace using an Azure Function or REST API.
  2. Enable Azure AD sign‑in logs (requires P1/P2 license).
  3. Create a scheduled alert rule that runs the KQL query every 5 minutes.
  4. Set an action to trigger an incident in Microsoft Sentinel.

What this does: Detects when a remote VPN session starts after a badge swipe in a production zone – a classic sign of badge cloning or tailgating, because the physical badge owner cannot be both inside the plant and remotely connected from another country.

What Undercode Say:

  • Key Takeaway 1: Isolated logging of physical access and OT changes leaves a gaping hole that attackers can exploit with a single stolen badge – correlation is not optional, it is foundational.
  • Key Takeaway 2: Open‑source tools like tshark, awk, and Python pandas provide a low‑cost way to implement converged security without waiting for expensive commercial XDR platforms.
  • Analysis: Most OT security frameworks (IEC 62443, NIST SP 800-82) still treat physical and cyber as separate domains. The example scenario of an engineer’s badge being used to modify a PLC without a work order demonstrates that convergence is a force multiplier: it turns two benign events into a high‑fidelity threat indicator. Organizations that fail to correlate will continue to miss the root cause of incidents, while adversaries increasingly target physical access as the easiest path to process disruption. The future lies in unified platforms that ingest badge, video, IT, and OT logs into a common data lake, enabling behavioral analytics across all layers of the converged attack surface.

Prediction:

Within three years, converged security will become a mandatory compliance requirement for critical infrastructure, driven by incidents where attackers use physical access to bypass air gaps. We predict the emergence of “physical‑OT correlation engines” as a distinct product category, and major cloud providers (AWS, Azure, GCE) will offer native badge‑to‑PLC correlation as a service. Meanwhile, red teams will increasingly combine lockpicking with PLC fuzzing, forcing defenders to integrate their physical security operations centers (PSOCs) and security operations centers (SOCs) into a single, converged command. The first high‑profile industrial breach traced to a correlated badge‑and‑PLC log will trigger a wave of investment – and a new generation of security analysts trained to hunt across both domains.

▶️ Related Video (82% Match):

🎯Let’s Practice For Free:

IT/Security Reporter URL:

Reported By: Zakharb 1 – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow UndercodeTesting & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin | 🦋BlueSky