Hacklu2019-COBOL OTP(CallMeCro)¶
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?
Examination Site¶
- COBOL
- Stream Cipher
Analysis¶
Convert COBOL to python. Probably meaning as follows
with open('key.txt','r') as key_file: ws_key = key_file.read() # len(ws_key) = 50 ws_flag = '' ws_input = str(raw_input("Enter your message to encrypt:"))[:50] for i in range(50): ws_parse = ord(ws_input[i]) ws_flag += chr(ord(ws_key[i])^ord(ws_input[i])) print ws_flag
By observing,we will find a rule:the position of the character whose ascii value is greater than 127 is 0 1 3 10 11 13 20 21 23 30 31 33 40 41 43 => index % 10 == 0 | 1 | 3. This rule shows that the key may only have 10 digits.
In addition,we found that there is a rule in ciphertext:
- No.12 byte == No.22 byte
- No.24 byte == No.34 byte
- No.26 byte == No.36 byte
- No.8 byte == No.18 byte == No.28 byte
Therefore,we will guess that the msg is the flag whose beginning may be "flag{". According to this guess, we can get the first 5 digits of the key, as well as some of the plaintext.
flag{?????c4n_?????O2_c3?????_s4v?????fUtUr?????
Exploit¶
#encoding:utf-8 from string import printable characters = '' for i in range(33,126): characters += chr(i) def filter(source_str, index): length = len(source_str) / 10 + 1 for i in range(length): if (source_str[index + 10]) not in characters: return False return True def pwn(): with open("out","rb") as ws_enc: ws_enc.readline() enc = ws_enc.readline() #################### No.6 Byte #################### key = '' guess = 'flag{' for i in range(len(guess)): key += chr(ord(guess[i])^ord(enc[i])) for i in range(255): ws_key = key + chr(i) + "????" result = '' for j in range(len(enc)): result += chr(ord(ws_key[j%10])^ord(enc[j])) if filter(result,5): print result #flag{N/[WJ_c4n_bjUW|O2_c3rk_W_s4v3_kD;`fUtUrE.\nu5 #################### No.6 Byte #################### #################### No.7 Byte #################### key = '' guess = 'flag{N' for i in range(len(guess)): key += chr(ord(guess[i])^ord(enc[i])) for i in range(255): ws_key = key + chr(i) + "???" result = '' for j in range(len(enc)): result += chr(ord(ws_key[j%10])^ord(enc[j])) if filter(result,6): print result #flag{N0[WJ_c4n_buUW|O2_c3rt_W_s4v3_tD;`fUtUrE1\nu5 #################### No.7 Byte #################### #################### No.8 Byte #################### key = '' guess = 'flag{N0' for i in range(len(guess)): key += chr(ord(guess[i])^ord(enc[i])) for i in range(255): ws_key = key + chr(i) + "??" result = '' for j in range(len(enc)): result += chr(ord(ws_key[j%10])^ord(enc[j])) if filter(result,7): print result #flag{N0wWJ_c4n_buyW|O2_c3rtsW_s4v3_th;`fUtUrE1!u5 #################### No.8 Byte #################### #################### No.9 Byte #################### key = '' guess = 'flag{N0w' for i in range(len(guess)): key += chr(ord(guess[i])^ord(enc[i])) for i in range(255): ws_key = key + chr(i) + "?" result = '' for j in range(len(enc)): result += chr(ord(ws_key[j%10])^ord(enc[j])) if filter(result,8): print result #flag{N0w_J_c4n_buy_|O2_c3rts__s4v3_th3`fUtUrE1!}5 #################### No.9 Byte #################### #################### No.10 Byte #################### key = '' guess = 'flag{Now_' for i in range(len(guess)): key += chr(ord(guess[i])^ord(enc[i])) for i in range(255): ws_key = key + chr(i) result = '' for j in range(len(enc)): result += chr(ord(ws_key[j%10])^ord(enc[j])) if filter(result,9): print result #flag{Now_u_c4n_b*y_CO2_c3r+s_&_s4v3_+h3_fUtUrEn!} #################### No.10 Byte #################### if __name__ == '__main__': pwn()