AI-Generated PLC Code: Why Your Next OT Breach Will Come from , Not a Hacker + Video

Listen to this Post

Featured Image

Introduction:

The convergence of Large Language Models (LLMs) with Operational Technology (OT) programming is no longer theoretical—tools like Eigen, , and CodeSys integrations can now generate structured PLC (Programmable Logic Controller) code in ladder logic and Structured Text. However, this capability introduces a silent but critical cybersecurity nightmare: AI-generated industrial control logic that lacks safety awareness, ignores real-world I/O anomalies, and cannot be held legally accountable for catastrophic failures.

Learning Objectives:

  • Identify vulnerabilities specific to AI-generated PLC code in industrial environments (Siemens, CodeSys, Mythos platforms)
  • Apply test‑driven development (TDD) and forensic auditing techniques to validate AI‑suggested ladder logic
  • Implement defensive network segmentation, human‑in‑the‑loop guardrails, and digital signing to mitigate AI‑induced OT breaches

You Should Know:

  1. The Training Data Gap: Why AI Doesn’t Know About Bouncing Contacts

Most AI models are trained on generic software repositories—not on decades of hard‑earned OT safety practices. As Jake Brodsky points out, a modern PLC’s short scan time can detect contact bounce on a limit switch that slower controllers missed. An AI, unaware of this physical behavior, will generate “perfect” logic that fails in the field. Furthermore, the “Top20” secure coding patterns for PLCs remain scarce in training sets.

Step‑by‑step guide to simulate and mitigate contact bounce:

  1. Simulate bounce in Python (before deploying to a real PLC):
    import time
    import random
    Simulate a noisy limit switch
    def read_limit_switch():
    return random.choice([True, False, False, True, False])  60% false triggers
    De‑bounce logic
    def debounce(pin, delay=0.02):
    stable = pin()
    time.sleep(delay)
    return stable == pin()
    
  2. Implement hardware de‑bounce in ladder logic on a Siemens S7‑1200 using an on‑delay timer (TON) – a pattern rarely generated by AI out‑of‑the‑box.
  3. Add input filtering with a moving average for analog I/O before feeding data to AI‑generated function blocks.
  4. Validate using OpenPLC (Linux: sudo apt install openplc && openplc), inject artificially bounced inputs, and observe if AI code handles them.

  5. Auditing AI‑Generated PLC Code: A Step‑by‑Step Forensic Approach

When an AI tool (e.g., CodeSys Assistant or Mythos) outputs a Structured Text routine, assume it contains logical race conditions or unsafe state transitions. Use network forensics to compare expected vs. actual I/O behavior.

Linux / Windows commands for OT traffic inspection:

  • Discover Modbus/TCP devices on your OT segment (Linux):
    sudo nmap -sS -p 502 --open 192.168.1.0/24 --script modbus-discover
    
  • Capture live PLC traffic with `tshark` (filter for function codes 01,02,03,04):
    sudo tshark -i eth0 -Y "modbus.func_code == 3" -T fields -e modbus.register_address -e modbus.register_value
    
  • Windows (PowerShell as Admin) using pktmon:
    pktmon start --capture --pkt-size 128 --file-name plc_capture.etl
    pktmon filter add -p 502
    pktmon stop
    

Step‑by‑step audit workflow:

  1. Run the AI‑generated PLC code in a hardware‑in‑the‑loop (HIL) simulator (e.g., Siemens PLCSIM).
  2. Inject boundary values (e.g., holding register writes beyond intended range).
  3. Compare Modbus exception responses against expected safe defaults.
  4. Use `modpoll` (Linux/Windows command‑line Modbus master) to automate fuzzing:
    modpoll -m tcp -a 1 -r 100 -c 10 192.168.1.10
    
  5. Log any unhandled edge cases—these are your security findings.

  6. Test‑Driven Development for PLCs: Adapting TDD to Ladder Logic

Matthew Kamerman’s question about TDD for AI‑generated OT code is critical. While IT environments have rich unit test frameworks, PLC ecosystems lack native infrastructure. However, you can implement a lightweight TDD loop using Python’s `pyModbus` and an OpenPLC runtime.

Step‑by‑step TDD for AI‑generated logic:

  1. Write a failing test first (e.g., “When emergency_stop = True, motor_contactor MUST be False within 50ms”).
  2. Generate or obtain AI‑produced code (e.g., from Eigen or prompt: “Write Siemens SCL for emergency stop latch”).

3. Run the PLC code inside OpenPLC (Linux):

git clone https://github.com/thiagoralves/OpenPLC_v3
cd OpenPLC_v3 && ./install.sh

4. Execute the test script using `pymodbus`:

from pymodbus.client import ModbusTcpClient
client = ModbusTcpClient('192.168.1.10')
client.write_coil(0, True)  emergency stop
import time; time.sleep(0.05)
status = client.read_coil(1)  motor contactor
assert status.bits[bash] == False, "AI code failed safety test"

5. Refactor – if the test fails, manually correct the AI logic (e.g., force reset priority) and re‑test.

4. Legal Landmines: Professional Engineer Liability and AI

Glenn Merrell’s warning is stark: no AI will ever certify a design that kills people. Professional Engineers (P.Eng) must demonstrate engineering due diligence when signing off AI‑generated PLC code. This requires version‑controlled forensic trails and comparative analysis between AI output and known‑safe reference logic.

Commands to establish a defensible audit trail (Windows/Linux):

  • Version control for ladder logic (export as XML from TIA Portal or CodeSys):
    git init plc_audit_repo
    git add .xml .scl
    git commit -m "Raw AI output from prompt v2.3"
    
  • Diff two AI‑generated revisions to spot injected malicious changes:
    diff --color=always old_plc.xml new_plc.xml | grep -E "^[<>]" | less
    
  • Generate SHA‑256 hash of final approved download file (proof of non‑repudiation):
    sha256sum final_download.hex >hash.txt
    

Step‑by‑step liability workflow:

  1. Store every AI prompt, output, and human modification in a tamper‑evident Git repo.
  2. Run a static analyzer (e.g., `plc‑static` – an open‑source tool for Structured Text) against AI code.

3. Document all discrepancies with physical I/O specifications.

  1. Have a second, independent engineer review the logic – never the same person who prompted the AI.

  2. Hardening Against AI‑Generated Malicious Logic: Network & Runtime Defenses

An AI could unknowingly (or intentionally, if the training data is poisoned) insert backdoor logic that opens a network port or disables safety interlocks. Implement defense in depth at the network and runtime layers.

Windows (netsh) and Linux (iptables) rules to restrict PLC access:

  • Linux (e.g., on a gateway between engineering workstation and PLC):
    Allow only specific engineering IP to access PLC on Modbus/TCP
    sudo iptables -A INPUT -p tcp --dport 502 -s 192.168.1.100 -j ACCEPT
    sudo iptables -A INPUT -p tcp --dport 502 -j DROP
    
  • Windows Defender Firewall (PowerShell as Admin):
    New-NetFirewallRule -DisplayName "Block_Modbus_Except_Engineering" `
    -Direction Inbound -Protocol TCP -LocalPort 502 `
    -RemoteAddress 192.168.1.100 -Action Allow
    New-NetFirewallRule -DisplayName "Block_All_Other_Modbus" `
    -Direction Inbound -Protocol TCP -LocalPort 502 -Action Block
    

Runtime integrity check – use `fciv` (Windows) or `aide` (Linux) to monitor PLC firmware changes:

 Linux (aide) – after downloading known‑good image
sudo aideinit
sudo aide --check | grep -i "plc"

6. Hands‑On: Analyzing a Malicious AI‑Generated PLC Payload

Assume an adversary uses a public LLM to generate a “harmless” pump control routine that actually contains a time‑bomb – after 10,000 cycles, it sets an output to overload the motor. Here’s how to detect it using simulation and anomaly detection.

Step‑by‑step detection lab:

  1. Request AI to produce a pump starter (prompt: “Write a Siemens S7 SCL function to start a pump when tank level > 20%”).
  2. Run the code in a sandboxed CodeSys runtime (Windows or Linux).
  3. Monitor register writes using `pymodbus` with a rolling counter:
    from pymodbus.client import ModbusTcpClient
    import matplotlib.pyplot as plt
    client = ModbusTcpClient('localhost')
    cycle_count = []
    for i in range(15000):
    client.write_register(100, i)  simulate cycle number
    status = client.read_holding_registers(200, 1).registers[bash]
    cycle_count.append(status)
    if i % 1000 == 0:
    print(f"Cycle {i}: output = {status}")
    plt.plot(cycle_count); plt.show()  look for sudden step change
    
  4. Look for non‑linear behavior – a malicious payload will deviate from expected linear/step function.
  5. Use Zeek (formerly Bro) IDS to alert on unusual Modbus write sequences:
    zeek -r plc_traffic.pcap modbus_detect.zeek
    

  6. Separation of Duties: Building Guardrails for AI in OT

Vivek Ponnada emphasizes that engineering and verification cannot be performed by the same agent. In practice, this means:
– One engineer prompts the AI and generates code.
– A different engineer (or an automated tool) reviews, tests, and approves.
– A human‑in‑the‑loop gate prevents direct download from AI to PLC.

Implementation (Linux / Windows CI pipeline example):

 .gitlab-ci.yml for PLC code approval
stages:
- ai_generate
- human_review
- deploy

ai_generate:
script:
- python3 call__api.py > generated.st
artifacts:
paths: [generated.st]

human_review:
script:
- ./review_tool.sh generated.st  fails unless flag is set
when: manual  requires button click

deploy:
script:
- sha256sum generated.st > signatures/
- scp generated.st engineer@plc-gateway:/downloads/

Digital signature verification on the PLC side (using OpenSSL):

 On engineering workstation
openssl dgst -sha256 -sign private.key -out generated.sig generated.st
 On PLC gateway
openssl dgst -sha256 -verify public.pem -signature generated.sig generated.st

What Undercode Say:

  • Key Takeaway 1: AI‑generated PLC code is not inherently malicious, but it is inherently ignorant of physical I/O realities and safety culture. Without structured testing (TDD, HIL simulation) and human forensic auditing, it introduces untraceable logic flaws.
  • Key Takeaway 2: The legal liability remains solely with the Professional Engineer. Version‑controlled audit trails, digital signatures, and separation of duties are not optional—they are the only defense against catastrophic liability when AI logic fails.

Analysis: The OT community is right to be alarmed. Unlike IT, where a software bug crashes an app, a PLC bug crashes a centrifuge or opens a valve. Current AI training corpora contain almost no secure PLC coding examples (e.g., the “Top20” list). Until benchmark datasets like ISA‑62443‑compliant ladder logic are created, any use of AI for control logic must be treated as an experimental hazard – not a productivity tool.

Prediction:

Within 18 months, the first publicly documented industrial incident involving AI‑generated PLC code will occur – likely a manufacturing line where an LLM omitted a state‑transition safety check. This will trigger urgent updates to IEC 61511 and ISA‑62443, mandating that any AI‑assisted code undergo independent formal verification. Tool vendors like Siemens and Rockwell will embed TDD frameworks directly into their IDEs, and cybersecurity insurers will demand proof of human‑in‑the‑loop review for AI‑generated logic. Until then, treat every line of AI‑suggested ladder logic as a potential zero‑day.

▶️ Related Video (78% Match):

🎯Let’s Practice For Free:

IT/Security Reporter URL:

Reported By: Https: – 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