Cobol OTP - Hack.Lu CTF 2019
Cobol OTP
Category: Crypto Author: midao Level: easy Solves: 104
Thanks to R. who actually flagged it :)
Description
To save the future you have to look at the past. Someone from the inside sent you an access code to a bank account with a lot of money. Can you handle the past and decrypt the code to save the future?
Attached file
A zip is provided with:
- otp.cob: a program in Cobol
- out
|
|
Understanding the Cobol program
We understand the Cobol program is performing XOR encryption using a key provided in a keyfille.
|
|
We don’t have the key file of course, but we know that flags begin with flag{...}
.
This means that the data in the key data will be at most 50 characters.
|
|
This allocates two variables: ws-flag which contains 1 characters and ws-key with at most 50. Then we have ws-xor-len composed of at most 1 digit (so 0 to 9), and ws-ctr, a counter, one digit as well.
|
|
In Cobol, the program instructions begin at procedure division
.
We read the key file.
|
|
Then, we ask for the message to encrypt, and initialize the counter to 1.
|
|
Then, we loop 50 times (because the message has 50 characters) to encrypt each character. By the way, we check that indeed our encrypted message has 50 characters (actually 49 + \n).
For each character, we read one character of the message to encrypt and put it in ws-parse. We also copy it on ws-flag which is the variable which will hold the encrypted character. Then, we call XOR on ws-flag using the i-th character of the key (using the counter ws-ctr). Finally we increment the counter.
|
|
Compililng Cobol
If you want to try the program, on Linux you can compile it using open-cobol
package:
|
|
Solution
We know that the first few characters of the encrypted message must correspond to plaintext flag{
. As the encryption algorithm is XOR, we can recover the first few bytes of the key:
|
|
So, the first bytes of the key are 0xc0, 0xbe, 0x72, 0xf1, 0x02.
We set this as a key, and decrypt the entire message in a Python interpreter:
|
|
It doesn’t work yet, because we miss characters for the key. We have only set 5 bytes but obviously it is not enough.
We notice in the middle that we have something that prints out correctly: fUtUr
, so this means that at some point we were correctly aligned with the key once again. As the message is 50 characters long, the key is likely to be a divider of 50. If 5 is not enough, then 10 probably.
Slightly before fUtUr
, we also see s4v3
. We guess that in between we should have _th3_
for s4v3_th3_fUtUr
.
With that, we recover the rest of the key:
|
|
And then, we can decrypt the message with the correct 10 character long key and get the flag: flag{N0w_u_c4n_buy_CO2_c3rts_&_s4v3_th3_fUtUrE1!}
Here is the Python program that solves the challenge
|
|