# 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