Steam Malware Analysis: UnityPlayer.dll DLL Side-Loading in Beyond The Dark

Steam Malware Analysis: UnityPlayer.dll DLL Side-Loading in Beyond The Dark

This post is also available in Korean

Steam, the well-known game distribution platform, offers not only paid titles but also free-to-play games. If an attacker can evade Steam’s security checks and upload a malicious file disguised as a free game, the platform could become an effective attack vector capable of infecting a large number of gamers. Such bold attempts have in fact been made repeatedly, and news occasionally surfaces that malicious files were found in games listed in the Steam library.

This article analyzes a malicious file included in Beyond The Dark, a game that was recently uploaded as a free title. At the time of writing, the Steam store page for the game still exists, but Steam appears to have already recognized the malicious activity and disabled downloads.

Beyond The Dark Steam page

1. File Info

The following is information about the malicious files included in Beyond The Dark. These files must never be executed on a host environment.

UnityPlayer.dll

  • MD5 : 4A7B088EC76C2513432901BC9616D675
  • SHA256 : B37CEA499EFAD35FF5AF7E73F34F17840C2D14DD6CD21E3345D22A39140B4D45
  • FileSize : 7,819,776 bytes
  • FileType : DLL64(.NET)
  • 통신 서버 : hxxps[:]//435123332155.com/api.php

WindowsCodecs.dll

  • MD5 : DD6F25C9E750D96E26F4717F63A416F6
  • SHA256 : FC4317EBABFBCA8A9DBD307F16EEEE553E659FB9F931BFF4D858871D6215540B
  • FileSize : 13,268,480 bytes
  • FileType : DLL64

RunPE.dll

  • MD5 : 0C42EC5B8C0C53DC170B944754D38E5C
  • SHA256 : 57BE85F23890FC8D2E3AC6B6123FB1D5B79777F7630C9550A18CB6C14A66288C
  • FileSize : 54,272 bytes
  • FileType : DLL64
  • 비고 : Fileless.

mirar.exe

  • MD5 : ACBBD4AF7F93FEDD4DB990EAEC94CD1F
  • SHA256 : 131B2C66BC614EDE57D0645C4CB2D407EB4F2EDBB394C1FB28A5E0BAEB97629D
  • FileSize : 11,545,600 bytes
  • FileType : EXE64(.NET Reactor)
  • C2 server : 435123332155.com
  • Note: Injected into the legitimate RegAsm.exe. Fileless.

2. Malicious Behavior Analysis

2.1 Beyond The Dark.exe

The attack begins when the user executes Beyond The Dark.exe. When this executable is launched, it crashes, making it impossible to play the game normally. However, the executable has a DLL dependency that causes it to load UnityPlayer.dll.

The attacker placed a malicious DLL named UnityPlayer.dll in the same directory as the executable, disguising it as a Unity game engine file and inducing DLL side-loading.

Beyond The Dark.exe loading the malicious UnityPlayer.dll

2.2 UnityPlayer.dll

The loaded UnityPlayer.dll is a 64-bit DLL built with .NET. Analysis with dnSpy showed that, when executed, the DLL collects the host name and MAC address, then uses both values to generate a client ID.

System information collection code

It also searches the installation paths of major browsers such as Chromium, Firefox, and Opera, and collects the list of installed extensions.

Browser extension information collection code
Browser extension storage path code

After performing basic information collection, the malware starts communicating with the attacker-controlled server. The packet actions exchanged with the server are as follows:

Action Function
register Sends the host name and MAC address to register the client
client_message Sends browser extension information
heartbeat Indicates that the client and server are alive
ack Responds to server packets

Communication requires a specific X-API-Key header value.

POST packet generation code

During the initial communication, the malware sends a register packet containing the host name and MAC address to register the client.

Client registration code

After registration, it sends the previously collected browser extension information to the attacker-controlled server.

Client information transmission code

When a message with the channel value set to 1 is received from the attacker-controlled server, the malware downloads a ZIP file.

ZIP download code

After extracting the downloaded ZIP file, it executes the first EXE file it finds.

Code that extracts the ZIP file and executes the EXE

Further malicious behavior would require analysis of the downloaded EXE file. However, the server was already down at the time of analysis, making communication impossible. It is likely that the core malicious functionality resides in the downloaded EXE file.

2.3 WindowsCodecs.dll

Among the Any.run analysis reports, there was one report showing successful communication with the attacker-controlled server. Based on this report, the analysis was continued. The Beyond The Dark.exe sample that successfully communicated with the server downloaded pdate_20260518_024820.zip, extracted it, dropped WinRAR.exe (53cf9bacc49c034e9e947d75ffab9224) and WindowsCodecs.dll (dd6f25c9e750d96e26f4717f63a416f6), and then executed WinRAR.exe.

Any.run analysis details

WinRAR.exe itself is a legitimate file. However, WindowsCodecs.dll, which is side-loaded by this executable, is malicious.

WindowsCodecs.dll loaded through DLL side-loading

The malicious WindowsCodecs.dll decrypts encrypted data embedded in the file, loads the RunPE DLL into memory, and executes one of its exported functions, GetGet.

GetGet export function of the RunPE DLL

2.4 RunPE DLL

The RunPE DLL launches the legitimate system executable RegAsm.exe in a suspended state, injects malicious code into it, and then resumes the process. During this process, it invokes APIs commonly used in process hollowing, such as NtUnmapViewOfSection, NtAllocateVirtualMemory, NtWriteVirtualMemory, NtGetContextThread, NtSetContextThread, NtResumeThread, NtDelayExecution, and NtClose, by using direct system calls. This technique helps evade detection by analysts and sandboxes.

Direct system call code

After injecting the payload PE file into RegAsm.exe, the malware resumes the thread and begins executing its malicious behavior.

2.5 mirar.exe

The malware injected into RegAsm.exe was a file named mirar.exe. It was obfuscated with the .NET Reactor protector, so the obfuscated code was unpacked using NETReactorSlayer before analysis.

Even after deobfuscation, analysis remained difficult due to the large amount of unnecessary code. The entry point launches the mirar.region1 form, repeatedly creates and closes multiple hidden and dummy WinForms, and eventually executes mirar.GForm2.GForm2_Load.

mirar.GForm2.GForm2_Load code

mirar.exe communicates with the previously observed attacker-controlled server, 435123332155.com, and functions as a backdoor. To resolve the attacker-controlled server domain, it uses Cloudflare’s DNS over HTTPS feature.

Code using Cloudflare DNS over HTTPS

The malware connects to /llllmaw/api.php, receives action commands from the attacker-controlled server, and executes them. Communication data is encrypted with AES using a randomly generated IV and the fixed key value MnBvCxZa0987654321QwErTy!@#$%^&*, then Base64-encoded.

AES encryption and Base64 encoding code

The actions exchanged with /llllmaw/api.php are as follows:

Action Function
ping Exchanges "ping" and "pong" data to verify that the connection with the attacker-controlled server is functioning normally
heartbeat If the received JSON data contains "restart", the malware re-establishes communication with the attacker-controlled server. If it contains "update", it downloads a ZIP file from the specified URL and executes the first EXE file found after extraction
report Returns the result of command execution to the server

The most notable behavior is when the heartbeat action contains "update". As seen earlier in UnityPlayer.dll, the malware downloads a ZIP file from the specified path, extracts it, and executes the first EXE file it finds.

Code that downloads the ZIP file and executes the EXE