# CYBERTALENTS MALWARE REVERSE ENGINEERING CATEGORY This is a writeup of the collection of challenges I have solved from [cybertalents](https://cybertalents.com/) ranging from easy to advanced. **NOTE : THIS WRITEUP CONTAIN SPOILERS** ## LEVEL : BASIC ### Pure Luck ##### Description ``` (1/24) * (1/60) * (1/60) , flag format:flag{xxxxxxxxxxxxxxxxxxxxxxxxx} ``` ##### Link [pure-luck.out](https://s3-eu-west-1.amazonaws.com/hubchallenges/Reverse/pure-luck.out) ##### Solution First to check the file type of this challenge: ![image](https://hackmd.io/_uploads/Bk30Dfhvp.png) Looking at the last strings of the file, I can see that it's packed with upx, so we unpack it to get the original binary which will make it easier to disassemble and decompile this binary: ![image](https://hackmd.io/_uploads/SJsW6X2wa.png) As seen below it's now unpacked: ![image](https://hackmd.io/_uploads/Hk0EaQ2wa.png) let's launch it up in "radare2" and read the disassembled output of the main function ```shell= user@localhost $> r2 -d pure-luck [0x08048736]> pdf @main ``` and the flag is each byte concatenated together: ![image](https://hackmd.io/_uploads/S1FdmfTKp.png) `FLAG : flag{UPX_is_so_eaaaasy}` ### Find the Pass ##### Description ![image](https://hackmd.io/_uploads/ryQAwQpFa.png) ##### Link [CyberTalentDemo0.exe](https://talentchallenges.s3-eu-west-1.amazonaws.com/Reverse/CybertalentDemo0.exe) ##### Solution First we need to understand what the challenge needs us to do, starting off we are provided with a question respectively as parts of the flag `Ans1`,`Ans2` and `Ans3`. **Qn1 - What is the address of the main function?** I open the executable in Binary Ninja, I am able to locate my main function in the symbols list,and the address is **0x401180** ![image](https://hackmd.io/_uploads/rJvR_mgq6.png) **Qn2 - What is the address of the function that validates the input?** I changed the decompiling level to "Pseudo C" which allowed me to get a nice read on the function, which allowed me to identify the `printf()`, `scanf()`, and the function which validates the input and parse itself in the if condition, where as if the input is not equal to 0 then it prints "Wrong Password": ![image](https://hackmd.io/_uploads/r1Sqi7x9T.png) and the address of that function is **0x401100** **Qn3 - What is the address of the hardcoded password?** Opening that function on the address that we previously just found, we shall see that it has the hardcoded password "elite" and the address is **0x4020f8** ![image](https://hackmd.io/_uploads/HkEL0Qeqp.png) `FLAG : flag{0x401180|0x401100|0x4020F8}` ### Find the Hash ##### Description ![image](https://hackmd.io/_uploads/H1xIJEg96.png) ##### Link [CyberTalentsDemo1.exe](https://talentchallenges.s3-eu-west-1.amazonaws.com/Reverse/CyberTalentDemo1.exe) Just as the previous challenge is, it needs us to get the three parts of the flag. **Q1 - What is the address of the main function?** Opening the executable in binary ninja or any decompiler and dissassembler of choice such as IDA, Ghidra, Cutter. We can see that the main function is at the address **0x401150** ![image](https://hackmd.io/_uploads/HyZavgWqp.png) **Q2 - What is the address of the function that Validate the input?** ![image](https://hackmd.io/_uploads/HySUOeb9a.png) Reading the output of the decompiled code, we can tell that the function `sub_401100` is responsible for validating the input, and it's address is **0x401100** **Q3 - What is the address of the hardcoded hash?** Analyzing the decompiled output, we can tell that there is a loop that takes the argument passed from the main function and then checks if it's equal to the output of `"1>&1"[var_ch]`: ![image](https://hackmd.io/_uploads/SJ_ZJWWcT.png) Thus we have our hardcoded hash at the address **0x403018**. `FLAG : flag{0x401150|0x401100|0x403018}` ### Salamander ##### Description ![image](https://hackmd.io/_uploads/SJh2xWW96.png) ##### Link [Salamander.exe](https://hubchallenges.s3-eu-west-1.amazonaws.com/Reverse/salamander.exe) ##### Solution Provided from the description we are told that the challenge will help us understand .Net reversing thus. The first thing I do after knowing its a .NET executable, I load it into DnSpy. And we opening the "Challenge" namespace we can see we have a form class and in the form class we have the flag listed for us where it's supposed to be retrieved after login with valid creds: ![image](https://hackmd.io/_uploads/rkykM-W56.png) `FLAG : FLAG{0_54l4m4nd3r_0}` ### Eazy ##### Description ![image](https://hackmd.io/_uploads/HkT5MMW5a.png) ##### Link [Eazy_Challenge.rar](https://hubchallenges.s3-eu-west-1.amazonaws.com/Reverse/Eazy_Challenge.rar) ##### Solution As the description says that it'll help us understand reverse engineering basics , so let's not overthink this. First I extract the file that is compresses in the RAR archived file provided: ![image](https://hackmd.io/_uploads/HJE7sMb5a.png) I then open the executable in binary ninja or any tool of your choice for decompiling and disassembling. While reviewing the `main` function, I saw that it copies 28 bytes from the hex encoded characters and then puts them to the destination of variable `var_3d`: ![image](https://hackmd.io/_uploads/HJinCfb56.png) Then we have a for loop which takes every iteration of the variable i+1 and adds it with `var_3d` then xors it with `0x41`, then writes the output to the file `Dont_Check_Me.txt`. Thus all we need to do is just run the executable and let it do the magic: ![image](https://hackmd.io/_uploads/BJmfgQW9T.png) `FLAG : FLAG{All_You_N33d_Is_Just_Execute_Me}` ### m0v ##### Description ![image](https://hackmd.io/_uploads/rkXe-X-5p.png) ##### Link [m0v.asm](https://hubchallenges.s3-eu-west-1.amazonaws.com/Reverse/m0v.asm) ##### Solution The question needs us to find the value of the ebx register after the last instruction. And the flag format provided is `flag{ebx}` Reading the assembly file provided: ![image](https://hackmd.io/_uploads/S16CGmZca.png) 1. sets `eax` register to 0 2. sets `ebx` register to 0 3. sets `edx` register to `deadbeefh` 4. sets the lower 16 bits of `eax` (`ax` register) to `3337h` 5. sets the `ebx` register to `31330000h` 6. sets the lower 16 bits of `edx`(`dx` register) to the value of `ax` 7. sets the lower 16 bits of `ebx`(`bx` register) to the value of `dx` Remember that dx register's value is `3337h` this makes bx also `3337h` and ax also `3337h`. Now since bx's value is 3337h and it's the lower 16 bits of ebx which is 31330000h, this means ebx will now change to have a value as `31333337` `FLAG : flag{31333337}` ### PE Master ##### Description ![image](https://hackmd.io/_uploads/ryTWnQZ96.png) ##### Solution I am using `pev` in kali linux, to extract PE infromation from the executable: ![image](https://hackmd.io/_uploads/SyqJW4Wqa.png) We now have the entry point and the image base address. What we are left with now is to get the virtual entrypoint address which we can actually easily get by adding the image base address and the entry point address together as seen below: ![image](https://hackmd.io/_uploads/Hkg5ZNZq6.png) And there we have our virtual entry point address. `FLAG : flag{0x14e0|0x133337|0x134817}` ### ELF Master ##### Description ![image](https://hackmd.io/_uploads/HyRzGVWcp.png) ##### Link [link to attached file](https://hubchallenges.s3-eu-west-1.amazonaws.com/Reverse/5735474573547.zip) ##### Solution I first open the file in binary ninja for analysis, and reading through the decompiled codes, I can understand that there is a weird series of characters, which are then passed into the for loop for XOR which in the end should be our flag: ![image](https://hackmd.io/_uploads/BkpTNVW96.png) I copy the hex encoded characters and head to cyberchef to perform the XOR using the key of `0x99` as seen on the above codes which gave me the flag in return :) ![image](https://hackmd.io/_uploads/H1h_HVWq6.png) `FLAG : flag{D0_1_L00k_L1k3_4n_3LF_M4st3r}` ## LEVEL : EASY ### Eye Of Sauron ##### Description ![image](https://hackmd.io/_uploads/S1gebQSqa.png) ##### Link [Inkie.zip](https://s3-eu-west-1.amazonaws.com/talentchallenges/Reverse/Inkie.zip) ##### Solution Provided the task that we are required to find the key to pass. I first extract the file from the archived file "Inkie.zip" and check the file type of the executable. ![image](https://hackmd.io/_uploads/rkfBWmSq6.png) Seeing that it's .Net compiled executable, I just launch it in **ILSpy**. This will help us get the decompiled code of the executable: ![image](https://hackmd.io/_uploads/rkGeQ7Bca.png) Reading through the codes we can see a really interesting function called "ShallHePass()" this actually takes "label2", "label3", "label4" and "label5" and concatenates them respectively then passes them through the **"reverse()"** function which takes every character and reverses it which gives out the output of the concatenated string in reversed order: ![image](https://hackmd.io/_uploads/BkwGEQSqT.png) Reading through **"InitializeComponent()"** to see what each variable initialized carries as a value, there we have the values of label2, label3, label4 and label5: ![image](https://hackmd.io/_uploads/S19h4XS5T.png) Taking the value of each required variable respectively we shall have ; `d0248b4e4788665583f05688c154b6ea`, but then label3 and label4 are redefined on **Form1_Load()** function and on the **btnCheck_Click()**, changing the values will result to having this as our value ; `d0248b4e4799665583f05689c154b6ea` now reversing this string should provide us without final answer which is the flag: ![image](https://hackmd.io/_uploads/H1hFdQHca.png) `FLAG : ae6b451c98650f3855669974e4b8420d` ### Getting Started ##### Description ![image](https://hackmd.io/_uploads/S1H0d7rq6.png) ##### Link [getting-started](https://s3-eu-west-1.amazonaws.com/talentchallenges/Reverse/getting-started) ##### Solution Checking to know the file type and the strings that are readable from the first 10 lines: ![image](https://hackmd.io/_uploads/rkYm9mSca.png) Opening the binary in binary ninja, I was able to get the flag straight up from the main function. Seems easier than I thought! ![image](https://hackmd.io/_uploads/S1z9nmrcp.png) `FLAG : flag{welcome_to_level_1}` ### Get Rid of Them All ##### Description ![image](https://hackmd.io/_uploads/BJZMTXScT.png) ##### Link [get-rid-of-them.jar](https://s3-eu-west-1.amazonaws.com/hubchallenges/Reverse/get-rid-of-them.jar) ##### Solution This is the first Java Reverse Engineering challenge in this platform. And provided with a **.JAR** file we are supposed to reverse engineering this file to obtain the flag as the description says. I will be using JADX-GUI to decompile this JAR file for reviewing the source codes: ![image](https://hackmd.io/_uploads/r1k7lVH9p.png) We can see the flag is sort of encrypted, and it's passed to the main function where a new class is being called if the argument length is greater than 10, the new class is named **ooo** let's try and analyze it as well: ![image](https://hackmd.io/_uploads/HkrnNES5T.png) This is the interesting part, the function **_1()** takes the string a which is most likely to be the flag, and then it decodes it from base64 and prints it out. ```java static String flag = "&^&@|* Zm}&,);\\('))[\\[$`|_^#(x*]>&hZ)'$ $#(: [$3;&$t \\_']?&>,&i)!QG{`- ,% ~<`._@'::_\\_{}-|_[&{<`~$) ?'?(!$,.{>? @!^:#|R,?')`[,`;?!f_:$$<)Y}$:[|^?2)_h&><.:.-{&[|&A\\*;*)-($.>>(<^';#Q@?,,H\\`|)$ <):@(;}?-[~(&)>>*)(~)`$:[;>!.&%<!.>~ %J}*zX:(&:~:<0)*>(B(!?.#@A*<*{-,[Q@{%!~)~-~:@:#|![>)]?];H;$-<}>!@~)<<) \\_!|]#,&!,@>\\[]|J ]\\^[?>$|$?'|,#.)$l[^@X.~! \\;0-&,;,!['@[J*~#`AQ[*&%<,~]?~_^~(;}\\$>)[&@) (]}];;*^<)''@\\E[.@! B*.<-A-,:-#`-.}<-|)^Z@](?;H >-}.%.?}@<!())0] <&=@(<*$\\(("; ``` From the looks of this line above, it seems like the base64 encoded string is available and it's mixed up with unwanted characters, now we get rid of the unwanted characters by writing a script to identify characters that are in base64 encoded strings: ![image](https://hackmd.io/_uploads/By6mjNS5T.png) We run the script and decode the output we then have our flag: ![image](https://hackmd.io/_uploads/BJRWj4r5a.png) `FLAG : flag{b@d_ch@@rs_@@@re_B@@@@d}` ### Bruteforce Me ##### Description ![image](https://hackmd.io/_uploads/r1d-hVB9a.png) ##### Link [bruteforceme.py](https://s3-eu-west-1.amazonaws.com/hubchallenges/Reverse/bruteforceme.py) ##### Solution ```python= ll =[51, 54, 48, 51, 61, 57, 50, 54, 48, 52, 55, 50, 50, 57, 47, 52, 57, 47, 54, 24, 57, 58, 62] i = raw_input() ss= 0 try: for ii in range(0,46 , 2): temp = i[ii:ii+2] temp = int(temp,0x10) ss+=temp temp >>=1 if temp != ll[ii/2]: print "Something is wrong" if ss !=2406: print ss/0 print "This flag may or may not work, can you find more ?" except: print "NO" ``` Provided the above code we are supposed to get the flag. Breaking down the codes, first we have a list declared "ll" then it takes an input "i" and it starts a loop in a range of 0 to 46 with a step of 2, at every iteration the variable "temp" equals a chunk of two chars from the input, and it will be decoded as hex to int, it will be added to variable "ss" after that the variable "temp" right shifts by 1 bit then in a condition it checks if temp is equal to the index output of "ii" divided by 2. And lastly after the loop ends it runs a condition to check if "ss" is equal to "2406" which then prints "This flag may or may not work, can you find more?" With all this, to simplify the script it's shifting to the right 1 bit for each character of the input provided by the user which should actually be 46 characters and should be hexadecimal with the characters having either "a-z" or "0-9". Writing a script to solve this will be fairly straightfoward, but there are some few fixes and tests, I initially wrote this script: ```python= ll = [51, 54, 48, 51, 61, 57, 50, 54, 48, 52, 55, 50, 50, 57, 47, 52, 57, 47, 54, 24, 57, 58, 62] aa = [95, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 125] flag = '' for x in ll: for y in aa: if (y >> 1) == x: flag += chr(y) print(flag) ``` let's break down the code, first we set the list of the initially declared variable from the first script provided, after that we set a list of characters "a-z", "0-9" and "_" in decimal, and we create an empty variable "flag" after that we start out loop where `x in ll` and another loop for `y in aa` then adding a condition to check each byte of y from aa in the loop if right shifted to 1 bit is equal x in the list of ll, and if it's True then the decimal is converted to a character and it's added to the variable "flag" and lastly it prints it: ![image](https://hackmd.io/_uploads/HJnWyL896.png) reading the output we can at least make some sense of the flag for example `fglmafgz{` removing each character after one step we have the word `flag`, so I write a script to automate this: ```python= ll = [51, 54, 48, 51, 61, 57, 50, 54, 48, 52, 55, 50, 50, 57, 47, 52, 57, 47, 54, 24, 57, 58, 62] aa = [95, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 125] flag = '' for x in ll: for y in aa: if (y >> 1) == x: flag += chr(y) output = '' for index, char in enumerate(flag): if index % 2 == 0: output += char print(output) ``` Running this I get this output: ![image](https://hackmd.io/_uploads/BJoygIL96.png) Reviewing the first output after running the script earlier we can see that after the bracket we have the words `rsdelmahinodeders` and removing the characters after one step still doesn't make sense , but removing the characters after 2 steps then 1 step we get the string`remainder`. Looks like we are heading somewhere πŸ’€, I remove the characters and ended up having the flag as : ![image](https://hackmd.io/_uploads/Hk-u48L5T.png) `FLAG : flag{remainder_is_l0st}` ### GUI I ##### Description ![image](https://hackmd.io/_uploads/BkElr8Ica.png) ##### Link [GUI.exe](https://s3-eu-west-1.amazonaws.com/hubchallenges/Reverse/GUI.exe) ##### Solution First I try to get some basic file type information: Seeing that it's .NET based executable, I launch it in **iLSpy** and I am able to retrieve the decompiled codes and in the **Form1** class, we are able to see some variables declared in the **InitializeComponents()** function: ![image](https://hackmd.io/_uploads/S150UIU56.png) The decimals in `label3.Text` are probably ASCII characters now let's try decoding them: ![image](https://hackmd.io/_uploads/BykUwUU96.png) Now back to analyzing the source codes, we can see we have another function **button1_Click()**: ![image](https://hackmd.io/_uploads/SkpgdIU96.png) Basically this is a simple logic to break down, it checks array index of each checkbox to the power of 2. Also we have another conditional logic which parses the string from label3 into integer and adds 10 then checks if it's equivallent to the value of num which is the value of output from the array exponentials. Our focus now is to get the flag right away looking at how it adds + 10 then adds the character of num in an incrementional behavior makes this look so obvious that it's sort of cipher. So I write a simple python script to solve this: ```python= flag = "92 98 87 93 113 95 105 85 106 94 95 105 85 89 87 91 105 87 104 85 89 95 102 94 91 104 53 115" result = ''.join(chr(int(a) + 10) for a in flag.split()) print(result) ``` ![image](https://hackmd.io/_uploads/HyrWiLL56.png) `FLAG : flag{is_this_caesar_cipher?}` ### Developer Locks ##### Description ![image](https://hackmd.io/_uploads/HkXuXD8qT.png) ##### Link [Developer-locks.exe](https://s3-eu-west-1.amazonaws.com/hubchallenges/Reverse/Developer-locks.exe) ##### Solution Checking the file type, we can see that it's .NET: ![image](https://hackmd.io/_uploads/rJyaQD8cT.png) We opening it up in **iLSpy** for analysis of the decompiled source code: ![image](https://hackmd.io/_uploads/BJjdLv8cp.png) In the **Program** class, we can get a nice review of how the code works, So first it takes an input which should not have the length greater than 11, then it creates an MD5 value from the username running the executable + the input text and checks if the hash is the same as **C246B75690B6F0746AA67ECC9B400ECF**, in our case this hash is our flag! Decrypting the hash will provide us with the flag: ![image](https://hackmd.io/_uploads/BJu9Rv8qa.png) `FLAG : Pic@tchuz00` ### Jumping Pixels ##### Description ![image](https://hackmd.io/_uploads/B1wMk_I9p.png) ##### Link [PixelSecrets.exe](https://s3-eu-west-1.amazonaws.com/hubchallenges/Reverse/PixelSecrets.exe) ##### Solutions Looking at the file type, we can see that it's .NET executable: ![image](https://hackmd.io/_uploads/HJFjydLcp.png) I open it up in **ilSpy**: ![image](https://hackmd.io/_uploads/B1AilOI5p.png) The description says that we are required to get the key and in order for that we need to jump the right sequence. Now reading the code we can see that we have a class known as **Mixer** and it has an encrypt function, let's take a look at it: ![image](https://hackmd.io/_uploads/Bk3tCuDcT.png) it gets even more fascinating seeing that there two function one known as **EncryptStringToBytes()** and the other known as **Encrypt()**, we can see that they all have different arguments that they take to run, In the second function we can see that the **Key** and **IV** are already set, and it takes an input although the input isn't used at all anywhere in the function since it has a predefined variable `plainText` which is the one that is encrypted: ```csharp= public string Encrypt(string input) { try { string plainText = "Here is some data to encrypt!"; using RijndaelManaged rijndaelManaged = new RijndaelManaged(); rijndaelManaged.Key = Convert.FromBase64String("2SPmCULv7pF5eq4ZEXAMmOj/AoSfNB9FlY5gjNIa3Nw="); rijndaelManaged.IV = Convert.FromBase64String("Qs+tOYyZH3K3W7lGlCquPg=="); return Convert.ToBase64String(EncryptStringToBytes(plainText, rijndaelManaged.Key, rijndaelManaged.IV)); } catch (Exception ex) { Console.WriteLine("Error: {0}", ex.Message); return ""; } } ``` And from our main class we can see that there is a condition which checks if the value of the variable `Text` is equal to "Hack" then it will run the encrypt function. So let's jump this step and run the encrypt function as it is. All I did was copy the function's codes as they are and created then in a class of a test project that I created in visual studio. then I just call the function in the main class with passing an empty string: ```csharp= using System.Security.Cryptography; namespace ProgramApp { public class Program { public static void Main(string[] args) { Mixer mixer = new Mixer(); System.Console.WriteLine(mixer.Encrypt("")); } } public class Mixer { private static byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV) { if (plainText == null || plainText.Length <= 0) { throw new ArgumentNullException("plainText"); } if (Key == null || Key.Length == 0) { throw new ArgumentNullException("Key"); } if (IV == null || IV.Length == 0) { throw new ArgumentNullException("IV"); } using RijndaelManaged rijndaelManaged = new RijndaelManaged(); rijndaelManaged.Key = Key; rijndaelManaged.IV = IV; ICryptoTransform transform = rijndaelManaged.CreateEncryptor(rijndaelManaged.Key, rijndaelManaged.IV); using MemoryStream memoryStream = new MemoryStream(); using CryptoStream stream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write); using (StreamWriter streamWriter = new StreamWriter(stream)) { streamWriter.Write(plainText); } return memoryStream.ToArray(); } public string Encrypt(string input) { try { string plainText = "Here is some data to encrypt!"; using RijndaelManaged rijndaelManaged = new RijndaelManaged(); rijndaelManaged.Key = Convert.FromBase64String("2SPmCULv7pF5eq4ZEXAMmOj/AoSfNB9FlY5gjNIa3Nw="); rijndaelManaged.IV = Convert.FromBase64String("Qs+tOYyZH3K3W7lGlCquPg=="); return Convert.ToBase64String(EncryptStringToBytes(plainText, rijndaelManaged.Key, rijndaelManaged.IV)); } catch (Exception ex) { Console.WriteLine("Error: {0}", ex.Message); return ""; } } } } ``` Running this I was able to get the flag which is the encrypted output: ![image](https://hackmd.io/_uploads/r1tfWtP56.png) `FLAG : rYzebWmuijINJimYBQZwomVlt988sEPM10XUZt8+Zfg=` ### Encipher ##### Description ![image](https://hackmd.io/_uploads/BkWdZtD5T.png) ##### Link [Encipher.exe](https://s3-eu-west-1.amazonaws.com/hubchallenges/Reverse/Encipher.exe) ##### Solution First thing first, I open it up in binary ninja, and I am able to get some useful decompiled output: ![image](https://hackmd.io/_uploads/rJuX4Fv9T.png) Now let's break down to understand what this does; first it reads a stdin of 22 characters MAX, and stores it's address to `data_406034`, then it loops through the input characters each byte and in every iteration it shall check if the next character has the ASCII code of 10 "\n" and if it's true then it XOR the character with 0x80 and breaks the loop. Otherwise XOR the current character with the next character and print out the output in hex. Now since we understand the logic behind it on how the encrypted string **0a0c073c5a55072c117e442b0c60501627614efd** was created, in this case it'll be easy for us to reverse the logic and crack the encrypted string. To achieve this, first we know that it takes the current character and xors it with the next one then the last one will be xor with 0x80 then it prints the output, this gives us a logic to xor from the last character to the beginning of the character "Inverse" : ```python= enc = bytearray.fromhex('0a0c073c5a55072c117e442b0c60501627614efd') flag = bytearray() cc = 0 for byte in reversed(enc): if not flag: cc = byte ^ 0x80 else: cc = byte ^ cc flag.insert(0, cc) print(flag.decode('utf-8')) ``` ![image](https://hackmd.io/_uploads/HkXzptPqa.png) `FLAG : FL@G{!ts_N0t_S3cuR3}` ### Pardon ##### Description ![image](https://hackmd.io/_uploads/SkivTKwc6.png) ##### Link [pardon.exe](https://hubchallenges.s3-eu-west-1.amazonaws.com/Reverse/pardon.exe) ##### Solution Opening the executable in ILSpy, we can see that most of the classes and the codes are sort of obfuscated all though the codes are well written: ![image](https://hackmd.io/_uploads/ryRDW5Dq6.png) will continue writing everytime I get some spare time 😎