# 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
