Tags: reverse
Rating: 4.3
The file is a python byte-compiled file.
To decompile, rename as
.pyc
and run uncompyle6 and we get the following:
# uncompyle6 version 3.7.4
# Python bytecode 2.7 (62211)
# Decompiled from: Python 3.8.5 (tags/v3.8.5:580fbb0, Jul 20 2020, 15:43:08) [MSC v.1926 32 bit (Intel)]
# Embedded file name: reverseme.py
# Compiled at: 2021-09-04 17:21:21
import numpy as np
flag = 'TamilCTF{this_one_is_a_liability_dont_fall_for_it}'
np.random.seed(369)
data = np.array([ ord(c) for c in flag ])
extra = np.random.randint(1, 5, len(flag))
product = np.multiply(data, extra)
temp1 = [ x for x in data ]
temp2 = [ ord(x) for x in 'dondaVSclb' * 5 ]
c = [ temp1[i] ^ temp2[i] for i in range(len(temp1)) ]
flagdata = ('').join(hex(x)[2:].zfill(2) for x in c)
real_flag = '300e030d0d1507251700361a3a0127662120093d551c311029330c53022e1d3028541315363c5e3d063d0b250a090c52021f'
# okay decompiling reverseme.pyc
In the above code, we can see an encryption algorithm running on a sample flag
TamilCTF{this_one_is_a_liability_dont_fall_for_it}
. If we were toprint(flagdata)
, we get:
300e030d0d15072517160c061d3b0e38363c05113b0e31080837310a000b101631000e38273c0a03080331020e240c0a181f
This format is the same as that of
real_flag
, but the values differ. We need to reverse the encryption algorithm and pass in the flagdata ofreal_flag
to get the actual flag.
We can adopt a bruteforce approach whereby we pass every printable ascii character through the algorithm and get the output, then compare it with the ciphertext to map out the ascii flag.
But first, we should explore the encryption algorithm. In the example below, encrypting the letter
T
gives us30
which corresponds to the first 2 digits of the flagdata ofreal_flag
. Since we know the flag format isTamilCTF{}
, we can proceed to encrypt the next lettera
, and we should expect0e
, which is the next 2 digits of flagdata. However, we are given05
instead. Strange.
real_flag = '300e030d0d1507251700361a3a0127662120093d551c311029330c53022e1d3028541315363c5e3d063d0b250a090c52021f'
"T" : 30
"a" : 05
Upon further exploration, I realised that the characters has to be in the correct index before encryption will tally. Here, the letter
a
is at the 2nd position and the result is0e
as expected.
"Ta" : 300e
"TamilCTF{" : 300e030d0d15072517
Thus, we create a string called
flag_decrypted
. We append a printable ascii character and compare it with the algorithm. If output matches withreal_flag
(truncated), continue with the next position, else, revert back to the original string and try a different ascii character. Since we know the flag format, we can start off withTamilCTF{
. This is the final code:
import numpy as np
def algo(flag):
np.random.seed(369)
data = np.array([ ord(c) for c in flag ])
extra = np.random.randint(1, 5, len(flag))
product = np.multiply(data, extra)
temp1 = [ x for x in data ]
temp2 = [ ord(x) for x in 'dondaVSclb' * 5 ]
c = [ temp1[i] ^ temp2[i] for i in range(len(temp1)) ]
flagdata = ('').join(hex(x)[2:].zfill(2) for x in c)
return flagdata
flag = 'TamilCTF{this_one_is_a_liability_dont_fall_for_it}'
flag_length = len(flag)
real_flag = '300e030d0d1507251700361a3a0127662120093d551c311029330c53022e1d3028541315363c5e3d063d0b250a090c52021f'
import string
ascii_list = string.printable
flag_decrypted = "TamilCTF{"
for y in range(len(flag_decrypted),flag_length):
temp_flag = flag_decrypted
for sym in ascii_list:
temp_flag+=sym #try ascii char
if algo(temp_flag) == real_flag[:2*y]: #check against truncated real_flag
flag_decrypted = temp_flag #append correct char
else:
temp_flag = flag_decrypted #go back to original
continue
print(flag_decrypted)
flag_decrypted+="}"
print(flag_decrypted)
We get the following output:
TamilCTF{
TamilCTF{b
TamilCTF{bR
TamilCTF{bRu
TamilCTF{bRuT
TamilCTF{bRuTe
TamilCTF{bRuTeF
TamilCTF{bRuTeF0
TamilCTF{bRuTeF0r
TamilCTF{bRuTeF0rC
TamilCTF{bRuTeF0rCe
TamilCTF{bRuTeF0rCe_
TamilCTF{bRuTeF0rCe_1
TamilCTF{bRuTeF0rCe_1s
TamilCTF{bRuTeF0rCe_1s_
TamilCTF{bRuTeF0rCe_1s_t
TamilCTF{bRuTeF0rCe_1s_tH
TamilCTF{bRuTeF0rCe_1s_tHe
TamilCTF{bRuTeF0rCe_1s_tHe_
TamilCTF{bRuTeF0rCe_1s_tHe_0
TamilCTF{bRuTeF0rCe_1s_tHe_0n
TamilCTF{bRuTeF0rCe_1s_tHe_0nL
TamilCTF{bRuTeF0rCe_1s_tHe_0nLy
TamilCTF{bRuTeF0rCe_1s_tHe_0nLy_
TamilCTF{bRuTeF0rCe_1s_tHe_0nLy_F
TamilCTF{bRuTeF0rCe_1s_tHe_0nLy_F0
TamilCTF{bRuTeF0rCe_1s_tHe_0nLy_F0r
TamilCTF{bRuTeF0rCe_1s_tHe_0nLy_F0rC
TamilCTF{bRuTeF0rCe_1s_tHe_0nLy_F0rCe
TamilCTF{bRuTeF0rCe_1s_tHe_0nLy_F0rCe_
TamilCTF{bRuTeF0rCe_1s_tHe_0nLy_F0rCe_2
TamilCTF{bRuTeF0rCe_1s_tHe_0nLy_F0rCe_2_
TamilCTF{bRuTeF0rCe_1s_tHe_0nLy_F0rCe_2_b
TamilCTF{bRuTeF0rCe_1s_tHe_0nLy_F0rCe_2_bR
TamilCTF{bRuTeF0rCe_1s_tHe_0nLy_F0rCe_2_bRe
TamilCTF{bRuTeF0rCe_1s_tHe_0nLy_F0rCe_2_bReA
TamilCTF{bRuTeF0rCe_1s_tHe_0nLy_F0rCe_2_bReAk
TamilCTF{bRuTeF0rCe_1s_tHe_0nLy_F0rCe_2_bReAk_
TamilCTF{bRuTeF0rCe_1s_tHe_0nLy_F0rCe_2_bReAk__
TamilCTF{bRuTeF0rCe_1s_tHe_0nLy_F0rCe_2_bReAk__1
TamilCTF{bRuTeF0rCe_1s_tHe_0nLy_F0rCe_2_bReAk__1n
TamilCTF{bRuTeF0rCe_1s_tHe_0nLy_F0rCe_2_bReAk__1n}
TamilCTF{bRuTeF0rCe_1s_tHe_0nLy_F0rCe_2_bReAk__1n}