Tags: reverse 

Rating: 4.3

![image](https://user-images.githubusercontent.com/68913871/134920839-ce673ebb-d011-43c7-8d97-806fd1e9a55c.png)
[obscure.zip](https://github.com/Rookie441/CTF/files/7236690/obscure.zip)

> The file is a python byte-compiled file.

![image](https://user-images.githubusercontent.com/68913871/134920971-3626bf13-7371-4dbe-ab73-9937c7783b64.png)

> To decompile, rename as `.pyc` and run [uncompyle6](https://pypi.org/project/uncompyle6/) and we get the following:

```python
# 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 to `print(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 of `real_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 us `30` which corresponds to the first 2 digits of the flagdata of `real_flag`. Since we know the flag format is `TamilCTF{}`, we can proceed to encrypt the next letter `a`, and we should expect `0e`, which is the next 2 digits of flagdata. However, we are given `05` 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 is `0e` 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 with `real_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 with `TamilCTF{`. This is the final code:

```python
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}`

Original writeup (https://github.com/Rookie441/CTF/blob/main/Storage/Writeups/TamilCTF2021_Writeup.md#obscure).