Recent Webinar: Building an Adaptive Cyber Resilient Cloud
arrow-white arrow-white Watch now
close

Not All Fun and Games: Lua Malware Targets Educational Sector and Student Gaming Engines

Posted by Shmuel Uzan on October 8, 2024

Recently, Morphisec Threat Labs identified and prevented multiple sophisticated Lua malware variants targeting the educational sector. These attacks capitalize on the popularity of Lua gaming engine supplements within the student gamer community. 

Lua Malware -blog_1200x628_v.2.1

Introduction 

In March 2024, OALabs reported on a new packed Lua loader aimed at the gaming community. This report was followed in April by additional threat insights by McAfee. In the months since, Morphisec Threat Labs observed its continued spread and evolution, with telemetry data indicating that this malware strain is highly prevalent across North America, South America, Europe, Asia, and even Australia. This post provides an analysis of the loader associated with this persistent attack. 

Over the past year, the delivery of Lua malware appears to have undergone simplification, possibly to reduce exposure to detection mechanisms. The malware is frequently delivered using obfuscated Lua scripts instead of compiled Lua bytecode, as the latter can trigger suspicion more easily. 

We would like to credit @Herrcore for their assistance in some of the deobfuscation efforts.

 

Technical Introduction

Lua Malware Diagram 2

We have observed that users searching for game cheats often end up downloading files from platforms like GitHub or similar sources. Today, Lua malware is typically delivered in the form of an installer or a ZIP archive. The ZIP archive usually contains four components: a Lua compiler, a Lua DLL file, an obfuscated Lua script, and a batch file. The batch file executes the Lua script by passing arguments to the Lua compiler. 

  • Lua51.dll - LuaJIT Runtime interpreter 
  • Compiler.exe - a thin compiled Lua loader 
  • Lua script – Malicious Lua script 
  • Launcher.bat - Batch script used to run Compiler.exe with the malicious script as parameter 

Post execution of the batch file, the loader establishes communication with a C2 server, sending details about the infected machine. In response, the server provides tasks divided into two categories: Lua loader tasks, which involve actions such as maintaining persistence or hiding processes, and task payloads, which focus on downloading new payloads and applying configurations to them. 

We will get into more details throughout this post. 

 

Delivery Techniques 

The delivery techniques, such as SEO poisoning, remain largely unchanged from those previously described by OALabs and McAfee. Notably, we identified an advertisement for the Solara and Electron executors - popular cheating script engines frequently associated with Roblox—leading to various Lua malware variants hosted across multiple GitHub repositories. 

Solara Google Search

Solara Web Page

Most of the download links are associated with github.com/user-attachments push requests. 

Github link on Solara web page

Solara folder in Windows ExplorerElectron google search

Electron web pageHTML from electron

Compiler.exe and lua51.dll 

The lua51.dll is a widely recognized runtime interpreter for Lua, often employed as an “SDK” to extend the functionality of existing software through an accessible and flexible scripting engine.  

The Compiler.exe acts as a lightweight loader, responsible for loading lua51.dll and invoking its SDK exported functions to process the specified script. In earlier campaigns, Compiler.exe was designed to load and execute Lua bytecode using lua51.dll. However, in the more recent campaigns, it loads a plain Lua script file instead, leveraging Lua's runtime capabilities to interpret the obfuscated script dynamically, allowing for greater flexibility in executing malicious logic. 

CFF Explorer Screenshot

 

Lua Script (config) 

As previously identified by OALabs, the script is obfuscated using the Prometheus obfuscator. In their analysis, they needed to decompile the bytecode; however, in the recent campaigns described here, the parameter is no longer a bytecode file but rather a directly obfuscated script file. 

Prometheus Obfuscator is a tool designed to enhance software security by employing advanced obfuscation techniques. Its primary purpose is to protect applications from reverse engineering and unauthorized access, making it significantly more difficult for researchers to analyze and understand the code. With capabilities such as code transformation and control flow obfuscation, Prometheus ensures that the underlying logic remains concealed from scrutiny. 

 

The content of the Lua obfuscated script is seen below: 

Lua script

A simple beautification of the script will result in (similar string structure is identified at the bytecode file samples):  

Lua scriptimage012

Post deobfuscation, we can easily dump the strings from memory: 

Lua memory strings

 

Anti-reversing 

The obfuscated code is initially written in a single line, and when using formatting tools to reorganize the code structure for readability, an error message “Tamper Detected!” appears during code execution. 

Anti-reversing techniques

The obfuscator's method involves line detection, where it deliberately triggers an error at least twice from different locations. It then verifies whether the line numbers are the same for both areas of the code. 

An example that demonstrates the technique: 

 

  1. The attacker defines a function that deliberately throws an error (division by zero).Code snippet
  2. The function throws an error and parses the line of the error to know from which line in the code it occurred. The pcall function makes a call to another function and returns an array. The first element indicates success, and the second element contains the error message if it failed. In this case, the error format in Lua is structured as `filename:line_number:message`.Code snippet
  3. An additional inline function is generated to ensure that the error is thrown from a different location in the code. Upon execution the function checks whether the line number in the error message matches the previous line number to determine if the code has been edited. 

Prometheus obfuscator implementation for this anti-reformatting / anti-beautify functionality is well described here.

Anti-Beautify in Lua

The attacker utilizes the `ffi` library for the direct execution of C code.

image018-1

What is FFI? 

The FFI library allows Lua code to call C functions and use C data structures directly without needing to write C wrapper code. This is particularly useful for integrating Lua with C libraries or for improving the performance of certain operations by leveraging native C functions. 

 

Import Modules and Functions 

The script imports the modules by traversing the PEB (Process Environment Block), and then uses the module's EXPORT table: 

Module 

Functions 

shell32.dll 

SHGetFolderPathW , SHCreateDirectoryExW , PathFileExistsW 

advapi32.dll 

RegCreateKeyExW , RegSetValueExW , RegCloseKey , RegGetValueW , RegCreateKeyExW , 

RegSetValueExW , RegCloseKey , RegGetValueW , RegGetValueW , RegQueryValueExW , 

OpenProcessToken , GetTokenInformation , CryptAcquireContextW , CryptGenRandom , 

CryptReleaseContext , GetUserNameW 

shlwapi.dll 

PathFileExistsW 

winbrand.dll 

BrandingFormatString 

kernel32.dll 

WinExec , CreateMutexW , SetFileAttributesW , GetModuleFileNameW , CopyFileW 

wininet.dll 

InternetOpenW , InternetConnectW , HttpOpenRequestW , InternetOpenUrlW , 

HttpSendRequestW , InternetReadFile , InternetCloseHandle 

 

Mutex-based 

The script uses a mutex using a long constant string  

In some cases, this string includes a concatenated, predefined number. 

Code snippet

Persistence 

The script establishes persistence by generating a random task name from a predefined list using the following command:  

`schtasks /create /sc daily /st %02d:%02d /f <Name> /tn <App> /tr <Path>`

Code snippet

Potential task name list: 

Potential task name last

Information gathering 

In the first stage, the script sets the same name for the `UserAgent` as the one defined for the `mutex`, then initiates a GET request to `http://ip-api[.]com/json/` to retrieve information about the victim. During this process, the script validates network connection by attempting to communicate with `https://www.microsoft.com`. 

Headers requestCode snippet

Then the script retrieves the `MachineGuid` from the attacker's machine (located at `Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography`). This string is concatinated along with the `loaderId`, `GUID`, `computer name`, `user name`, `IP`, `country`, `city`, `timezone`, `operating system`, and `architecture`.

Code snippet

Afterward, the script encodes the string using a simple symmetric encryption method that combines a basic form of a stream cipher or XOR cipher with byte addition. After encryption, the script converts the bytes to Base64 format. 

image025-1

Finally, the script captures a screenshot of the compromised computer and sends the adversary C2, the collected data from the computer along with screenshots. 

 

C2 communication  

After the data is sent to the attacker's server, the server can respond in one of two ways: 

  1. Blocked – indicating the request is denied.
  2. JSON Response – commands of the following categories; `loader` and `tasks`.
    • Loader - These are actions for the "lua loader" to execute, such as hiding, restarting, maintaining persistence, etc.
    • Tasks - These are meant to load additional payloads and define which configurations should be applied when loading them.

If the server returns a "blocked" response, the malware attempts to connect to an alternate predefined address. If that is also blocked, it accesses pastebin[.]com/raw/mmABULhh to retrieve a new address. If all attempts fail, the process terminates. 

If a valid response is received, the `lua loader` saves the output in the `C:\Users\<User>\Pictures\` folder, using the machine’s `GUID` as the filename. 
After saving the file, the loader executes the required tasks and then sends a response back to the server with the task ID (that was initially provided. 
The payloads are CypherIT Loader / Crypter , Redline). 

Code snippet

 

Loader Config 

Command 

Description 

bypass_defender 

`powershell "Start-Process <#rand name> powershell <#rand name> -Verb <#rand name> runAs" -WindowStyle hidden -Argument 'Add-MpPreference -ExclusionPath $env:SystemDrive -ExclusionExtension .exe, .dll -Force` 

autorun 

Create task 

`schtasks /create /sc daily /st <time> /f /tn <generated name> /tr "<compiler file> <script file>"` 

relaunch 

implements a delay using a loop (`Sleep (1000);`) 

tablet 

pop up message with `MessageBoxW` 

hide 

Set `SetFileAttributesW` to flag `FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM` to files 

persistence 

The script copies itself files to the directory `C:\Users\john\AppData\Local\<folder>\` and creates a scheduled task using the following command: 

`schtasks /create /sc daily /st <time> /f /tn <generated name> /tr "<compiler file> <script file>"` 

  

If the current process has elevated privileges, additional steps are taken to bypass Windows Defender. 

`powershell -WindowStyle hidden Add-MpPreference -ExclusionPath <path> -Force` 

 

Task Config 

Command 

Description 

id 

Task number 

link 

Link to download additional payloads 

file_path 

which folder to write (`AppData,Desktop ..`) 

file_name 

File location to be written 

start 

Whether to run the file or not 

`exe` - create task and run `powershell -Command \"Register-ScheduledTask -TaskName 'task' -Action (New-ScheduledTaskAction -Execute '<task>') -Trigger (New-ScheduledTaskTrigger -At (Get-Date).AddMinutes(1) -Once) -Settings (New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable) -Force\""` 

or using `WinExec` 

  

`DLL` - using `loadlibrary` and export function in `cfg` (run time)  

or  run command `rundll32 <dll>, <export>` 

  

`ps1` - `powershell -WindowStyle Hidden -ExecutionPolicy Bypass -File <file>` 

`cmd` or `bat` - `cmd /c <file>` 

autorun 

execute the file with task 

hide 

Set `SetFileAttributesW` to flag `FILE_ATTRIBUTE_HIDDEN` to files 

pump 

increase the size of file 

dll_loader 

using for loading DLL file and specific export 

query 

If there is a query for the link 

 

Python code snippet for decoding the strings:

Lua python code snippet

Conclusion 

Based on our investigation, the malware ultimately leads to the deployment of Infostealers, notably Redline Infostealers. Infostealers are gaining prominence in the landscape as the harvested credentials from these attacks are sold to more sophisticated groups to be used in later stages of the attack. Redline notably has a huge market in Dark web selling these harvested credentials. 

 

How Morphisec Helps 

Automated Moving Target Defense (AMTD) from Morphisec effectively stops malware attacks at various stages of the attack chain. Morphisec doesn’t rely on signature or behavioral patterns. Instead, it uses its patented AMTD technology to prevent the attack at its earliest stages, preemptively blocking attacks on memory and applications, and effectively remediating the need for response. 

Schedule a demo today to see how Morphisec stops Lua malware and other new and emerging threats. 

Get a Demo of Morphisec

 

IOCs 

77.73.129[.]64 

C2 Lua loader 

185.221.198[.]82 

C2 lua loader 

146.19.128[.]146 

C2 Lua loader 

212.193.4[.]66 

C2 Lua loader 

185.236.228[.]12 

RedLine 

185.208.158[.]36 

RedLine 

Solaraexec[.]cc 

Fake website 

electronexec[.]com 

Fake website 

github[.]com/user-attachments/files/16201677/getter.json 

Task Payload  

 

github[.]com/user-attachments/files/16968308/socket.json 

Task Payload 

github[.]com/user-attachments/files/17057089/SolaraV3.zip 

Lua Loader 

github[.]com/user-attachments/files/16737781/Electron.zip 

Lua Loader 

 

`schtasks /create /sc daily /st <time> /f /tn <generated name> /tr "<compiler file> <script file>"` 
 
 
`powershell -Command \"Register-ScheduledTask -TaskName 'task' -Action (New-ScheduledTaskAction -Execute '<task>') -Trigger (New-ScheduledTaskTrigger -At (Get-Date).AddMinutes(1) -Once) -Settings (New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable) -Force\""` 

 
 

Persistent 

pastebin[.]com/raw/mmABULhh 

C2 lua loader 

`1crorgz4bo93e47pxiiyklanj0mfswyjtxeg56nahc5sm58` 

Mutex 

Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography 

Registry  

 

Hashes

B3ecbe4132598ef746e2111ba29f46af06886677d18595b6845849577121707a 

CypherIT 

3B515469ABA46A0A08D8FCBD8FEB98CE9BCEBFA1A48D56BE586DC9AA4584C0C2 

CypherIT 

308721F4DC7818AED5F0282A3EFA5944C1D16E97B0CB3BB5786009A186EA9791 

CyperIT 

B3ECBE4132598EF746E2111BA29F46AF06886677D18595B6845849577121707A 

CyperIT 

98418f7079cc11970899a18098425d22414663301dbbad1c892a8c702b90223f 

Lua Loader 

9aacf8f59b8daff24161549378c95174dac40b2fb01d7b8a78b513d3d35f6411 

Lua Loader 

Afd731bb658525845c8ee4216b05ce0c9c8b2e8b745884fbefeb01ef331163a1 

Lua Loade 

8e59a9de633fc1e0a9da10268c606b898e7d5a6645ee21851465e027aefbaec9 

Lua Loade 

AECDAA94885C3FCD856C3516311BF366AC5EE13B43C28560EADC1F637EFCF432 

Lua Loade 

E09370c9adc09c15eb8d05301bd3c74ef76e98b8a2fa2089df9c4ec5d7b4e047 

Redline 

 

Resources