# How to defeat the Russian Dukes: A step-by-step analysis of MiniDuke used by APT29/Cozy Bear **[cybergeeks.tech/how-to-defeat-the-russian-dukes-a-step-by-step-analysis-of-miniduke-used-by-apt29-cozy-bear/](https://cybergeeks.tech/how-to-defeat-the-russian-dukes-a-step-by-step-analysis-of-miniduke-used-by-apt29-cozy-bear/)** Summary APT29/Cozy Bear is a Russian actor that has been associated with Russia’s Foreign Intelligence Service (SVR). The US government has blamed this actor for the SolarWinds supply chain compromise operation, as described at https://media.defense.gov/2021/Apr/15/2002621240/-1/-1/0/CSA_SVR_TARGETS_US_ALLI ES_UOO13234021.PDF/CSA_SVR_TARGETS_US_ALLIES_UOO13234021.PDF. MiniDuke is a backdoor written in pure assembly that was previously documented by ESET at https://www.welivesecurity.com/wpcontent/uploads/2019/10/ESET_Operation_Ghost_Dukes.pdf and Kaspersky at [https://securelist.com/miniduke-is-back-nemesis-gemina-and-the-botgen-studio/64107/,](https://securelist.com/miniduke-is-back-nemesis-gemina-and-the-botgen-studio/64107/) however, this sample is the most recent one (June 2019) that we’re aware of and hasn’t been documented before. This malware is pretty obfuscated (control-flow flattening) and implements multiple methods of data exfiltration, such as using POST and PUT HTTP methods in the case of sending data to the C2 server or using a named pipe in the case of no Internet connectivity. The backdoor implements 37 different functions that can be visualized below (some of these are similar/identical and were skipped): ----- **Analyst:** [@GeeksCyber](https://twitter.com/GeeksCyber) Technical analysis SHA256: 6057b19975818ff4487ee62d5341834c53ab80a507949a52422ab37c7c46b7a1 The malware uses the SetUnhandledExceptionFilter function in order to set the exception filter function to a particular function: ----- Figure 1 The process retrieves the content of the STARTUPINFO structure by calling the GetStartupInfoA routine, as shown below: Figure 2 A new thread is created by the malicious file using the CreateThread API: Figure 3 **Thread activity – sub_4036D0** As mentioned by ESET at https://www.welivesecurity.com/wpcontent/uploads/2019/10/ESET_Operation_Ghost_Dukes.pdf, the backdoor has added a lot of obfuscation that consists of control-flow flattening (every function is split in a switch/case, and a lot of computation that is useless for the main execution flow is added): Figure 4 Figure 5 presents an example of an instruction that jumps to a place where a lot of useless computation occurs. We’ve added NOP operations in place of the jump and patched the binary: Figure 5 ----- The binary forces the system not to display the Windows Error Reporting dialog (0x2 = **SEM_NOGPFAULTERRORBOX):** Figure 6 The kernel32.dll, advapi32.dll and winninet.dll DLLs are loaded into the address space using the LoadLibraryA routine: Figure 7 The functions that will be used during the execution are located using a hashing mechanism. Basically, for each function name from a DLL, the malware computes a 4-byte value that is compared with a hard-coded one: Figure 8 The following APIs belong to the targeted list: GetProcAddress, GetLongPathNameA, GetLastError, CreateProcessWithLogonW, CryptAcquireContextW, CryptGenRandom, InternetOpenA, InternetConnectA, InternetSetOptionA, HttpOpenRequestA, HttpSendRequestA, HttpQueryInfoA, InternetReadFile, InternetCloseHandle, HttpAddRequestHeadersA. The hashing function is displayed below: Figure 9 ----- The CryptAcquireContextW API is utilized to get a handle to a key container within a CSP (cryptographic service provider). The function call is presented in figure 10 (0x1 = **PROV_RSA_FULL, 0xF0000040 = CRYPT_VERIFYCONTEXT | CRYPT_SILENT):** Figure 10 AllocateAndInitializeSid is used to allocate and initialize a SID with one subauthority: Figure 11 The file creates a new ACL using the SetEntriesInAclA routine (0x2 = SET_ACCESS): Figure 12 A new security descriptor is initialized by the malicious process (0x1 = **SECURITY_DESCRIPTOR_REVISION):** Figure 13 The malware sets information in a DACL (discretionary access control list) using the SetSecurityDescriptorDacl API: ----- Figure 14 The following relevant strings are written into memory and will be used later on: Figure 15 CryptGenRandom is utilized to generate 16 random bytes. The first 15 bytes are encoded using the Base64 algorithm: Figure 16 The binary writes the file signature of JPEG in the JFIF format into the memory. These bytes will be used in data exfiltration, as we’ll describe in the following paragraphs: Figure 17 The process creates the “Software\Microsoft\ApplicationManager” registry key using the RegCreateKeyA API (0x80000001 = HKEY_CURRENT_USER): Figure 18 A new value called “AppID” is created under the above registry key. This value is computed using the output of a GetTickCount function call: Figure 19 ----- There are 2 more calls to the GetTickCount routine (it retrieves the number of milliseconds that elapsed since the system was started): Figure 20 One of the outputs from above is transformed and written into a buffer, along with the “AppID” value. This buffer will be encrypted using a custom algorithm that also includes the XOR operator: Figure 21 The encryption algorithm and the result of the above operation are highlighted in figure 22: ----- Figure 22 The backdoor initializes the use of the WinINet functions using the InternetOpenA API with a particular user agent: Figure 23 The proxy is set to 10.1.1.1:8080 using the InternetSetOptionA function (0x26 = **INTERNET_OPTION_PROXY):** Figure 24 The connect time-out value for connection requests is set to 11 seconds (0x2 = **INTERNET_OPTION_CONNECT_TIMEOUT):** ----- Figure 25 The receive time-out value for connection requests is set to 11 seconds (0x6 = **INTERNET_OPTION_RECEIVE_TIMEOUT):** Figure 26 The send time-out value for connection requests is set to 11 seconds (0x5 = **INTERNET_OPTION_SEND_TIMEOUT):** Figure 27 InternetConnnectA is utilized to open an HTTP session with the C2 server salesappliances[.]com (0x3 = INTERNET_SERVICE_HTTP): Figure 28 The malware implements 3 different cases for exfiltrating the buffer that was encrypted earlier (or outputs from backdoor functions), depending on the availability of Internet connectivity. **Case 1** **(no Internet availability)** WaitNamedPipeA is used to wait until 11 seconds have elapsed or an instance of the “\\pipe\DefPipe” pipe is available for connection (this pipe is supposed to be utilized between this machine and another machine that has an Internet connection): ----- Figure 29 The process opens the specified pipe using the CreateFileA routine (0xC0000000 = **GENERIC_READ | GENERIC_WRITE, 0x3 = OPEN_EXISTING):** Figure 30 SetNamedPipeHandleState is utilized to set the read mode and the blocking mode of the pipe mentioned above (0x2 = PIPE_READMODE_MESSAGE, 0x0 = PIPE_WAIT): Figure 31 The binary writes the encrypted buffer to the specified pipe using the TransactNamedPipe API: Figure 32 **Case 2 (Data exfiltration using PUT method)** A new HTTP request handle is created by the file (0x80400100 = **INTERNET_FLAG_RELOAD | INTERNET_FLAG_KEEP_CONNECTION |** **INTERNET_FLAG_PRAGMA_NOCACHE):** ----- Figure 33 The Referer header is added to the HTTP request handle using HttpAddRequestHeadersA (0x20000000 = HTTP_ADDREQ_FLAG_ADD): Figure 34 The Accept-Language header is added to the HTTP request handle using HttpAddRequestHeadersA (0x20000000 = HTTP_ADDREQ_FLAG_ADD): Figure 35 The Accept-Encoding header is added to the HTTP request handle using HttpAddRequestHeadersA (0x20000000 = HTTP_ADDREQ_FLAG_ADD): Figure 36 The process exfiltrates the encrypted buffer to the C2 server by calling the HttpSendRequestA routine, as shown below: ----- Figure 37 **Case 3 (Data exfiltration using POST method)** A new HTTP request handle is created by the file (0x80400100 = **INTERNET_FLAG_RELOAD | INTERNET_FLAG_KEEP_CONNECTION |** **INTERNET_FLAG_PRAGMA_NOCACHE):** Figure 38 The Referer header is added to the HTTP request handle using HttpAddRequestHeadersA (0x20000000 = HTTP_ADDREQ_FLAG_ADD): Figure 39 The Accept-Language header is added to the HTTP request handle using HttpAddRequestHeadersA (0x20000000 = HTTP_ADDREQ_FLAG_ADD): Figure 40 The Accept-Encoding header is added to the HTTP request handle using HttpAddRequestHeadersA (0x20000000 = HTTP_ADDREQ_FLAG_ADD): ----- Figure 41 The encrypted buffer is added to a fake JPEG image (note the file signature in the network traffic) and transmitted to the C2 server without raising any suspicion: Figure 42 HttpOpenRequestA is utilized to create a new HTTP request handle. The HTTP method is set to GET ( 0x80480100 = INTERNET_FLAG_RELOAD | **INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_NO_COOKIES |** **INTERNET_FLAG_PRAGMA_NOCACHE):** Figure 43 The file generates 256 random bytes via a function call to CryptGenRandom (the result will be Base64-encoded, and a small part of the output is used as a parameter in the Referer header): Figure 44 The Referer, Accept-Language and Accept-Encoding headers are set as described before. The encrypted buffer that was exfiltrated using one of the 3 methods is Base64-encoded: ----- Figure 45 The Cookie header is set to a string that is obtained from the above using some transformations, and the request is sent to the C2 server, as shown in figure 46. Figure 46 Here is the network request captured by FakeNet: Figure 47 It’s important to mention that the backdoor also performs a “cleaning” operation by freeing the memory in order to hide possible IOCs that could be extracted from it: Figure 48 The status code returned by the server is extracted and compared with 200 (0x20000013 = **HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_STATUS_CODE):** Figure 49 ----- The malicious binary retrieves the size of the resource using the HttpQueryInfoA API (0x20000005 = HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_CONTENT_LENGTH): Figure 50 There is a function call to InternetReadFile, which is utilized to read data received from the C2 server: Figure 51 The response from the C2 server is parsed, and the byte at position 0x1c (28 in decimal) is extracted. There is also a “checksum” of the 5th-8th bytes that is computed, and the result should match the first 4 bytes. We will describe each case depending on that particular byte. **Byte = 0x11 – read the content of a file specified by the C2 server and compute the MD5** hash of it The path of the %TEMP% directory is extracted using GetTempPathA: Figure 52 The path of the %TEMP% directory is converted to its long form by calling the GetLongPathNameA routine, as highlighted below: Figure 53 GetCurrentDirectoryA is utilized to extract the current directory for the current process: ----- Figure 54 The response from the C2 server is supposed to contain a file name, which is opened via a CreateFileA function call (0x80000000 = GENERIC_READ, 0x1 = FILE_SHARE_READ, 0x3 = OPEN_EXISTING, 0x80 = FILE_ATTRIBUTE_NORMAL): Figure 55 The malware creates an unnamed file mapping object using the CreateFileMappingA API (0x8 = PAGE_WRITECOPY): Figure 56 The malicious binary maps the newly created file mapping into the address space of the calling process, as shown in the next pictures (0x1 = FILE_MAP_COPY): Figure 57 Figure 58 The MD5 hashing algorithm is implemented by the malware (note the variables from below), which is used to perform hashing of the file content extracted above: ----- Figure 59 Figure 60 The resulting buffer that will be exfiltrated is similar to the one from figure 21, however, it also contains the MD5 hash value and the file name. The encryption algorithm is the same presented in figure 22 (this is valid for all cases, and we will not repeat it every time): Figure 61 **Byte = 0x12 – create and populate a new file** ----- The backdoor creates a new file specified by the C2 server in the network traffic (0x40000000 = GENERIC_WRITE, 0x1 = FILE_SHARE_READ, 0x1 = CREATE_NEW, 0x80 = FILE_ATTRIBUTE_NORMAL): Figure 62 The newly created file is populated with content provided by the C2 server as well: Figure 63 The final buffer that will be exfiltrated contains the file name: Figure 64 **Byte = 0x13 (same execution flow as 0x11)** **Byte = 0x14 – write specific bytes into memory depending on the C2 server response** Depending on 2 bytes received from the C2 server, the binary writes 0x100, 0x200, 0x400, 0x800, 0x1000 or 0x2000 into memory. The first 3 cases are highlighted in figure 65: Figure 65 The buffer that will be exfiltrated contains a 4-byte value computed from a GetTickCount function call, the “AppID” value and a marker value (0x81 in this case): Figure 66 **Byte = 0x15 – listen on port 8080 and record all connections that are established on this port** A new thread is created using the CreateThread routine: ----- Figure 67 The process creates a new socket using the socket API. The inet_addr function is utilized to convert a string containing an IP dotted-decimal address into a proper address for the IN_ADDR structure, as shown below: Figure 68 There is a mistake done by the malware developers because they’ve called the inet_addr routine with the C2 server as the parameter (and not an IP as above). This function call returns INADDR_NONE (0xFFFFFFFF): Figure 69 The binary associates the local address with the socket created before using the bind API: Figure 70 The listen function is used to place the socket in a listening state for incoming connections: Figure 71 The malware was supposed to connect to the C2 server using the connect API, however, due to the implementation mistake, this function call fails: ----- Figure 72 For the sake of the analysis, we’ve emulated an external connection from a remote IP to the local host on port 8080. The getpeername API is utilized to extract the address of the peer to which the socket is connected: Figure 73 The inet_ntoa routine is the opposite of inet_addr and it’s used to convert an IP from a hex form into an ASCII string (dotted-decimal format): Figure 74 getsockname is utilized to retrieve the local name for the socket: Figure 75 inet_ntoa is used again to convert the IP address from hex to dotted-decimal format, as highlighted in figure 76: Figure 76 The final buffer that will be exfiltrated contains some details about the network connection (source and destination IPs/ports) and the string “listen”: Figure 77 ----- It s important to mention that because of the bug, only this behavior is expected, however, there are other execution flows as well. For example, if no connection is established, the malware only copies the string “idle” in the buffer. If the connection to the C2 server is successful, then the string “connect” would have been copied into the final buffer. Finally, if the connection is successful and the process accepts another connection on port 8080, the string “accept” is copied into the buffer as well. **Byte = 0x16 – create a named pipe and wait for connections** The file creates a new named pipe using the CreateNamedPipeA routine (0x40040003 = **FILE_FLAG_OVERLAPPED | WRITE_DAC | PIPE_ACCESS_DUPLEX, 0x6 =** **PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE):** Figure 78 A new unnamed event object is created by the backdoor: Figure 79 The binary enables the pipe to wait for connections from client processes, as displayed below: Figure 80 Whether the C2 server specifies the “off” parameter in the network traffic, the malware calls the DisconnectNamedPipe API: Figure 81 The buffer that will be exfiltrated is similar to the one presented in figure 66. ----- **Byte = 0x20 – extract timestamps for a file mentioned by the C2 server** The FindFirstFileA routine is utilized to locate a file specified by the C2 server in the network traffic: Figure 82 The malicious process converts the file time to system time format using FileTimeToSystemTime: Figure 83 The GetTimeFormatA API is utilized to convert the time from above to a time string (0x800 = **LOCALE_SYSTEM_DEFAULT, 0x80000000 = LOCALE_NOUSEROVERRIDE):** Figure 84 The GetDateFormatA API is utilized to convert the date from above to a date string (0x800 = **LOCALE_SYSTEM_DEFAULT, 0x80000000 = LOCALE_NOUSEROVERRIDE):** Figure 85 The final buffer that will be exfiltrated contains the file name, file creation date and time, and the length of the file content: Figure 86 ----- If any error occurs during an operation such as creating a file, opening a file, and so in all studied cases, the malware formats the error message using FormatMessageA and copies it to the final buffer (0x1000 = FORMAT_MESSAGE_FROM_SYSTEM, 0x2 = **ERROR_FILE_NOT_FOUND):** Figure 87 **Byte = 0x21 – move a file to a new file** The response from the C2 server contains 2 file names. The process moves the first file to the second one by calling the MoveFileA API: Figure 88 The buffer that will be exfiltrated is similar to the one presented in figure 66. **Byte = 0x22 – copy a file to a new file** The response from the C2 server contains 2 file names. The malware copies the first file to the second one by calling the CopyFileA API: Figure 89 The buffer that will be exfiltrated is similar to the one presented in figure 66. **Byte = 0x23 – delete a file** The response from the C2 server contains a file name. The binary deletes the file using the DeleteFileA function: Figure 90 The buffer that will be exfiltrated is similar to the one presented in figure 66. ----- **Byte = 0x24 – retrieve the current directory for the process** GetCurrentDirectoryA is used to extract the current directory for the process: Figure 91 The final buffer that will be exfiltrated contains the path extracted above: Figure 92 **Byte = 0x25 – create a directory** The response from the C2 server contains a directory name. The backdoor creates the new directory using the CreateDirectoryA routine: Figure 93 The buffer that will be exfiltrated is similar to the one presented in figure 66. **Byte = 0x26 – delete a directory** The response from the C2 server contains a directory name. The binary deletes the directory using the RemoveDirectoryA routine: Figure 94 The buffer that will be exfiltrated is similar to the one presented in figure 66. **Byte = 0x27 – change the current directory for the process** The response from the C2 server contains a directory name. The process changes the current directory for the process to this directory: Figure 95 The buffer that will be exfiltrated is similar to the one presented in figure 66. ----- **Byte = 0x28 – set the current directory for the process to the %TEMP% folder** GetTempPathA is utilized to retrieve the path of the %TEMP% directory: Figure 96 The file changes the current directory for the process using the SetCurrentDirectoryA API: Figure 97 **Byte = 0x29 – retrieve the valid drives on the system and their type** The valid drives on the system are extracted by calling the GetLogicalDriveStringsA function: Figure 98 The backdoor extracts the type of the drive using the GetDriveTypeA API, as displayed in figure 99. Figure 99 The final buffer that will be exfiltrated contains the drives name and a string that categorizes their type: Figure 100 The following strings are hard-coded and indicate the type of drives: unk (DRIVE_UNKNOWN), nrt (DRIVE_NO_ROOT_DIR), rmv (DRIVE_REMOVABLE), fix (DRIVE_FIXED), net (DRIVE_REMOTE), cdr (DRIVE_CDROM), ram (DRIVE_RAMDISK) and und (most likely UNDEFINED). **Byte = 0x2A – retrieve the computer Uptime and encrypt the value** The malware calls the GetTickCount function and stores the result in a separate buffer: Figure 101 ----- The 4-byte value extracted above is encrypted using a custom algorithm: Figure 102 The final buffer that will be exfiltrated contains the result of the above encryption: Figure 103 **Byte = 0x30 – retrieve the path of an executable that corresponds to a particular process ID** The response from the C2 server contains a string with a process ID. The atoi function is used to convert the string to a number: ----- Figure 104 The malicious binary opens the local process object that corresponds to the process ID using the OpenProcess routine (0x1F0FFF = PROCESS_ALL_ACCESS): Figure 105 EnumProcessModules is utilized to enumerate the modules of the targeted process: Figure 106 GetModuleFileNameExA is used to retrieve the path of the file that contains a specific module. This is an interesting way to find out the path to the executable that corresponds to the targeted process ID: Figure 107 The final buffer that will be exfiltrated contains the address of the module from above and the path to the executable: Figure 108 **Byte = 0x31 – kill a process** The response from the C2 server contains a string with a process ID. The backdoor opens the local process object that corresponds to the process ID using the OpenProcess routine (0x1= PROCESS_TERMINATE): ----- Figure 109 The binary kills the targeted process using TerminateProcess, as described in figure 110: Figure 110 The final buffer that will be exfiltrated contains the string “term” (which probably refers to terminate) and the process ID: Figure 111 **Byte = 0x32 – create a new process** The response from the C2 server contains a process name. The malware creates this process by calling the CreateProcessA API: Figure 112 The final buffer that will be exfiltrated contains the ID of the process created earlier: Figure 113 **Byte = 0x33 – create a new process in the security context of the credentials received from** the C2 server The response from the C2 server contains the following data: user, password, Windows domain, and process name. Two anonymous pipes are created using the CreatePipe API: ----- Figure 114 Figure 115 GetCurrentDirectoryW is utilized to retrieve the current directory for the process: Figure 116 The binary creates a new process that runs in the context of the credentials extracted from the network traffic via a CreateProcessWithLogonW function call: Figure 117 The executable extracts a handle for each module in the process created above by calling the EnumProcessModules routine: Figure 118 There is a call to GetModuleFileNameExA that extracts the path of the file containing the above module: ----- Figure 119 The buffer that will be exfiltrated is similar to the one presented in figure 108. **Byte = 0x34 (same execution flow as 0x33)** **Byte = 0x40 – retrieve the current process ID, the path of the executable, the hostname, the** username, and the default locale GetModuleFileNameA is utilized to extract the path of the executable of the current process: Figure 120 The malware retrieves the NetBIOS name of the local computer and the user name by calling the GetComputerNameA and GetUserNameA functions, respectively: Figure 121 Figure 122 The current process ID is extracted using the GetCurrentProcessId routine: Figure 123 GetLocaleInfoA is utilized to retrieve information about the default locale for the user or process (0x400 = LOCALE_USER_DEFAULT): Figure 124 ----- The final buffer that will be exfiltrated contains the current process ID, the path of the executable, the hostname, the username, the “AppID” value, the C2 server, the HTTP method used during network communications, the pipe name mentioned in Case1 of Data Exfiltration, and the user’s language (English – United States): Figure 125 **Byte = 0x41 –retrieve the current process ID, the path of the executable, the hostname, the** username, and the default locale GetModuleFileNameA is utilized to extract the path of the executable of the current process: Figure 126 The GetComputerNameA and GetUserNameA APIs are used to retrieve the hostname and the username associated with the current thread: Figure 127 Figure 128 GetCurrentProcessId is utilized to extract the ID of the current process: Figure 129 The default locale for the user or process is extracted using GetLocaleInfoA (0x400 = **LOCALE_USER_DEFAULT):** ----- Figure 130 The final buffer that will be exfiltrated contains the current process ID, the path of the executable, the hostname, the username, and the user’s language (English – United States): Figure 131 **Byte = 0x48 – retrieve the hostname and username** The malware extracts the username and hostname as before: Figure 132 Figure 133 The final buffer that will be exfiltrated contains the hostname and username, as highlighted in figure 134: Figure 134 **Byte = 0x49 – exfiltrate the C2 domain name and port number** The final buffer that will be exfiltrated contains the C2 server and the port number: Figure 135 **Byte = 0x85 – close open handles** There is only a FindClose function call regarding this case. The buffer that will be exfiltrated is similar to the one presented in figure 66. **Byte = 0x8B – close open handles** ----- This is also a cleaning case because the backdoor calls the CloseHandle API a few times. The buffer that will be exfiltrated is similar to the one presented in figure 66. **Byte = 0x98 calculate the MD5 hash of the empty string** The process computes the MD5 hash of the empty string and saves the result to the buffer that will be exfiltrated: Figure 136 **Byte = 0xC4 – close open handles** No notable activity regarding this case. The buffer that will be exfiltrated is similar to the one presented in figure 66. **Byte = 0xC7 – close open handles and unmap a mapped view of a file** The binary performs 2 function calls to CloseHandle and a call to UnmapViewOfFile. The buffer that will be exfiltrated is similar to the one presented in figure 66. **Byte = 0xCA – close open handles** No notable activity regarding this case. The buffer that will be exfiltrated is similar to the one presented in figure 66. **Byte = 0xE1 – resume a suspended thread and copy data from a pipe** The malicious process resumes a thread that was previously suspended using the ResumeThread routine: Figure 137 PeekNamedPipe is utilized to copy data from a named or anonymous pipe into a buffer without removing it from the pipe: Figure 138 Whether more data is available in the pipe, the malware reads it using the ReadFile API: ----- Figure 139 The buffer that will be exfiltrated contains the data received from the pipe: **Byte = 0xE2 – copy data from a pipe** Figure 140 The executable copies data from a named or anonymous pipe into a buffer via a PeekNamedPipe function call: Figure 141 The ReadFile function is utilized to read more data from the pipe if it’s available: Figure 142 The buffer that will be exfiltrated contains the data received from the pipe: Figure 143 **Byte = 0xE3 – kill a process** The backdoor kills a specific process, whose handle is read from memory: Figure 144 The buffer that will be exfiltrated is similar to the one presented in figure 66. ----- **Byte = 0xFE – close open handles** The binary performs a function call to CloseHandle and closesocket. The buffer that will be exfiltrated is similar to the one presented in figure 66. **Byte = 0xFF – copy a string that probably represents the exit of the program** The malware copies the string “Exiting…” to the final buffer that will be exfiltrated: Figure 145 References [MSDN: https://docs.microsoft.com/en-us/windows/win32/api/](https://docs.microsoft.com/en-us/windows/win32/api/) VirusTotal: https://www.virustotal.com/gui/file/6057b19975818ff4487ee62d5341834c53ab80a507949a52 422ab37c7c46b7a1 Fakenet: [https://github.com/fireeye/flare-fakenet-ng](https://github.com/fireeye/flare-fakenet-ng) MalwareBazaar: https://bazaar.abuse.ch/sample/6057b19975818ff4487ee62d5341834c53ab80a507949a524 22ab37c7c46b7a1/ ESET: https://www.welivesecurity.com/wpcontent/uploads/2019/10/ESET_Operation_Ghost_Dukes.pdf Kaspersky: https://securelist.com/miniduke-is-back-nemesis-gemina-and-the-botgenstudio/64107/ Cybersecurity Advisory: https://media.defense.gov/2021/Apr/15/2002621240/-1/-1/0/CSA_SVR_TARGETS_US_ALLI ES_UOO13234021.PDF/CSA_SVR_TARGETS_US_ALLIES_UOO13234021.PDF INDICATORS OF COMPROMISE C2 server: salesappliances[.]com SHA256: 6057b19975818ff4487ee62d5341834c53ab80a507949a52422ab37c7c46b7a1 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36 (prone to False Positives) Named Pipe: \\pipe\DefPipe -----