79 lines
2.7 KiB
Markdown
79 lines
2.7 KiB
Markdown
# Protocol Seven -- Solution
|
|
|
|
## Overview
|
|
Multi-protocol challenge requiring cross-referencing three OT protocols.
|
|
Eiri Masami distributed Protocol Seven's components across BACnet, OPC-UA,
|
|
and EtherNet/IP. Players must extract data from all three and combine
|
|
them to decrypt the flag.
|
|
|
|
## Architecture
|
|
|
|
| Layer | Protocol | Port | Provides |
|
|
|-------|----------|------|----------|
|
|
| 1 | BACnet/IP | 47809/udp | XOR encryption key (8 bytes) |
|
|
| 2 | OPC-UA | 4841/tcp | Encrypted payload (32 bytes) |
|
|
| 3 | EtherNet/IP | 44819/tcp | Rotation nonce (integer) |
|
|
|
|
## Steps
|
|
|
|
### 1. Port Discovery
|
|
Scan the target -- three open ports: 47809/udp, 4841/tcp, 44819/tcp.
|
|
|
|
### 2. Layer 1 -- BACnet Key Extraction
|
|
Send WhoIs to port 47809 → IAm from device 7777.
|
|
Read object-list: 8 AnalogValue objects named `Harmonic_0` through `Harmonic_7`.
|
|
|
|
Read the device description: **"Key Harmonic Array -- integer components matter"**
|
|
|
|
Read presentValue of each harmonic:
|
|
```
|
|
Harmonic_0 = 69.14 -> int(69) = 'E'
|
|
Harmonic_1 = 105.92 -> int(105) = 'i'
|
|
Harmonic_2 = 114.37 -> int(114) = 'r'
|
|
Harmonic_3 = 105.68 -> int(105) = 'i'
|
|
Harmonic_4 = 95.44 -> int(95) = '_'
|
|
Harmonic_5 = 75.81 -> int(75) = 'K'
|
|
Harmonic_6 = 101.22 -> int(101) = 'e'
|
|
Harmonic_7 = 121.55 -> int(121) = 'y'
|
|
```
|
|
|
|
**XOR key = `Eiri_Key` (8 bytes)**
|
|
|
|
### 3. Layer 2 -- OPC-UA Payload Extraction
|
|
Connect anonymously to `opc.tcp://HOST:4841/protocol7/`.
|
|
Read `Server.NamespaceArray` → find `urn:protocol-seven:payload`.
|
|
|
|
Browse `Protocol7_Vault`:
|
|
- `Payload_Encrypted`: 32-byte ByteString (the ciphertext)
|
|
- `Layer_Info`: "Payload encrypted with 8-byte repeating XOR key -- see BACnet harmonics"
|
|
- `IV_Hint`: "Rotation offset from CIP controller -- read NONCE tag"
|
|
|
|
### 4. Layer 3 -- EtherNet/IP Nonce Extraction
|
|
Connect to EtherNet/IP on port 44819. Read tags:
|
|
- `NONCE = 3` (the rotation offset)
|
|
- `Layer_Hint`: "Rotate payload by NONCE bytes before XOR decryption"
|
|
- `Assembly_Check = [47809, 4841, 44819]` (confirms all three ports)
|
|
|
|
### 5. Decryption
|
|
```python
|
|
# XOR payload with repeating key
|
|
xored = bytes(payload[i] ^ key[i % 8] for i in range(32))
|
|
# Rotate right by NONCE (undo the left rotation used during encryption)
|
|
flag = xored[-nonce:] + xored[:-nonce]
|
|
# Strip null padding
|
|
print(flag.rstrip(b'\x00').decode())
|
|
```
|
|
|
|
## Key Insights
|
|
- The BACnet device description explicitly says "integer components matter"
|
|
- The OPC-UA hints point directly to BACnet and EtherNet/IP
|
|
- The EtherNet/IP `Assembly_Check` tag confirms the three-port architecture
|
|
- `Eiri_Key` as the XOR key is a mnemonic hint (Eiri Masami is the creator)
|
|
- The challenge teaches multi-protocol OT environments and data cross-referencing
|
|
|
|
## Flag
|
|
`ESPILON{pr0t0c0l_7_m3rg3_c0mpl3t3}`
|
|
|
|
## Author
|
|
Eun0us
|