# VERMIN: Quasar RAT and Custom Malware Used In Ukraine **[researchcenter.paloaltonetworks.com/2018/01/unit42-vermin-quasar-rat-custom-malware-used-ukraine/](https://researchcenter.paloaltonetworks.com/2018/01/unit42-vermin-quasar-rat-custom-malware-used-ukraine/)** Juan Cortes, Tom Lancaster January 29, 2018 By [Juan Cortes and](https://unit42.paloaltonetworks.com/author/juan-cortes/) [Tom Lancaster](https://unit42.paloaltonetworks.com/author/tom-lancaster/) January 29, 2018 at 5:00 AM [Category: Unit 42](https://unit42.paloaltonetworks.com/category/unit42/) Tags: [AutoFocus,](https://unit42.paloaltonetworks.com/tag/autofocus/) [ConfuserEx,](https://unit42.paloaltonetworks.com/tag/confuserex/) [Espionage,](https://unit42.paloaltonetworks.com/tag/espionage/) [Quasar,](https://unit42.paloaltonetworks.com/tag/quasar/) [Quasar RAT,](https://unit42.paloaltonetworks.com/tag/quasar-rat/) [Ukraine,](https://unit42.paloaltonetworks.com/tag/ukraine/) [VERMIN](https://unit42.paloaltonetworks.com/tag/vermin/) Summary Palo Alto Networks Unit 42 has discovered a new malware family written using the Microsoft .NET Framework which the authors call "VERMIN"; an ironic term for a RAT (Remote Access Tool). Cursory investigation into the malware showed the attackers not only had flair for malware naming, but also for choosing interesting targets for their malware: nearly all the targeting we were able to uncover related to activity in Ukraine. Pivoting further on the initial samples we discovered, and their infrastructure, revealed a modestly sized campaign going back to late 2015 [using both Quasar RAT and VERMIN.](https://github.com/quasar/QuasarRAT) This blog shows the links between the activity observed, a walkthrough of the analysis of the VERMIN malware, and IOCs for all activity discovered. It all began with a tweet [Our initial interest was piqued through a tweet from a fellow researcher who had identified some malware with an interesting theme relating to](https://twitter.com/blu3_team/status/917050823724732419) the Ukrainian Ministry of Defense as a lure. _Figure 1 – The decoy document displayed to users when executing the initial malware sample_ ----- The sample was an SFX exe which displayed a decoy document to users before continuing to execute the malware; the hash of the file is given below. SHA256 31a1419d9121f55859ecf2d01f07da38bd37bb11d0ed9544a35d5d69472c358e [The malware was notable for its rare use of HTTP encapsulated SOAP, an XML based protocol used for exchanging structured information, for](https://en.wikipedia.org/wiki/SOAP) command and control (C2), which is something not often seen in malware samples. Using AutoFocus, we were quickly able to find similar samples, by pivoting on the artifacts the malware created during a sandbox run, resulting in 7 other samples as shown in Figure 2. _Figure 2 – Pivoting in AutoFocus makes it easy to find similar malware samples._ Using the [Maltego for AutoFocus transforms, we were then able to take the newly discovered samples and look at the C2 infrastructure in an](https://live.paloaltonetworks.com/t5/Maltego-for-AutoFocus/ct-p/AutoFocus_Maltego) attempt to see if we could link the samples together and in turn see if these C2’s were contacted by malware. We quickly built up a picture of a campaign spanning just over 2 years with a modest C2 infrastructure: _Figure 3 – Further analysis using AutoFocus & other data sources allows us to link up the activity discovered so far._ The malware samples we discovered fell largely into two buckets: Quasar Rat and VERMIN. Quasar RAT is an open-source malware family [which has been used in several other attack campaigns including criminal and](https://community.rsa.com/community/products/netwitness/blog/2017/10/02/malspam-delivers-rat-spyware-quasar-9-27-2017) [espionage motivated attacks. But a reasonable number of the](https://blog.paloaltonetworks.com/2017/01/unit42-downeks-and-quasar-rat-used-in-recent-targeted-attacks-against-governments/) samples were the new malware family, VERMIN. Looking at the samples in our cluster we could see the themes of the dropper files were similar to our first sample. Notably, most of the other files we discovered did not come bundled with a decoy document and instead were simply the malware and dropper compiled with icons matching popular document viewing tools, such as Microsoft Word. Names of some of the other dropper binaries observed are given below, with the original Ukrainian on the left and the translated English (via Google) on the right: **Original Name (Ukrainian)** **Translated Name (if applicable)** Ваш_ сертиф_кати для отримання безоплатно_ вторинно_ допомоги.exe Your certificate for free_receive help.exe ----- доповідь2.exe report2.exe доповідь забезпечення паливом 08.06.17.exe fuel supply report 08.06.17.exe lg_svet_smeta2016-2017cod.exe. lugansk_2273_21.04.2017.exe N/A N/A Отчет-районы_2кв-л-2016.exe Report-areas_2kv-l-2016.exe Given the interesting targeting themes and the discovery of a new malware family, we decided to take a peek at what “VERMIN” was capable of and document it here. Dissecting VERMIN For this walkthrough, we’ll be going through the analysis of the following sample: SHA256 98073a58101dda103ea03bbd4b3554491d227f52ec01c245c3782e63c0fdbc07 Compile Timestamp 2017-07-04 12:46:43 UTC Analyzing the malware dynamically quickly gave us a name for the malware, based on the PDB string present in the memory of the sample: Z:\Projects\Vermin\TaskScheduler\obj\Release\Licenser.pdb As is the case with many of the samples from the threat actors behind VERMIN, our sample is packed initially with the popular .NET [obfuscation tool ConfuserEx. Using a combination of tools, we were able to unpack and deobfuscate the malware.](https://yck1509.github.io/ConfuserEx/) [Following initial execution, the malware first checks if the installed input language in the system is equal to any of the following:](https://technet.microsoft.com/en-us/library/cc766191(v=ws.10).aspx) ru - Russian uk - Ukrainian ru-ru - Russian uk-ua - Ukrainian [If none of the languages above is found the malware calls “Application.Exit()”, however despite its name, this API call doesn’t actually](https://msdn.microsoft.com/en-us/library/ms157894(v=vs.110).aspx) successfully terminate the application, and instead the malware will continue to run. It’s likely the author intended to terminate the application, in which case a call like “System.Environment.Exit()” would have been a better choice. The fact that this functionality does not work as intended suggests that if author tested the malware before deployment, they were likely to be doing so on systems where the language matches the list above, since otherwise they would notice that the function is not working as expected. After passing the installed language check the malware proceeds to decrypt an embedded resource using the following logic: It retrieves the final four bytes of the encrypted resource. These four bytes are a CRC32 sum, and the malware then proceeds to brute force what 6-byte values will give this CRC32 sum. Once it finds this array of 6 bytes it performs an MD5 hash sum on the bytes, this value is used as the key. The first 16bytes of the encrypted resource are then used as the IV for decryption Finally, using AES it decrypts the embedded resource. A script mirroring this routine can be found in appendix C. After decrypting the embedded resource, the malware passes several hardcoded arguments to the newly decrypted binary and performs a simple setup routine before continuing execution. The embedded resource contains all the main code for communications and functionality the RAT contains. First the malware attempts to decrypt all of the strings passed as parameters. If no arguments were supplied the malware attempts to read a configuration file from a pre-defined location expecting it to be base64-encoded and encrypted with 3-DES using a hardcoded key "KJGJH&^$f564jHFZ": C:\Users\Admin\AppData\Roaming\Microsoft\AddIns\settings.dat If arguments were supplied, they are saved and encrypted to the same location as above. Parameters supplied are given below. Note that these are the actual variable names used by the malware author: serverIpList mypath keyloggerPath mutex username password keyloggerTaskName myTaskName ----- y ocess a e keyLoggerProcessName myTaskDecription myTaskAuthor keyLoggerTaskDecription keyLoggerTaskAuthor The decrypted resource is set to be run as a scheduled task every 30 minutes, indefinitely. After this, the malware is ready to start operations, and does so by collecting various information about the infected machine, examples of collected information includes but is not limited to: Machine name Username OS name via WMI query Architecture: x64 vs x86 (64 vs. 32 bit) Local IP Address Checks Anti-Virus installed via WMI query If the Anti-Virus (AV) query determines any AV is installed the malware does not install the keylogger. The keylogger is embedded as a resource named ‘AdobePrintFr’. This binary is only packed with Confuser-Ex and is not further obfuscated. The malware then sends its initial beacon using a SOAP envelope to establish a secure connection. The author uses the WSHttpBinding() API - which allows the author to use WS-Addressing and purposely sets the WSMessageEncoding.Mtom to encode the SOAP messages. The author also sets up for using ‘Username’ authentication for communicating with its C2, presumably allowing the author easier control over the various infected hosts. A defanged exemplar request/response is given below: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 POST /CS HTTP/1.1 MIME-Version: 1.0 Content-Type: multipart/related; type="application/xop+xml";start="";boundary="uuid:ae621187-99b2-4b50-8a74-a33e8 Host: akamainet024[.]info Content-Length: 1408 Expect: 100-continue Accept-Encoding: gzip, deflate Connection: Keep-Alive --uuid:ae621187-99b2-4b50-8a74-a33e8c7c0990+id=3 Content-ID: Content-Transfer-Encoding: 8bit Content-Type: application/xop+xml;charset=utf-8;type="application/soap+xml" http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issueurn:uuid:159e7656-a3ea-4099-aa http://www.w3.org/2005/08/addressing/anonymoushttp://akamainet024 http://schemas.xmlsoap.org/ws/2005/02/sc/scthttp://schemas.xmlsoap.org/ws/2005/02/trust/Is FgMBAFoBAABWAwFaCdyfpYsLZDbnCizlWg3iw2M80KiaWb+oIgzhJ1BvugAAGAAvADUABQAKwBPAFMAJwAoAMgA --uuid:ae621187-99b2-4b50-8a74-a33e8c7c0990+id=3- VERMIN collects all keystrokes and clipboard data and encrypts the data before storing it in the following folder: %appdata%\Microsoft\Proof\Settings.{ED7BA470-8E54-465E-825C-99712043E01C}\Profiles\. Each file is saved with the following format: "{0:dd-MM-yyyy}.txt". The data is encrypted using the same method and 3-DES key, used to encrypt the configuration file. Vermin supports the following commands: ArchiveAndSplit CancelDownloadFile CancelUploadFile CheckIfProcessIsRunning CheckIfTaskIsRunning CreateFolder DeleteFiles DeleteFolder DownloadFile GetMonitors GetProcesses KillProcess ReadDirectory RenameFile RenameFolder RunKeyLogger ----- Set c o u e ShellExec StartAudioCapture StartCaptureScreen StopAudioCapture StopCaptureScreen UpdateBot UploadFile For most of these commands, the malware requires “hands-on-keyboard” style one-to-one interactions. Often remote access tools written in .NET borrow and steal code from other tools due to the plethora of code available through open source; however, it appears that whilst some small segments of code may have been lifted from other tools, this RAT is not a fork of a well-known malware family: it’s mostly original code. We have linked all the samples we have been able to identify to the same cluster of activity: this strongly suggests the VERMIN malware is used exclusively by this threat actor and this threat actor alone. Concluding thoughts We were unable to definitively determine the aims of the attackers or the data stolen. However, given the limited number of samples, the targeting themes observed, and the “hands-on-keyboard” requirement for most of the malwares’ operations (except for keylogging), it seems likely that the malware is used in targeted attacks in Ukraine. [Ukraine remains a ripe target for attacks, even gaining its own dedicated Wikipedia page for attacks observed in 2017. In addition to the high-](https://en.wikipedia.org/wiki/2017_cyberattacks_on_Ukraine) profile attacks such as the [Petya/NotPetya and](https://www.theregister.co.uk/2017/06/28/petya_notpetya_ransomware/) [BadRabbit, which have been widely reported, there are likely many smaller campaigns like the](https://www.crowdstrike.com/blog/badrabbit-ms17-010-exploitation-part-one-leak-and-control/) one described in this blog aimed to steal data to gain an information advantage for the attackers’ sponsors. Palo Alto Networks defends our customers against the samples discussed in this blog in the following ways: Wildfire identifies all samples mentioned in this article as malicious. Traps identifies all samples mentioned in this article as malicious. C2 domains used in this campaign are blocked via Threat Prevention. AutoFocus customers can track samples related to this blog via the following tags: [VERMIN](https://autofocus.paloaltonetworks.com/#/tag/Unit42.VERMIN%20https://autofocus.paloaltonetworks.com/#/tag/Unit42.VERMINCampaign%20https://autofocus.paloaltonetworks.com/#/tag/Unit42.VERMIN) [VERMINKeylogger](https://autofocus.paloaltonetworks.com/#/tag/Unit42.VERMIN%20https://autofocus.paloaltonetworks.com/#/tag/Unit42.VERMINCampaign%20https://autofocus.paloaltonetworks.com/#/tag/Unit42.VERMINKeyLogger) [VERMINCampaign](https://autofocus.paloaltonetworks.com/#/tag/Unit42.VERMIN%20https://autofocus.paloaltonetworks.com/#/tag/Unit42.VERMINCampaign%20https://autofocus.paloaltonetworks.com/#/tag/Unit42.VERMINCampaign) **Appendix A – C2 Addresses** akamaicdn[.]ru cdnakamai[.]ru www.akamaicdn[.]ru www.akamainet066[.]info www.akamainet023[.]info www.akamainet021[.]info akamainet023[.]info akamainet022[.]info akamainet021[.]info www.akamainet022[.]info akamainet066[.]info akamainet024[.]info www.cdnakamai[.]ru notifymail[.]ru www.notifymail[.]ru mailukr[.]net tech-adobe.dyndns[.]biz www.mailukr[.]net 185.158.153[.]222 94.158.47[.]228 195.78.105[.]23 94.158.46[.]251 188.227.75[.]189 212.116.121[.]46 185.125.46[.]24 5.200.53[.]181 **Appendix B – Malware Samples** ----- **sha256** **Family** 0157b43eb3c20928b77f8700ad8eb279a0aa348921df074cd22ebaff01edaae6 Quasar 154ef5037e5de49a6e3c48ea7221a02a5df33c34420a586cbff6a46dc5026a91 Quasar 24956d8edcf2a1fd26805ec58cfd1ee7498e1a59af8cc2f4b832a7ab34948c18 Quasar 250cf8b44fc3ae86b467dd3a1c261a6c3d1645a8a21addfe7f2e2241ff8b79fc Quasar 4c5e019e0e55a3fe378aa339d52c235c06ecc5053625a5d54d65c4ae38c6e3da Quasar 92295b38daa4e44b9d257e56c5b271bbbf6a620312dc58e48e56473427170aa1 Quasar 9ea00514c4ae9519a8938924b02826cfafeb75fc70f16c422aeadb8317a146c1 Quasar a3c84c5f8d981653a2a391d29f32c8127fba8f0ab7da8815330a228205c99ba6 Quasar 7b08b0d4d68ebf5238eaa8a40f815b83de372e345eb22cc3d50a4bb1869db78e Quasar f75861216f5716b0227733e6a093776f693361626efebe37618935b9c6e1bdfd Quasar 51b0bb172c6e5eaa8e333fbf2451ae27094991b6330025374b9082ae8cd879cf Quasar 46ae101a8dc8bf434d2c599aaabfb72a0843d21e2150a6c745c0c4a771c09da3 Quasar 488db27f3d619b3067d95515a356997ea8e840c65daa2799bdd473dce93362f2 Quasar 5a05d2171e6aeb5edd9d39c7f46cd3bf0e2ee3ee803431a58a9945a56ce935f6 Quasar 6f4e20e421451c3d8490067f8424d7efbcc5edeb82f80bb5562c76d4adfb0181 Quasar 9a81cffe79057d8d307910143efd1455f956f2de2c7cc8fb07a7c17000913d59 Quasar c84afdd28fa0923a09f6dd3af1e3821cdb07862b2796fa004cd3229bc6129cbe Quasar 6cf63ae829984a47aca93f8a1261afe5a06930f04fab6f86f6f7f9631fde59ec Quasar aa982fe7d28bbf55865047b16334efbe3fcb6bae06e5ed9cab544f1c8d307317 Quasar 2963c5eacaad13ace807edd634a4a5896cb5536f961f43afcf8c1f25c08a5eef VERMIN 677edb1a0a86c8bd0df150f2d9c5c3bc1d20d255b6f7944c4adcff3c45df4851 VERMIN 74ba162eef84bf13d1d79cb26192a4692c09fed57f321230ddb7668a88e3935d VERMIN e1d917769267302d58a2fd00bc49d4aee5a472227a75f9366b46ce243e9cbef7 VERMIN eb48a31f8f81635d24f343a09247284149884bd713d3bc1c0b9c936bca8bafd7 VERMIN 15c52b01d2b9294e2dd4d9711cde99e10f11cd188e0d1e4fa9db78f9805626c3 VERMIN 31a1419d9121f55859ecf2d01f07da38bd37bb11d0ed9544a35d5d69472c358e VERMIN 5586fb423aff39a02cddf5e456a83a8301afe9ed78ecbc8de2cd852bc0cd498f VERMIN 5ee12dd028f5f8c2c0eb76f28c2ce273423998b36f3fc20c9e291f39825601f9 VERMIN eb48a31f8f81635d24f343a09247284149884bd713d3bc1c0b9c936bca8bafd7 VERMIN 98073a58101dda103ea03bbd4b3554491d227f52ec01c245c3782e63c0fdbc07 VERMIN c5647603337a4e9bfbb2259c0aec7fa9868c87ded2ab74e9d233bdb2a3bb163e VERMIN eb46b8978619a72f4b0d3ea8961dde527f8e27e89701ccd6e5643c33b103d901 VERMIN abd05a20b8aa21d58ee01a02ae804a0546fbf6811d71559423b6b5afdfbe7e64 VERMIN Appendix **Appendix C – Python script to decode VERMIN resources** 1 2 3 4 5 #!/usr/local/bin/python __author__ = "Juan C Cortes" __version__ = "1.0" __email__ = "jcortes@paloaltonetworks.com" from random import randint ----- 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 p import binascii import sys import logging import hashlib import argparse import os import struct from tabulate import tabulate from Crypto import Random from Crypto.Cipher import AES def parse_arguments(): """Argument Parser""" parser = argparse.ArgumentParser( usage="Decrypt strings for VerminRAT") parser.add_argument( "-v", "--verbosity", action="store_true", dest="vverbose", help="Print debugging information") parser.add_argument( "-o", "--output", dest="output_file", type=str, help="Output results file") parser.add_argument( "input", type=str, action='store', help="Input file of newline separated strings or single string") parser.add_argument( "-b", "--blob", action='store_true', help="Param use for decrypting blobs of data instead of strings. Blob is autosave to 'blob.out'") return parser def write_out(output_list, headers, output_file=False): """ Pretty outputs list :param output_list: List to output """ print tabulate(output_list, headers, tablefmt="simple") print "" if output_file: with open(output_file, "ab") as file: file.write(tabulate(output_list, headers, tablefmt="simple")) file.write("\n\n") def generateArray(): abyte = bytearray(6) for i in range(0,6): abyte[i] = randint(0, 0x7FFFFFFF) % 7 return abyte; def parseEncrypteStr(encryptStr): try: decoded = encryptStr.decode('base64') hardcoded_crc32 = decoded[-4:] parsedEncrypted = decoded[16:-4] iv = decoded[:16] return hardcoded_crc32,parsedEncrypted,iv except Exception as e: print e def bruteForceCRC32Value(valuecrc32): while (True): arry = generateArray() crc32 = binascii.crc32(arry) crc32 = crc32 % (1 << 32) if crc32 == valuecrc32: return(arry) def decryptStr(str,key,iv): aes = AES.new(key, AES.MODE_CBC, iv) blob = aes.decrypt(str) return blob def parsePlainText(str): char = "" for i in str: if 0x20 <= ord(i) <= 0x127: ----- 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 else: continue return char def parseUnicde(str): try: uni = "" for i in range(0,len(str)/2): uni += str[i] return uni.decode('utf16') except Exception as e: print e def main(): """Main Method""" args = parse_arguments().parse_args() strs = [] if args.vverbose: logging.basicConfig( level=logging.DEBUG, format=' %(asctime)s - %(levelname)s - %(message)s') if args.blob and os.path.exists(args.input) != True: b = args.input crc32Hardcode, encryptedStr, iv = parseEncrypteStr(b) crc32Hardcode = bytearray(crc32Hardcode) crc32Hardcode = struct.unpack('