# Makop Ransomware ### Prepared by: LIFARS, LLC Date: 8/13/2021 #### 1 ----- ## EXECUTIVE SUMMARY Makop ransomware encrypts user’s files using the AES256 algorithm and advises the victims to contact the attackers via Tox (P2P instant-messaging protocol). The ransomware imports an AES256 key that is used to decrypt a lot of strings, including an RSA public key. There is a mutex called “m23071644” created by the process to ensure that only one instance is running at a single time and a new process spawned by the malware that encrypts network shares. The Windows Product ID is extracted from the registry and is used to generate a personal ID that will also be present in the ransom note. The ransomware deletes all volume shadow copies and kills specific processes that could lock different targeted file types. The malware operators are aware of other ransomware families because they don’t encrypt possibly encrypted files by ransomware such as Shootlock, RAGA and origami. Two new AES256 keys are generated by the ransomware, which will be used interchangeably to encrypt the content of the files. A new initialization vector (IV) that consists of 16 bytes is generated and stored in the encrypted file, and the AES key used for encryption is encrypted using the RSA public key. There is no possibility to decrypt the files without knowing the RSA private key that corresponds to the hard-coded public one. Even if the operators pretend that they exfiltrate data from the network, we didn’t observe any network communications. ----- ## ANALYSIS AND FINDINGS SHA256:9D90919B4434B9CAC736945384857209103FDF1A749671F190C947FDA8CC1681 The malware uses the GetVersion function to retrieve the major and minor version numbers of the OS along with other information: ###### Figure 1 The Get TokenInformation API is used to determine the elevation level of the token (0x14 = TokenElevationType): ----- ###### Figure 2 The ransomware retrieves the command-line string for the current process and compares the number of arguments with 2: Figure 3 ----- The CryptAcquireContextW routine is utilized to acquire a handle to a key container within a cryptographic service provider (0x18 = PROV_RSA_AES): ###### Figure 4 The following 32 bytes represent an AES256 key that will be used to decrypt a lot of strings at runtime: ###### Figure 5 The AES key constructed earlier is imported by calling the CryptImportKey API, as shown in figure 6: ----- ###### Figure 6 The parameters of the blob are explained below: - 08 - PLAINTEXTKEYBLOB – the key is a session key - 02 – CUR_BLOB_VERSION - 0x6610 – CALG_AES_256 - 0x20 – key size Using the AES key, the binary decrypts data by calling the CryptDecrypt function: ###### Figure 7 The result of the decryption is an RSA public key: ###### Figure 8 The parameters of the blob are detailed below: - 06 – PUBLICKEYBLOB – the key is a public key - 02 – CUR_BLOB_VERSION - 0xa400 – CALG_RSA_KEYX - 0x0400 – key size - 0x010001 – public key exponent Other strings are decrypted by the malicious process using the same hard-coded AES key: ----- ###### Figure 9 The malware retrieves the address of the following export functions by calling the GetProcAddress routine: Wow64DisableWow64FsRedirection, Wow64RevertWow64FsRedirection and CreateProcessWithTokenW. GetLocaleInfoW is used to retrieve the LOCALE_FONTSIGNATURE value for the default locale of the OS (0x800 = LOCALE_SYSTEM_DEFAULT and 0x58 = LOCALE_FONTSIGNATURE): ###### Figure 10 The ransomware decrypts even more strings, and their purpose will be explained later on: ----- ###### Figure 11 ###### Figure 12 ----- The binary retrieves a handle to the Shell’s desktop window using the GetShellWindow API, as shown in the next figure: ###### Figure 13 GetWindowThreadProcessId is utilized to extract the identifier of the thread and of the process that created the window from above: ###### Figure 14 The malware obtains the join status information for the local computer by calling the NetGetJoinInformation function: ###### Figure 15 Some directories names and a mutex name are decrypted by the executable, as shown in figure 16: ###### Figure 16 The value of the “SystemDrive” environment variable is retrieved using the GetEnvironmentVariableW API: ----- ###### Figure 17 The ransomware creates a mutex called “m23071644” to ensure that only one instance of the executable is running at a single time: ###### Figure 18 The process opens the “SOFTWARE\Microsoft\Windows NT\CurrentVersion” registry key using the RegOpenKeyExA routine: ###### Figure 19 The Windows product ID is extracted from the registry and it will be used to compute a victim ID: ###### Figure 20 The ransomware extracts the volume serial number of the C drive by calling the GetVolumeInformationW API: ----- ###### Figure 21 The malware uses a custom “hash” function to compute a 4-byte value that corresponds to the Product ID. A snippet of the implementation is shown below: ###### Figure 22 Two more strings are decrypted by the ransomware using the AES key imported before: ----- ###### Figure 23 The binary disables the file system redirection for the calling thread using Wow64DisableWow64FsRedirection: ###### Figure 24 An open handle to the current process is obtained by calling the GetCurrentProcessId and OpenProcess APIs: ###### Figure 25 The malicious executable opens the access token associated with the current process: ###### Figure 26 DuplicateTokenEx is utilized to create a new access token that duplicates the existing token: ----- ###### Figure 27 The ransomware creates an anonymous pipe by calling the CreatePipe function: ###### Figure 28 There is a new process spawned by the malware with the “-n” parameter. The new process handles the encryption of the network shares, as will be detailed in the upcoming paragraphs: ###### Figure 29 The process restores the file system redirection for the current thread: ###### Figure 30 ----- The file enforces the system to send critical errors to the calling process using the SetErrorMode API (0x1 = SEM_FAILCRITICALERRORS). It obtains the currently available disk drives using GetLogicalDrives: ###### Figure 31 The GetDriveTypeW API determines if a disk drive is a removable, fixed, CD-ROM, RAM or network drive. Makop doesn’t target CD-ROM drives and RAM disks: ###### Figure 32 The malware opens the “C:\” drive using the CreateFileW routine (0x80000000 = GENERIC_READ, 0x3 = **FILE_SHARE_READ|FILE_SHARE_WRITE,** 0x3 = **OPEN_EXISTING** and 0x80 = **FILE_ATTRIBUTE_NORMAL):** ###### Figure 33 DeviceIoControl is utilized to retrieve the physical location of the specified volume (0x560000 = **IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS):** ----- ###### Figure 34 Makop generates 2 buffers of 32 random bytes using the CryptGenRandom API (let’s call the first one **AESKey1 and the second one AESKey2):** ###### Figure 35 ###### Figure 36 4 bytes that will be used as a marker in the encrypted files are decrypted by the binary: “AD AD 6B A1”. The RSA public key is imported using the CryptImportKey function: ----- ###### Figure 37 These 2 buffers are encrypted using the RSA public key and contain the following information: 4-byte marker, 4-byte “hash” value of Product ID generated earlier, 4-byte the volume serial number, 4-byte value obtained from the result of the GetLocaleInfoW call, AESKey1 (or AESKey2) and 4-byte “hash” value of this buffer, computed using the same function used for Product ID: ###### Figure 38 ----- ###### Figure 39 The ransomware decrypts the following strings and uses the GetProcAddress API to obtain the addresses of the export functions: ###### Figure 40 NtQueryObject is used to retrieve information about the system and the current process (0x3 = **ObjectAllTypesInformation):** ###### Figure 41 The executable gets information about the OS using the RtlGetVersion API. It compares the major version number (0xa for Windows 10) of the OS with 0x6: ----- ###### Figure 42 There is a call to GetTokenInformation that obtains information about whether virtualization is enabled for the token (0x18 = TokenVirtualizationEnabled): ###### Figure 43 The malware decrypts even more data using the CryptDecrypt routine: ###### Figure 44 The ComSpec environment variable points to the command line interpreter and its content is extracted using the GetEnvironmentVariableW API: ###### Figure 45 The CreatePipe routine is utilized to create an anonymous pipe that is used as an inter-process communication mechanism: ----- ###### Figure 46 The pipe created above will be inherited by child processes: ###### Figure 47 There is a new cmd.exe process created by the ransomware: ###### Figure 48 All volume shadow copies are deleted by the cmd.exe process using the following commands: - vssadmin delete shadows /all /quiet - wbadmin delete catalog -quiet - wmic shadowcopy delete ----- ###### Figure 49 The output of the above operations is transmitted to our initial process via pipes: ###### Figure 50 A small part of the processes that will be killed by the malware is presented in figure 51 (the entire list can be found in the appendix): ###### Figure 51 ----- CreateToolhelp32Snapshot is utilized to take a snapshot of the processes (0x2 = **TH32CS_SNAPPROCESS):** ###### Figure 52 The processes are enumerated using the Process32FirstW and Process32NextW functions: ###### Figure 53 The following function is used to compare processes’ names with the targeted list: ----- ###### Figure 54 Any targeted process found is killed using the TerminateProcess routine: ###### Figure 55 ----- The following extension will be appended to the encrypted files (note the “hash” of the Product ID): ###### Figure 56 A new thread is created to encrypt the current directory. Similar threads will be created to encrypt the “C:\”, “C:\ProgramData” and “C:\Users” directories: ###### Figure 57 It’s important to mention that the following folders will not be encrypted: “C:\WINDOWS”, "C: \ProgramData\microsoft\windows\caches", “C:\Users\All Users\Microsoft\Windows\Caches” and "C: \Users\Public". Also, the process doesn’t target directories that contain “windows” or “winnt” in their names. ## THREAD ACTIVITY – START ADDRESS FUNCTION The files are enumerated using the FindFirstFileW and FindNextFileW APIs: ###### Figure 58 The files that have the following extensions will be skipped: "makop", "CARLOS", "shootlock", "shootlock2", "1recoesufV8Sv6g", "1recocr8M4YJskJ7", "btc", "KJHslgjkjdfg", "origami", "tomas", "RAGA", "zbw", "fireee", "XXX", "element", "HELP", "zes", "lockbit", "captcha", "gunga", "fair", "SOS", "Boss", "moloch", "BKGHJ", "WKSGJ", "termit", "BBC", "dark", "id2020", "arch", "Raf", "ryan", "zxz", "XXL", "xakepz", "exe", "dll", "sphera", "Lookfornewitguy", "XHAMSTER", "xdqd", "BTCHORSEBORIS", "code". Some of these extensions like shootlock, origami, raga and others are the result of other ransomware infections (Shootlock, Origami and Raga ransomware). The following files are not encrypted by Makop: “boot.ini”, ----- “bootfont.bin”, “ntldr”, “ntdetect.com”, “io.sys”, “readme-warning.txt”, “desktop.ini”. The ransomware opens a file for encryption using the CreateFileW API: ###### Figure 59 CryptGenRandom is utilized to generate 16 random bytes: ###### Figure 60 The process imports AESKey1 using the CryptImportKey routine: ###### Figure 61 ----- The initialization vector (IV) is set to the 16-byte buffer generated above: ###### Figure 62 The filename is encrypted using AESKey1: The encrypted filename is written to the file: ###### Figure 63 ----- ###### Figure 64 A 4-byte value that represents the encrypted filename size is also written to the file: ###### Figure 65 The initialization vector that was generated earlier is added to the encrypted file: ###### Figure 66 The encrypted buffer that also contains AESKey1 is written to the file: ----- ###### Figure 67 Makop adds 8 NULL bytes after the encrypted content from above: ###### Figure 68 The ransomware reads the content of the file by calling the ReadFile function: ###### Figure 69 The file content is encrypted using AESKey1: ----- ###### Figure 70 The encrypted content is written to the file: ###### Figure 71 ##### The file extension is changed to show that the file has been encrypted: ###### Figure 72 The ransom note name and content are also decrypted at runtime: ----- ###### Figure 73 The ransom note that contains the personal ID is shown below: ###### Figure 74 It's important to mention that AESKey1 and AESKey2 are successively used to encrypt files. ## RUNNING WITH “-n” PARAMETER Makop verifies that the Process ID that comes with the “-n” parameter is composed of digits only: ----- ###### Figure 75 The binary creates a new thread that will enumerate the network resources: ###### Figure 76 The WNetOpenEnumW and WNetEnumResourceW APIs are used to enumerate the network resources. The malicious executable is looking for network shares that will also be encrypted: ----- ###### Figure 77 ----- ## APPENDIX ###### List of processes to be stopped msftesql.exe sqlagent.exe sqlbrowser.exe sqlservr.exe sqlwriter.exe oracle.exe ocssd.exe dbsnmp.exe synctime.exe agntsrvc.exe mydesktopqos.exe isqlplussvc.exe xfssvccon.exe mydesktopservice.exe ocautoupds.exe encsvc.exe firefoxconfig.exe tbirdconfig.exe ocomm.exe mysqld.exe mysqld-nt.exe mysqld-opt.exe ----- dbeng50.exe sqbcoreservice.exe excel.exe infopath.exe msaccess.exe mspub.exe onenote.exe outlook.exe powerpnt.exe steam.exe thebat.exe thebat64.exe thunderbird.exe visio.exe winword.exe wordpad.exe -----