76 lines
2.6 KiB
Markdown
76 lines
2.6 KiB
Markdown
# Cyberia Grid -- Solution
|
|
|
|
## Overview
|
|
EtherNet/IP server simulating a PLC at Cyberia nightclub. The controller
|
|
manages power infrastructure and contains hidden tags with encoded KIDS
|
|
experiment data. A write-triggered "Psyche Processor" reveals the flag.
|
|
|
|
## Steps
|
|
|
|
### 1. Connect and Enumerate Tags
|
|
Connect to the EtherNet/IP server on port 44818. List all available tags.
|
|
|
|
```bash
|
|
# Using cpppo client
|
|
python -m cpppo.server.enip.client --address HOST:44818 \
|
|
'Zone_Main_Power' 'Zone_VIP_Power' 'Zone_Basement_Power' \
|
|
'Sound_System_dB' 'BPM' 'Lighting_Main[0-7]' \
|
|
'KIDS_Subject[0-15]' 'Knights_Cipher[0-3]' \
|
|
'Psyche_Processor[0-3]' 'Psyche_Status' 'Decoded_Output'
|
|
```
|
|
|
|
### 2. Analyze Infrastructure Tags
|
|
- `Zone_Main_Power = 1`, `Zone_VIP_Power = 1` -- normal
|
|
- `Zone_Basement_Power = 0` -- basement is OFF (suspicious)
|
|
- `Sound_System_dB = 95`, `BPM = 140`
|
|
- `Lighting_Main = [255, 200, 180, 150, 100, 80, 60, 40]`
|
|
|
|
### 3. Analyze Hidden Tags
|
|
- `KIDS_Subject[0-15]`: 16 DINTs containing XOR-encoded flag data
|
|
- `Knights_Cipher[0-3]`: partial XOR key `[0x4B, 0x6E, 0x69, 0]` -- 4th byte is missing!
|
|
- `Psyche_Processor[0-3]`: all zeros -- awaiting activation
|
|
- `Psyche_Status = "DORMANT"`
|
|
|
|
### 4. Derive Activation Sequence
|
|
The 4 Psyche_Processor values are derived from infrastructure tag values:
|
|
|
|
| Index | Formula | Value |
|
|
|-------|---------|-------|
|
|
| 0 | `Zone_Basement_Power XOR BPM` | `0 ^ 140 = 140` |
|
|
| 1 | `Sound_System_dB` | `95` |
|
|
| 2 | `sum(Lighting_Main) % 256` | `1065 % 256 = 17` |
|
|
| 3 | `0x1337` (hacker constant) | `4919` |
|
|
|
|
### 5. Activate Psyche Processor
|
|
Write `[140, 95, 17, 4919]` to `Psyche_Processor[0-3]`.
|
|
|
|
```python
|
|
from cpppo.server.enip.get_attribute import proxy_simple as device
|
|
with device(host="HOST", port=44818) as via:
|
|
for i, val in enumerate([140, 95, 17, 4919]):
|
|
via.write(via.parameter_substitution(f"Psyche_Processor[{i}]"), val)
|
|
```
|
|
|
|
### 6. Read Flag
|
|
After the PLC scan cycle (~500ms), read `Decoded_Output`:
|
|
|
|
```python
|
|
flag = via.read(via.parameter_substitution("Decoded_Output"))
|
|
print(flag)
|
|
```
|
|
|
|
Also: `Knights_Cipher[3]` is now populated (0x67 = 'g'), completing the
|
|
key `"Knig"` which can also be used to manually XOR-decode `KIDS_Subject`.
|
|
|
|
## Key Insights
|
|
- `Zone_Basement_Power = 0` is the first hint that something is hidden underground
|
|
- The 0x1337 constant echoes the Operating Room challenge pattern
|
|
- The PLC scan cycle polling pattern mimics real industrial controller behavior
|
|
- Without authentication, anyone can read/write tags -- a common EtherNet/IP vulnerability
|
|
|
|
## Flag
|
|
`ESPILON{cyb3r14_ps7ch3_pr0c3ss0r}`
|
|
|
|
## Author
|
|
Eun0us
|