Skip to main content
performing-s7comm-protocol-security-analysis Perform security analysis of Siemens S7comm and S7CommPlus protocols used by SIMATIC S7 PLCs to identify vulnerabilities including replay attacks, integrity bypass, unauthorized CPU stop commands, and program download manipulation exploiting weaknesses in S7-300, S7-400, S7-1200, and S7-1500 controllers.
Ir a la instalación Skills Marketplace Descubre y explora habilidades de IA creadas por la comunidad.
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Copiar promptMostrar detalles del prompt Un comando directo omite el prompt de revisión. Revisa el origen antes de ejecutarlo.
npx skills add https://github.com/mukul975/Anthropic-Cybersecurity-Skills --skill performing-s7comm-protocol-security-analysisEl comando permanece en una sola línea. Desplázate horizontalmente para revisarlo antes de copiarlo.
¿Prefieres una copia local? Descarga los archivos que SkillsMP tiene disponibles ahora.
Descargar Zip Descargando... Más de este repositorio abusing-dpapi-for-credential-access Extract and decrypt Windows DPAPI-protected secrets (Credential Manager, browser logins/cookies, Wi-Fi credentials, KeePass keys) online or offline using SharpDPAPI, SharpChrome, Mimikatz, or Impacket's dpapi.py, including domain-wide decryption via the DPAPI backup key. Use during authorized red-team credential-access engagements after gaining a foothold or when triaging DPAPI blobs pulled from a host.
abusing-shadow-credentials-for-privesc Take over Active Directory accounts by writing attacker-controlled public keys to msDS-KeyCredentialLink (Shadow Credentials) with pyWhisker, Whisker, or Certipy, then authenticate via PKINIT to recover the target's NT hash without a password reset. Use when BloodHound shows GenericWrite/GenericAll/AddKeyCredentialLink over a target, as a stealthier alternative to ForceChangePassword, during authorized red-team engagements.
acquiring-disk-image-with-dd-and-dcfldd Create forensically sound bit-for-bit disk images with dd or dcfldd on a Linux forensic workstation, preserving evidence integrity through hash verification (MD5/SHA) during acquisition. Use when imaging a suspect drive, USB device, or memory card for investigation, preserving volatile disk evidence during incident response, or producing a verified copy for legal or law-enforcement proceedings before any destructive analysis.
Explorador de archivos
4 archivos Ocupaciones relacionadas SOC
Basado en la clasificación ocupacional SOC
name performing-s7comm-protocol-security-analysis description Perform security analysis of Siemens S7comm and S7CommPlus protocols used by SIMATIC S7 PLCs to identify vulnerabilities including replay attacks, integrity bypass, unauthorized CPU stop commands, and program download manipulation exploiting weaknesses in S7-300, S7-400, S7-1200, and S7-1500 controllers.
domain cybersecurity subdomain ot-ics-security tags ["ot-security","ics","s7comm","siemens","plc-security","protocol-analysis","scada","vulnerability-assessment"] version 1.0 author mahipal license Apache-2.0 nist_csf ["PR.IR-01","DE.CM-01","ID.AM-05","GV.OC-02"] mitre_attack ["T1078","T1190","T1059","T1685.002","T1685.005"]
Performing S7comm Protocol Security Analysis
When to Use
When assessing the security posture of Siemens SIMATIC S7 PLC environments
When building detection rules for S7comm-based attacks against S7-300/400/1200/1500 controllers
When performing a security audit of Siemens Step 7/TIA Portal communications
When investigating suspected unauthorized access to Siemens PLC programs
When evaluating S7CommPlus integrity mechanisms and their bypass potential
Do not use for scanning production Siemens PLCs without authorization and a test plan (this can crash controllers), for non-Siemens protocol analysis (see detecting-modbus-command-injection-attacks for Modbus), or for modifying PLC programs in a production environment.
Prerequisites
Network access to the S7comm communication segment (TCP port 102)
Wireshark with S7comm dissector or Zeek with S7comm protocol analyzer
Authorized access for security testing (never scan production PLCs without authorization)
Knowledge of the Siemens PLC models and firmware versions in scope
Understanding of S7comm protocol structure (COTP, S7 PDU, function codes)
Workflow
Step 1: Analyze S7comm Traffic and Identify Vulnerabilities
"""S7comm Protocol Security Analyzer.
Analyzes Siemens S7comm protocol traffic to identify security
vulnerabilities, unauthorized access patterns, and potential
attack indicators against SIMATIC S7 PLCs.
"""
import struct
import sys
import json
from collections import defaultdict
from datetime import datetime
from typing import Dict , List , Optional
try :
from scapy.all import rdpcap, IP, TCP
except ImportError:
print ("Install scapy: pip install scapy" )
sys.exit(1 )
S7_ROSCTR = {
: ,
: ,
: ,
: ,
}
S7_FUNCTIONS = {
: ,
: ,
: ,
: ,
: ,
: ,
: ,
: ,
: ,
: ,
: ,
: ,
}
CRITICAL_FUNCTIONS = { , , , , , }
PROGRAM_FUNCTIONS = { , , , , , }
:
( ):
.timestamp = datetime.now().isoformat()
.severity = severity
.finding_type = finding_type
.src_ip = src_ip
.dst_ip = dst_ip
.function = function
.description = description
.cve = cve
.recommendation = recommendation
:
( ):
.findings: [S7commSecurityFinding] = []
.sessions: [ , ] = defaultdict( : {
: ,
: (),
: ,
: ,
: ,
: ,
: ,
})
.authorized_engineering: = ()
.packet_count =
( ):
.authorized_engineering = (ips)
( ) -> [ ]:
(payload) < :
tpkt_version = payload[ ]
tpkt_version != :
tpkt_length = struct.unpack( , payload[ : ])[ ]
(payload) < :
cotp_length = payload[ ]
cotp_type = payload[ ]
s7_offset = + + cotp_length
(payload) < s7_offset + :
protocol_id = payload[s7_offset]
protocol_id != :
rosctr = payload[s7_offset + ]
redundancy = struct.unpack( , payload[s7_offset + :s7_offset + ])[ ]
pdu_ref = struct.unpack( , payload[s7_offset + :s7_offset + ])[ ]
param_length = struct.unpack( , payload[s7_offset + :s7_offset + ])[ ]
data_length = struct.unpack( , payload[s7_offset + :s7_offset + ])[ ]
result = {
: rosctr,
: S7_ROSCTR.get(rosctr, ),
: pdu_ref,
: param_length,
: data_length,
}
param_offset = s7_offset +
rosctr ( , ) param_length > (payload) > param_offset:
func_code = payload[param_offset]
result[ ] = func_code
result[ ] = S7_FUNCTIONS.get(func_code, )
result
( ):
.packet_count +=
pkt.haslayer(IP) pkt.haslayer(TCP):
tcp = pkt[TCP]
tcp.dport != tcp.sport != :
payload = (tcp.payload)
payload:
s7 = .parse_s7comm(payload)
s7:
src_ip = pkt[IP].src
dst_ip = pkt[IP].dst
session_key =
session = .sessions[session_key]
session[ ] +=
session[ ] :
session[ ] = (pkt.time)
session[ ] = (pkt.time)
func_code = s7.get( )
func_code :
session[ ].add(func_code)
tcp.dport == func_code CRITICAL_FUNCTIONS:
.authorized_engineering src_ip .authorized_engineering:
.findings.append(S7commSecurityFinding(
severity= ,
finding_type= ,
src_ip=src_ip, dst_ip=dst_ip,
function=s7.get( , ),
description=(
),
recommendation= ,
))
func_code == :
session[ ] +=
.findings.append(S7commSecurityFinding(
severity= ,
finding_type= ,
src_ip=src_ip, dst_ip=dst_ip,
function= ,
description= ,
cve= ,
recommendation= ,
))
func_code ( , , ):
session[ ] +=
.findings.append(S7commSecurityFinding(
severity= ,
finding_type= ,
src_ip=src_ip, dst_ip=dst_ip,
function=s7.get( , ),
description=(
),
cve= ,
recommendation= ,
))
func_code == :
session[ ] +=
func_code ( , , ):
.findings.append(S7commSecurityFinding(
severity= ,
finding_type= ,
src_ip=src_ip, dst_ip=dst_ip,
function=s7.get( , ),
description= ,
recommendation= ,
))
( ):
vuln_checks = [
{
: ,
: ,
: ,
: ,
: ,
},
{
: ,
: ,
: ,
: ,
: ,
},
{
: ,
: ,
: ,
: ,
: ,
},
{
: ,
: ,
: ,
: ,
: ,
},
]
vuln_checks
( ):
( )
( )
( )
( )
( )
( )
( )
( )
key, session .sessions.items():
funcs = [S7_FUNCTIONS.get(f, ) f session[ ]]
( )
( )
( )
( )
( )
( )
.findings:
( )
f .findings:
( )
( )
( )
( )
f.cve:
( )
f.recommendation:
( )
( )
vuln .check_known_vulnerabilities():
( )
( )
( )
( )
__name__ == :
analyzer = S7commAnalyzer()
analyzer.set_authorized_stations([ , ])
(sys.argv) >= :
( )
packets = rdpcap(sys.argv[ ])
pkt packets:
analyzer.analyze_packet(pkt)
analyzer.generate_report()
:
( )
( )
0x01
"Job (Request)"
0x02
"Ack"
0x03
"Ack_Data (Response)"
0x07
"Userdata"
0x00
"CPU services"
0x04
"Read Variable"
0x05
"Write Variable"
0x1A
"Request Download (Program)"
0x1B
"Download Block"
0x1C
"Download Ended"
0x1D
"Start Upload (Read Program)"
0x1E
"Upload Block"
0x1F
"Upload Ended"
0x28
"PI Service (Start/Stop CPU)"
0x29
"PLC Stop"
0xF0
"Setup Communication"
0x1A
0x1B
0x1C
0x28
0x29
0x05
0x1A
0x1B
0x1C
0x1D
0x1E
0x1F
class
S7commSecurityFinding
"""Represents a security finding in S7comm traffic."""
def
__init__
self, severity: str , finding_type: str , src_ip: str ,
dst_ip: str , function: str , description: str ,
cve: str = "" , recommendation: str = ""
self
self
self
self
self
self
self
self
self
class
S7commAnalyzer
"""Analyzes S7comm protocol traffic for security vulnerabilities."""
def
__init__
self
self
List
self
Dict
str
dict
lambda
"packets"
0
"functions_seen"
set
"writes"
0
"program_downloads"
0
"cpu_commands"
0
"first_seen"
None
"last_seen"
None
self
set
set
self
0
def
set_authorized_stations
self, ips: List [str ]
"""Set list of authorized engineering workstation IPs."""
self
set
def
parse_s7comm
self, payload: bytes
Optional
dict
"""Parse S7comm protocol data from TCP payload."""
if
len
4
return
None
0
if
3
return
None
">H"
2
4
0
if
len
7
return
None
4
5
4
1
if
len
10
return
None
if
0x32
return
None
1
">H"
2
4
0
">H"
4
6
0
">H"
6
8
0
">H"
8
10
0
"rosctr"
"rosctr_name"
f"Unknown (0x{rosctr:02x} )"
"pdu_ref"
"param_length"
"data_length"
10
if
in
0x01
0x03
and
0
and
len
"function_code"
"function_name"
f"Unknown (0x{func_code:02x} )"
return
def
analyze_packet
self, pkt
"""Analyze a packet for S7comm security issues."""
self
1
if
not
or
not
return
if
102
and
102
return
bytes
if
not
return
self
if
not
return
f"{src_ip} ->{dst_ip} "
self
"packets"
1
if
"first_seen"
is
None
"first_seen"
float
"last_seen"
float
"function_code"
if
is
not
None
"functions_seen"
if
102
and
in
if
self
and
not
in
self
self
"CRITICAL"
"UNAUTHORIZED_ENGINEERING_ACCESS"
"function_name"
"Unknown"
f"Critical S7comm operation from unauthorized source {src_ip} . "
f"Function: {s7.get('function_name' )} . Only authorized TIA Portal "
f"workstations should issue these commands."
"Block unauthorized sources at industrial firewall. Investigate source host for compromise."
if
0x29
"cpu_commands"
1
self
"CRITICAL"
"CPU_STOP_COMMAND"
"PLC CPU Stop (0x29)"
f"CPU STOP command sent to PLC at {dst_ip} . This halts PLC program execution."
"MITRE T0881 - Service Stop"
"Verify if this is an authorized maintenance action. If not, isolate source immediately."
if
in
0x1A
0x1B
0x1C
"program_downloads"
1
self
"CRITICAL"
"PROGRAM_DOWNLOAD"
"function_name"
"Download"
f"PLC program download operation to {dst_ip} . "
f"This modifies the running control logic on the PLC."
"MITRE T0843 - Program Download"
"Verify against change management records. Compare with known-good program backup."
if
0x05
"writes"
1
if
in
0x1D
0x1E
0x1F
self
"HIGH"
"PROGRAM_UPLOAD_EXFILTRATION"
"function_name"
"Upload"
f"PLC program upload (read) from {dst_ip} . Source {src_ip} is extracting PLC control logic."
"Verify if this is authorized maintenance. Unauthorized uploads indicate reconnaissance."
def
check_known_vulnerabilities
self
"""Check for known Siemens S7 vulnerabilities based on observed behavior."""
"name"
"S7-300/400 Replay Attack Vulnerability"
"cve"
"CVE-2019-13945"
"description"
"S7-300/400 PLCs lack integrity checks on S7comm sessions, allowing replay attacks"
"affected"
"S7-300, S7-400 (all firmware versions)"
"severity"
"HIGH"
"name"
"S7CommPlus Integrity Bypass"
"cve"
"Research finding (Biham et al.)"
"description"
"S7CommPlusV3 integrity mechanism can be bypassed by attackers who can observe one legitimate session"
"affected"
"S7-1200 (< V4.5), S7-1500 (< V2.9)"
"severity"
"HIGH"
"name"
"Unpatchable Hardware Root of Trust"
"cve"
"CVE-2022-38773"
"description"
"Hardware vulnerability allows bypassing protected boot and persistent firmware modification"
"affected"
"S7-1500 (specific hardware revisions)"
"severity"
"CRITICAL"
"name"
"Remote DoS via Port 102"
"cve"
"CVE-2019-10929"
"description"
"Specially crafted packets on TCP port 102 can crash S7 PLCs remotely"
"affected"
"S7-300, S7-400, S7-1200, S7-1500 (specific firmware)"
"severity"
"HIGH"
return
def
generate_report
self
"""Generate comprehensive S7comm security analysis report."""
print
f"\n{'=' *70 } "
print
"S7COMM PROTOCOL SECURITY ANALYSIS REPORT"
print
f"{'=' *70 } "
print
f"Analysis Time: {datetime.now().isoformat()} "
print
f"Packets Analyzed: {self.packet_count} "
print
f"S7comm Sessions: {len (self.sessions)} "
print
f"Security Findings: {len (self.findings)} "
print
f"\n--- SESSION SUMMARY ---"
for
in
self
f"0x{f:02x} "
for
in
"functions_seen"
print
f"\n {key} "
print
f" Packets: {session['packets' ]} "
print
f" Functions: {', ' .join(funcs)} "
print
f" Writes: {session['writes' ]} "
print
f" Program Downloads: {session['program_downloads' ]} "
print
f" CPU Commands: {session['cpu_commands' ]} "
if
self
print
f"\n--- SECURITY FINDINGS ---"
for
in
self
print
f"\n [{f.severity} ] {f.finding_type} "
print
f" Source: {f.src_ip} -> {f.dst_ip} "
print
f" Function: {f.function} "
print
f" Detail: {f.description} "
if
print
f" Reference: {f.cve} "
if
print
f" Action: {f.recommendation} "
print
f"\n--- KNOWN VULNERABILITY ASSESSMENT ---"
for
in
self
print
f"\n [{vuln['severity' ]} ] {vuln['name' ]} "
print
f" CVE: {vuln['cve' ]} "
print
f" Affected: {vuln['affected' ]} "
print
f" Detail: {vuln['description' ]} "
if
"__main__"
"10.10.2.50"
"10.10.2.51"
if
len
2
print
f"[*] Analyzing capture: {sys.argv[1 ]} "
1
for
in
else
print
"Usage: python s7comm_analyzer.py <capture.pcap>"
print
" Analyzes S7comm traffic for security vulnerabilities"
Key Concepts Term Definition S7comm Siemens proprietary protocol for communication with SIMATIC S7 PLCs over TCP port 102, layered on COTP/TPKT S7CommPlus Enhanced version of S7comm used by S7-1200/1500 with integrity protection mechanisms ROSCTR Remote Operating Service Control field in S7comm header indicating PDU type (Job, Ack, Ack_Data, Userdata) TIA Portal Totally Integrated Automation Portal -- Siemens engineering software for programming S7 PLCs CPU Stop (0x29) S7comm function that halts PLC program execution, a critical denial-of-service operation Program Download (0x1A) S7comm function initiating transfer of new control logic to a PLC, representing the highest risk operation
Common Scenarios
Scenario: Unauthorized PLC Program Modification Context : A Dragos sensor alerts on S7comm program download traffic from an IP address that is not the authorized TIA Portal engineering workstation.
Capture the complete S7comm session for forensic analysis
Identify the source host and determine if it is compromised or rogue
Compare the current PLC program against the last known-good backup
Check if the PLC CPU mode was changed (RUN to STOP to PROGRAM)
If the program was modified, restore from verified backup
Investigate the attack chain -- how did the attacker reach the S7comm network segment
Implement S7comm access protection (know-how protection, access passwords) on all PLCs
Pitfalls : S7-300/400 PLCs have no cryptographic integrity protection -- any device that can reach TCP port 102 can send commands. Do not rely solely on PLC passwords as they are transmitted in cleartext in S7comm (not S7CommPlus). Network segmentation is the primary defense.
Output Format S7COMM SECURITY ANALYSIS REPORT
===================================
Date: YYYY-MM-DD
Scope: [Network segments analyzed]
SESSION INVENTORY:
Engineering stations: [count and IPs]
PLCs communicating: [count and IPs]
Unauthorized sources: [count]
CRITICAL FINDINGS:
CPU Stop commands: [count]
Program downloads: [count from unauthorized sources]
Replay attack potential: [assessment]
VULNERABILITY ASSESSMENT:
S7-300/400 (no integrity): [count of affected PLCs]
S7-1200/1500 (S7CommPlus): [firmware assessment]
Known CVEs applicable: [list]
RECOMMENDATIONS:
1. [Highest priority remediation]
2. [Network segmentation improvement]
3. [Monitoring enhancement]