Skip to content

13.1 Network Attacks and Defense

The previous part covered industrial networking: protocols, topologies, MRP, and Hirschmann switches. All of that assumes the network carries legitimate traffic. In practice, networks face attacks that exploit protocol weaknesses. Understanding attacks at the packet level enables you to build effective defenses and detect attacks in progress.

A firewall rule that blocks “bad traffic” is only as good as the engineer’s understanding of what bad traffic looks like. Knowing how a SYN flood consumes server resources, how ARP poisoning redirects traffic, and how MAC flooding bypasses switch security transforms abstract threats into concrete, detectable patterns.

Before examining specific attacks, define the core terms that security discussions rely on.

TermDefinition
VulnerabilityA weakness in a system (unpatched software, default password, open port)
ExploitCode or technique that takes advantage of a vulnerability
ThreatA potential event that exploits a vulnerability (attacker, malware, natural disaster)
RiskThe probability of a threat exploiting a vulnerability multiplied by the impact
CIA TriadThe three goals of security: Confidentiality (only authorized access), Integrity (data is accurate and unmodified), Availability (systems are accessible when needed)
Attack surfaceThe total set of points where an attacker can interact with a system
Zero-dayA vulnerability that has no patch available because the vendor is unaware of it

Every attack in this chapter targets one or more elements of the CIA triad. A SYN flood targets availability. ARP poisoning targets confidentiality and integrity. Understanding which element is at risk guides the choice of defense.

A SYN flood exploits the TCP three-way handshake. The attacker sends SYN packets with spoofed source IPs. The server allocates a TCB (Transmission Control Block) for each half-open connection and waits for the ACK that never comes. The connection table fills up and the server refuses legitimate connections.

SYN cookies (RFC 4987) mitigate this: the server encodes connection state in the sequence number instead of allocating a TCB. No memory is consumed until the ACK arrives.

The following script detects SYN floods by counting SYN packets per source IP per second.

from scapy.all import sniff, IP, TCP
from collections import defaultdict
import time
syn_counts: dict[str, list[float]] = defaultdict(list)
THRESHOLD = 100
def detect_syn_flood(pkt):
if not (pkt.haslayer(TCP) and pkt[TCP].flags == "S"):
return
src = pkt[IP].src
now = time.time()
syn_counts[src].append(now)
syn_counts[src] = [t for t in syn_counts[src] if now - t < 1.0]
if len(syn_counts[src]) > THRESHOLD:
print(f"SYN flood from {src}: {len(syn_counts[src])} SYNs/sec")
sniff(iface="eth0", filter="tcp[tcpflags] & tcp-syn != 0 and "
"tcp[tcpflags] & tcp-ack == 0",
prn=detect_syn_flood, store=False)

A source exceeding 100 SYNs per second without completing handshakes is almost certainly an attack. The script makes this visible in real time on a mirror port.

SYN floods target servers. ARP poisoning targets the trust model of Layer 2.

ARP has no authentication. Any device sends a gratuitous ARP reply claiming to own any IP address. An attacker sends ARP replies mapping the gateway’s IP to the attacker’s MAC. All traffic from the victim flows through the attacker.

Defend with Dynamic ARP Inspection (DAI) on managed switches, which validates ARP packets against the DHCP snooping binding table. On Hirschmann switches, enable DAI on access ports at Security → ARP Inspection.

A switch maintains a CAM table (Content Addressable Memory) that maps MAC addresses to ports. The table has a fixed size (typically 8,000 to 32,000 entries on industrial switches). A MAC flooding attack exploits this limit.

The attacker sends thousands of Ethernet frames per second, each with a random, unique source MAC address. The switch learns each new MAC and adds it to the CAM table. When the table fills, the switch can no longer learn new addresses. For any frame destined to a MAC not in the table, the switch floods the frame to all ports, exactly like a hub. The attacker now sees all traffic on the segment.

Configure port security to limit the number of MAC addresses learned per port. On Hirschmann HiOS, navigate to Security → Port Security and set the maximum MAC addresses per port to the expected number of devices (typically 1 for an access port connected to a single device).

The following script detects MAC flooding by counting new MAC addresses per second on a monitored interface.

from scapy.all import sniff, Ether
import time
known_macs: set[str] = set()
new_mac_times: list[float] = []
THRESHOLD = 50 # new MACs per second
def detect_mac_flood(pkt):
if not pkt.haslayer(Ether):
return
src = pkt[Ether].src
if src in known_macs:
return
known_macs.add(src)
now = time.time()
new_mac_times.append(now)
# Keep only the last second
while new_mac_times and now - new_mac_times[0] > 1.0:
new_mac_times.pop(0)
if len(new_mac_times) > THRESHOLD:
print(f"MAC flood detected: {len(new_mac_times)} new MACs/sec "
f"(total unique: {len(known_macs)})")
sniff(iface="eth0", prn=detect_mac_flood, store=False)

A normal network learns a few new MACs per minute. Fifty new MACs per second indicates a MAC flooding attack.

MAC flooding turns a switch into a hub. VLAN hopping crosses VLAN boundaries that are supposed to be isolated.

VLAN hopping allows an attacker to send traffic to a VLAN they have no access to. Two techniques exist: double tagging and switch spoofing.

The attacker crafts a frame with two 802.1Q tags. The outer tag matches the native VLAN of the trunk port. The inner tag specifies the target VLAN.

Step by step:

  1. The attacker connects to an access port on VLAN 1 (the native VLAN)
  2. The attacker sends a frame with two 802.1Q tags: outer = VLAN 1, inner = VLAN 20
  3. Switch 1 receives the frame on an access port. It sees the outer tag matches the native VLAN and strips it
  4. The frame now has one tag: VLAN 20. Switch 1 forwards it out the trunk port
  5. Switch 2 receives the frame tagged VLAN 20 and delivers it to VLAN 20 ports
  6. The victim receives the frame. The attack is one-way (the victim’s reply stays in VLAN 20)

The attacker configures their NIC to negotiate a trunk link using DTP (Dynamic Trunking Protocol). If the switch port is set to “dynamic auto” or “dynamic desirable,” it forms a trunk with the attacker. The attacker now has access to all VLANs on the trunk.

Defend against both attacks by:

  • Setting the native VLAN to an unused VLAN (not VLAN 1) on all trunk ports
  • Explicitly tagging the native VLAN on trunk ports (vlan trunk native tagged)
  • Disabling DTP on all ports (set ports to static access or static trunk)
  • Never using VLAN 1 for any production traffic

The following script uses Scapy to craft a double-tagged frame, demonstrating the concept for testing purposes.

from scapy.all import Ether, Dot1Q, IP, ICMP, sendp
# Double-tagged frame: outer VLAN 1 (native), inner VLAN 20 (target)
frame = (
Ether(dst="ff:ff:ff:ff:ff:ff")
/ Dot1Q(vlan=1) # Outer tag: native VLAN (stripped by first switch)
/ Dot1Q(vlan=20) # Inner tag: target VLAN (forwarded by second switch)
/ IP(dst="192.168.20.1")
/ ICMP()
)
print(f"Frame size: {len(frame)} bytes")
print(f"Outer VLAN: {frame[Dot1Q].vlan}")
print(f"Inner VLAN: {frame[Dot1Q:2].vlan}")
# sendp(frame, iface="eth0") # Uncomment to send (lab only)

A rogue DHCP server responds to DHCPDISCOVER messages with incorrect configuration: a wrong gateway (routing traffic through the attacker), wrong DNS servers (redirecting name resolution to attacker-controlled servers), or a short lease time (causing frequent renewals that disrupt connectivity).

The following script monitors DHCP traffic and alerts when it detects DHCPOFFER messages from unauthorized server IPs.

from scapy.all import sniff, DHCP, BOOTP, IP
AUTHORIZED_SERVERS = {"192.168.1.1", "192.168.1.2"}
def detect_rogue_dhcp(pkt):
if not pkt.haslayer(DHCP):
return
options = {opt[0]: opt[1] for opt in pkt[DHCP].options if isinstance(opt, tuple)}
msg_type = options.get("message-type", 0)
if msg_type != 2: # DHCPOFFER
return
server_ip = pkt[IP].src
server_id = str(options.get("server_id", server_ip))
if server_id not in AUTHORIZED_SERVERS:
offered = pkt[BOOTP].yiaddr
print(f"ROGUE DHCP SERVER: {server_id} offering {offered}")
print(f" gateway={options.get('router', 'none')} "
f"dns={options.get('name_server', 'none')}")
sniff(iface="eth0", filter="udp port 67 or udp port 68",
prn=detect_rogue_dhcp, store=False)

Defend with DHCP snooping on managed switches. DHCP snooping designates specific ports as trusted (connected to the legitimate DHCP server) and drops DHCPOFFER messages from untrusted ports.

DNS cache poisoning injects false records into a recursive resolver’s cache. The attacker sends forged DNS responses with a spoofed source IP (matching the authoritative server) and a guessed transaction ID. If the forged response arrives before the legitimate one, the resolver caches the false record and serves it to all clients.

DNSSEC (DNS Security Extensions) adds cryptographic signatures to DNS records. The resolver validates the signature against the zone’s public key. A forged response without a valid signature is rejected. Deploy DNSSEC on internal zones and configure resolvers to validate signatures.

Additional defenses: use randomized source ports for DNS queries (makes transaction ID guessing harder), restrict recursive resolvers to internal clients only, and monitor for unexpected changes in DNS responses.

Social engineering attacks target people, not protocols. They bypass technical controls by manipulating human behavior.

AttackMethodDefense
PhishingFraudulent email with malicious link or attachmentSecurity awareness training, email filtering
Spear phishingTargeted phishing aimed at a specific individualVerify requests through a separate channel
VishingVoice phishing via phone callNever provide credentials over the phone
TailgatingFollowing an authorized person through a secured doorBadge-only access, security awareness
Shoulder surfingWatching someone enter a password or PINPrivacy screens, awareness of surroundings
PretextingCreating a fabricated scenario to extract informationVerify identity before sharing information

In OT environments, social engineering is particularly dangerous because operators have physical access to control systems. An attacker posing as a vendor technician who gains physical access to the control room can plug a USB drive into an engineering workstation or connect a laptop to the OT network.

MAC flooding turns switches into hubs

Limit MAC addresses per port with port security. Monitor for sudden spikes in new MAC addresses.

VLAN hopping requires two changes to prevent

Change the native VLAN to an unused ID and disable DTP on all ports. These two changes eliminate both double-tagging and switch spoofing.

Social engineering bypasses all technical controls

Security awareness training is a technical control. Conduct it annually and test with simulated phishing campaigns.

This chapter covered general network attacks. OT networks face additional, specialized threats: malware that targets PLCs, attacks on industrial protocols, and the unique challenges of securing systems that cannot be patched. The next chapter covers OT-specific threats and the IEC 62443 framework for defending against them.

  • RFC 4987 — TCP SYN Flooding Attacks and Common Mitigations (IETF, 2007)
  • RFC 4033 — DNS Security Introduction and Requirements (IETF, 2005)
  • CompTIA Network+ N10-009 Exam Objectives, Domain 4: Network Security
  • Tanenbaum, A. S., & Wetherall, D. J. (2011). Computer Networks (5th ed.). Pearson.