Rating:

**This is a possible solution, provided by Syskron Security.**

All of the following steps are described in the files you got for the challenge.

## Generate the private keys for both PLCs
Generate the private keys for both PLCs, using the BB Key generator (PLC1: B999100 → 42434554555666; PLC2: B999107 → 49434554555666). The deviceIds are listed in the files libreplc-config-plc1.json and libreplc-config-plc2.json.

## Derive the shared key
Derive the relevant shared key for the communication (the content of libreplc-config-shared-keys.json can't be read, but the results are already there after step 1): B999100 comes first since the number is lower → 4243455455566649434554555666. However, we need to omit the last two digits → 424345545556494345545556.

## Decode all exchanges messages
Decode the messages in the .out files (from hex, from MessagePack):

M1:

{
"protocol": "epes",
"protocolVersion": 2,
"protocolMessage": "SYN",
"scryptSalt": "dGhlTW9zdFNlY3VyZUNyeXB0b1Byb3RvY29s",
"hmacSha": 256,
"aesKeySize": 192,
"aesIv": "0x86ce20cec9f4dbd8f5a9df51dd63b5a0",
"aesMode": "cfb"
}


M2:

{
"protocol": "epes",
"protocolVersion": 2,
"protocolMessage": "ACK"
}


M3:

{
"timestamp": 1601877506,
"encryptedMessage": "0xb2b591ea94c704"
}


M4:

{
"timestamp": 1601877534,
"encryptedMessage": "0xb77c347a2619d3"
}


M5:

{
"timestamp": 1601877557,
"encryptedMessage": "0x6c69dfad4f3ff9"
}


M6:

{
"timestamp": 1601877599,
"encryptedMessage": "0x24ed9df539ab08"
}


M7:

{
"timestamp": 1601877681,
"encryptedMessage": "0x5450c732c60508"
}


M8:

{
"timestamp": 1601877704,
"encryptedMessage": "0xf00d34f319fa5d"
}


This reveals:
* AES-192-CFB is used. The IV is 0x86ce20cec9f4dbd8f5a9df51dd63b5a0.
* The scrypt salt is dGhlTW9zdFNlY3VyZUNyeXB0b1Byb3RvY29s. The other parameters of scrypt are mentioned in the description: N=16384, r=8, p=1, dkLen=64.
* For the OATH-TOTP HMAC, SHA-256 is used.

## Calculate the scrypt output
Using scrypt with the parameters (step 3; M1) and the shared key (step 2), we get 5c1472d3fc0b04afe8d24528c999ff219db16a6e7b15de0fc5f7cf3f6afbd953ce6cabe474d74278af87f7fcd95cfebf40065e7d4d47e258309a2c5182797ef7 as the shared secret.

## Recalculate OATH-TOTPs
For OATH-TOTP, we need the shared secret (step 4), the timestamp (see each message M, step 3), the HMAC hash function (step 3). The timestamp needs to be converted from epoch time to ISO time. This can be done for M3 to M8, resulting in the 8-digit encryption/decryption key for each message.

## Decrypt each message
To decrypt each message, the 8-digit key needs to be repeated three times (to get 192 bits, as described in the protocol). Using AES-192-CFB results in six parts of the flag.

Flag: syskronCTF{getting-the-flag-was-a-PITA}