New Malware Gameloader in Discord Malspam Campaign Identified by GoSecure Titan LabsThe expert investigators at GoSecure Titan Labs have found, analyzed and created signatures to detect a new malware that they call Gameloader – since it and its variants contain numerous strings that attempt to disguise themselves as video games. The file Titan Labs used for their research was a Rich Text Format (RTF) file entitled New Purchase Order from Alibaba.doc provided by the GoSecure Titan Inbox Detection and Response (IDR) team. The RTF file downloads a 32-bit .NET loader, which loads FormBook Stealer. The following is an in-depth analysis of the Gameloader.



Infection Chain

The initial infection vector is via malspam containing links to Using Discord’s content delivery network (CDN) as a malware distribution system continues to grow in popularity among threat actors. The email (51875bd4157c2755a6af3ce92218ea03), shown in Figure 1, purports to be from Alibaba, stating that the user’s purchasing order has been received and that they can download it by clicking the link labelled DOWNLOAD PURCHASE ORDER, which downloads a malicious RTF file (dd59a0508d8c8327a0a326a8e50bc508) from hxxps://cdn[.]discordapp[.]com/attachments/ 882541551555846144/882541673186484224/New_Purchase_Order.doc.

Figure 1: Malspam


Figure 2 compares a standard RTF file, shown on the left, to New_Purchase_Order.doc, shown on the right. A standard RTF file consists of RTF control words whereas New_Purchase_Order.doc clearly does not, indicating that it is heavily obfuscated.

Figure 2: Standard RTF vs. Obfuscated RTF


As depicted in Figure 3, the tool displays the streams contained in New_Purchase_Order.doc, their nesting level, and also the amount of hexadecimal characters in each one. We can see that streams 1, 2, and 3 have a high number of hexadecimal characters, which warrants a closer examination.

Figure 3: rtfdump Output


As displayed in Figure 4, by using the s flag to investigate specific streams and the H flag to decode the hexadecimal characters, we find that stream 3 contains the string equATION.3, which invokes Equation Editor. By exploiting CVE-2017-11882, a buffer overflow vulnerability in Microsoft Equation Editor, the RTF file downloads GameLoader (e3488000bfab3d82a4fd31206ba01954) from hxxp://lg-tv[.]tk/bankzx.exe. Note that we also used’s S flag to shift the hexadecimal bytes by one nibble. Due to the implementation of the RTF parser, it is possible to make the parser ignore a nibble of a byte, which has the effect of shifting the starting point of hex-encoded data by one nibble, which is exactly what the threat actor did in this case to further obfuscate the file.

Figure 4: Stream 3, hex-decoded



Figure 5 depicts the functionality of GameLoader’s first stage. Line 105 begins with a call to function fDangNhap.X0203, which decrypts the second-stage loader. fDangNhap.X0203 receives two parameters, Desc.String1, which is a string in GameLoader’s resource section that contains the encrypted second-stage loader, and the string Z7FE68C5, which is the decryption key. We can see that function fDangNhap.X0203’s implementation, beginning at line 136, iterates through both the encrypted string and the decryption key, subtracting the integer value of the current character in the key from the integer value of the current character in the encrypted string. It then converts the resulting value back to a character and appends it to a string. The resulting string is a base64-encoded, 32-bit .NET DLL, which gets passed to Convert.FromBase64String, back on line 105. The decoded DLL (36fa916ea33da29b017dc9b363834024), GameLoader’s second stage loader, is then passed to the function this.X0204, the implementation of which begins at line 129. It uses Assembly.Load to reflectively load the DLL into the application domain of GameLoader. It then gets the Type object Meshomatic.Ms3dLoader from the newly loaded assembly and stores it in this.Linear. The function this.X0202 is then called on line 106. As shown in its implementation, on line 152, this.X0202 calls the Activator.CreateInstance method to create an instance of Meshomatic.Ms3dLoader, essentially executing the second-stage loader. Activator.CreateInstance accepts two parameters: the object type to instantiate and an array of arguments to be passed to the instantiated object. In the bottom of Figure 5, where local variables are shown, we can see that the array contains 3 strings: 4950726F6475636572436F6E73756D6572436F6C6C65637469, 6A7067, and Tetris.

Figure 5: GameLoader’s First Stage Loader


Following the execution of the instantiated object, we can step inside the second-stage DLL, internally named ColladaLoader, and see that the first method executed in Meshomatic.Ms3dLoader is Ms3dLoader.SelectorX, which is passed the 3 aforementioned arguments. Figure 6 illustrates that besides sleeping for a random amount of time, Ms3dLoader.SelectorX calls Ms3dLoader.XeH on line 48. Ms3dLoader.XeH simply converts the hexadecimal string stored in ugz1 to the ascii string IProducerConsumerCollecti. This string, along with the variable projname, which stores the string Tetris, is then passed to

Figure 6: ColladaLoader’s Injection Function


As shown in Figure 7, retrieves the bitmap image IProducerConsumerCollecti from Tetris.Properties.Resources.

Figure 7:


The bitmap image, depicted in Figure 8, does not display an image of any kind, only seemingly randomized pixels.

Figure 8: Bitmap Image Containing An Encrypted DLL


Back on line 48, in Figure 6, the bitmap image gets stored in a variable that is passed to on line 49. iterates through the bitmap image, converting the Argb value of each pixel into bytes and storing them in an array. It then creates a second array, using the first 4 bytes of the first array as the size of the second. Starting from the fifth byte, it copies the bytes in the first array to the second array until the second array is fully populated. This byte array is then passed to Ms3dLoader.fgh, which is responsible for decrypting the array. The return value from Ms3dLoader.XeH, which is the string jpg, is also passed to Ms3dLoader.fgh. Once inside Ms3dLoader.fgh, shown in Figure 9, the string jpg is converted to a byte array, stored in the variable bytes, and used as the decryption key. The array is decrypted by XORing each of its bytes with a key byte, and also with the value stored in the variable num, which is 0x9d. This value was created by XORing the length of the encrypted array minus one with 112. The decrypted array is GameLoader’s third-stage loader, a 32-bit .NET assembly internally named CF_Secretaria (d8e57e7bf8dfe611427511dcc5ae2ec8). Once again, Assembly.Load is used to reflectively load the DLL. Next, ColladaLoader calls Assembly.GetTypes, which returns an array of all the types defined in the loaded assembly, and stores the twenty-first type in a variable. It then uses Type.GetMethods to return an array of the all methods defined for the specified type, and stores the sixth method in a variable, which it then executes with a call to MethodInfo.Invoke.

Figure 9: ColladaLoader’s Decryption Function


Again, we follow the execution to step inside the invoked method. However, CF_Secretaria is protected with .NET Reactor, a code obfuscation tool designed to protect intellectual property, which greatly hinders analysis. To overcome this, we save CF_Secretaria to disk, then use the .NET deobfuscator de4dot to improve the readability of the code. The executed method belongs to a class named FrmIntegrante. Figure 10 displays the method responsible for initializing the class’s fields. The method Class6.smethod_0 retrieves the byte array zdljr from CF_Secretaria’s resource section. The byte array is passed, along with the string YgSqwuwwJHlcE, to Class6.smethod_5, which is a decryption function that is exactly the same as ColladaLoader’s decryption function, shown above in Figure 9. Of course, the string YgSqwuwwJHlcE is the decryption key. The decrypted array is then passed to Class6.smethod_4, which removes the first 16 bytes, before being stored in FrmIntegrante.byte_0. The resulting array is a 32-bit executable, FormBook Stealer (4c1f6f8f4bf9678c49d6ea74baca3576).

Figure 10: FrmIntegrante’s Initialization


Also depicted in Figure 10 are a set of Windows API functions and their corresponding libraries that are commonly used for process hollowing, a technique where a payload is injected and executed in the context of a selected process. Each API function is passed to FrmIntegrante.smethod_7, which is stored in FrmIntegrante.delegate{number}_0. From Figure 11, which displays FrmIntegrante.smethod_7’s implementation, we see that the first parameter, a library name, is passed to FrmIntegrante.LoadLibraryA, a pointer to the imported function kernel32.LoadLibraryA, which returns a handle to the specified library. The handle is passed, along with a function name stored in FrmIntegrante.smethod_7’s second parameter, to FrmIntegrante.GetProcAddress, a pointer to kernel32.GetProcAddress, which returns the address of the specified function. This is then converted to a delegate and returned. Therefore, FrmIntegrante.delegate{number}_0 is a reference to a specified Windows API function.

Figure 11: API Delegate-Building Function


CF_Secretaria implements a switch statement, displayed in Figure 12, to determine into which process to inject its payload, which is FormBook in this instance. Case zero returns string_10, which is the path of the currently executing assembly, GameLoader, while cases 1, 2, and 3 return the paths of MSBuild.exe, vbc.exe, and RegSvcs.exe, respectively. In this instance, case 0 is selected and GameLoader proceeds to inject the payload into its own process. The case that is selected is determined by the parameter int_12, which is set by the threat actor in CF_Secretaria’s configuration.

Figure 12: Process Injection Options


Figures 13 and 14 display the function responsible for the process injection. For readability, we have added the API call that each delegate refers to. The function begins by calling kernel32.CreateProcessA. The first parameter, which specifies the process to create, is string_10, the result from the aforementioned switch statement. The sixth parameter, containing 134217732U, specifies flags used to set the properties of the created process. 134217732U (0x08000004) sets the flags CREATE_SUSPENDED and CREATE_NO_WINDOW to true. Thus, the process will be created in suspended mode and will be executed without a console window. Next, either kernel32.GetThreadContext or kernel32.Wow64GetThreadContext will be called, depending on whether the process is 32-bit or 64-bit, and a CONTEXT structure of the process’s main thread will be retrieved. The base address of the process is parsed out of the CONTEXT structure and passed to kernel32.ReadProcessMemory, which is used to retrieve the base virtual address of the process’s view. The base virtual address is then passed to ntdll.ZwUnmapViewOfSection, which unmaps, or hollows, the entire view from the process’s virtual address space. The virtual address space is no longer reserved and is now available to map other views. Next, it allocates space within the process’s virtual address space by calling kernel32.VirtualAllocEx, then calls kernel32.WriteProcessMemory to inject the payload into the newly allocated memory. Either kernel32.SetThreadContext or kernel32.Wow64SetThreadContext is called to change the process’s thread context so that it will now point to the injected payload. Finally, kernel32.ResumeThread is called to resume the thread and thus, execute the injected payload.

Figure 13: Process Injection Function

Figure 14: Process Injection Function Continued



GameLoader is a multi-stage, steganographic loader that has been observed loading various types of commodity malware, including AgentTesla, LokiBot, and Snake Keylogger. At the time of writing, over 1000 GameLoader samples have been uploaded to VirusTotal.

The signatures to detect the emerging threats discussed in this report were developed through the close monitoring, analysis and reverse engineering conducted by GoSecure Titan Labs, as part of the GoSecure Titan Managed Detection and Response (MDR) solution, which includes GoSecure Titan Inbox Detection and Response (IDR) tools for users to share suspicious emails in real-time with our professional threat hunting team.

Malware Analyst: Sean Mahoney


Indicators of Compromise

| Type |                                                Indicator                                                |        Description        |
| md5  | 51875bd4157c2755a6af3ce92218ea03                                                                        | Malspam Email             |
| md5  | dd59a0508d8c8327a0a326a8e50bc508                                                                        | RTF File                  |
| md5  | e3488000bfab3d82a4fd31206ba01954                                                                        | GameLoader                |
| md5  | 36fa916ea33da29b017dc9b363834024                                                                        | GameLoader's Second Stage |
| md5  | d8e57e7bf8dfe611427511dcc5ae2ec8                                                                        | GameLoader's Third Stage  |
| url  | hxxps://cdn[.]discordapp[.]com/attachments/882541551555846144/882541673186484224/New_Purchase_Order.doc | GameLoader Download URL   |
| url  | hxxp://lg-tv[.]tk/bankzx.exe                                                                            | RTF File Download URL     |



rule other_rtf_obfuscated_0 {
        author      = "Titan Labs"
        company     = "GoSecure"
        description = "Obfuscated RTF File"
        created     = "2021-09-28"
        hash        = "dd59a0508d8c8327a0a326a8e50bc508"
        os          = "windows"
        type        = "other"
        tlp         = "white"
        id          = 1
        $magic   = "{\\rtf" 
        $ansi    = "ansi"
        $deflang = "deflang"
        $windows = "windows"
        $deff    = "deff"
        $magic at 0 and
        filesize < 1MB and
        not $ansi in (5..20) and 
        not $deflang in (5..20) and
        not $windows in (5..20) and
        not $deff in (5..20)
rule malware_game_loader_0 {
        author      = "Titan Labs"
        company     = "GoSecure"
        description = "GameLoader"
        hash        = "e3488000bfab3d82a4fd31206ba01954"
        created     = "2021-09-28"
        os          = "windows"
        type        = "malware.loader"
        tlp         = "white"
        rev         = 1
        $decryptyion_routine = {
            00 02 07 28 ?? ?? ?? ?? 28 ?? ?? ?? ?? 03 07 03
            6F ?? ?? ?? ?? 5D 17 58 28 ?? ?? ?? ?? 28 ?? ??
            ?? ?? 59 0C 06 08 28 ?? ?? ?? ?? 0D 12 ?? 28 ??
            ?? ?? ?? 28 ?? ?? ?? ?? 0A 00 07 17 58 0B 07 02
            6F ?? ?? ?? ?? FE 02 16 FE 01 13 ?? 11 ?? 2D ??
        uint16(0) == 0x5a4d and
        uint32(uint32(0x3c)) == 0x00004550 and

Détection et réponse gérées Titan
Antivirus de nouvelle génération
Détection et réponse sur les terminaux
Détection et réponse sur le réseau
Détection et réponse sur les boîtes de messagerie
Détection et réponse face aux menaces internes
Gestion des pare-feu
Gestion des SIEM
La gestion des vulnérabilités en tant que service
GoSecure Titan
Logiciel Titan
Sécurité de la messagerie
Sécurité Web
Boîte à outils «Responder PRO Forensics»
Services professionnels
Services de préparation aux brèches
Évaluation de la cybersécurité
Services de réponse aux incidents
Services des équipes « Red & Purple »
Services de tests d'intrusion
Services de conformité et d'audit
Évaluation de la compromission de la sécurité
Technologies tierces

Pin It on Pinterest

Share This