Minas – on the way to complexity

General attack execution flow

Sometimes when investigating an infection and focusing on a targeted attack, we come across something we were not expecting. The case described below is one such occurrence.

In June 2022, we found a suspicious shellcode running in the memory of a system process. We decided to dig deeper and investigate how the shellcode was initially placed into the process and where on the infected system the threat was hidden.

The infection chain

We were unable to reproduce the whole infection procedure, but we were able to reconstruct it from the point at which PowerShell was executed, as shown in the sceme below.

General attack execution flow

In a nutshell, the infection chain is as follows:

  • PowerShell script runs via the Task Scheduler and downloads the lgntoerr.gif file from a remote server.
  • The script decrypts lgntoerr.gif, resulting in a .NET DLL, which is then loaded.
  • The .NET DLL extracts and decrypts three files from its resources: two DLLs and an encrypted payload. The extracted files are placed in the ProgramData directory.
  • The .NET DLL creates a task to autorun the legitimate ilasm.exe component at system startup via Task Scheduler.
  • Task Scheduler starts ilasm.exe from the ProgramData directory.
  • ilasm.exe launches fusion.dll, a malicious DLL hijacker, from the same directory.
  • fusion.dll loads the second decrypted DLL.
  • That DLL creates a suspended dllhost.exe process.
  • It then decrypts the payload from the encrypted binary file.
  • The decrypted payload is loaded into the dllhost.exe process as a DLL.
  • The PID of the dllhost.exe process is saved to a file in the ProgramData directory.
  • The dllhost.exe process passes control to the decrypted payload.
  • The payload DLL extracts and launches the miner DLL in memory.
  • We named this malware Minas. From our reconstruction of the infection chain, we determined that it originated by running an encoded PowerShell script as a task, which we believe with low confidence was created through GPO:

    Encoded PowerShell command

    Encoded PowerShell command

    Technical description

    The core functionality of the PowerShell script is to launch the malware installation process. To do this, the PowerShell script downloads an encrypted payload from a remote server, decrypts it using a custom XOR encryption algorithm with the key “fuckkasd9akey” and loads the  payload into memory:

    Decoded PowerShell command

    Decoded PowerShell command

    The payload is a .NET binary (DLL) that is launched by the PowerShell process, passing three arguments:

    $a.GetType(“I.C”).GetMethod(“I”).Invoke($null, ([Byte[]]($d),”A5D9FD13″,0));

  • $d: .NET DLL as an array of bytes;
  • A5D9FD13: (key for decrypting resources in the .NET DLL);
  • 0: (parameter used to block the creation of more than one main payload process).
  • This .NET binary (which we will refer to as “the installer”) is responsible for the subsequent installation of the malware components contained in the resources of .NET DLL.

    Using hash functions (Ap, SDBM, RS), the installer creates a directory structure:

    C:ProgramData{ApHash(MachineName)}{ApHash(MachineName)}ilasm.exe
    C:ProgramData{ApHash(MachineName)}{ApHash(MachineName)}fusion.dll
    C:ProgramData{ApHash(MachineName)}{RSHash(MachineName)}{RSHash(MachineName)}
    C:ProgramData{SDBMHash(MachineName)}{SDBMHash(MachineName)}.dll

    Example files and directories

    Example files and directories

    Next, it checks for the presence of the legitimate ilasm.exe file (version 4.0.30319 located at %windir%Microsoft.NETFramework64v4.0.30319ilasm.exe or version 2.0.50727 located at %windir%Microsoft.NETFramework64v2.0.50727ilasm.exe) on the system (note that if ilasm.exe is present on the system, it should be in one of these directories). If the file is not found, the installation process will be terminated. As soon as ilasm.exe is found, a Scheduled Task is created as a persistence mechanism:

    • Task path – C:WindowsSystem32TasksWindowsMicrosoft{RSHash(ApHash(Hostname))}{ApHash(RSHash(Hostname))}
    • File name - C:ProgramData{ApHash(MachineName)}{ApHash(MachineName)}ilasm.exe
    • Delay - 120 seconds

    After this, the files are copied to the previously created directories as mentioned above (see directory structure).

    The malware then proceeds to append the first 100 bytes of the installer to the file {RSHash(MachineName)} that was extracted from the “_64_bin” .NET DLL resource, and the resulting file is encrypted (the key is the machine name in lower case). In addition, up to 10240 of random bytes are appended to the fusion.dll and {SDBMHash(MachineName)}.dll files, thus rendering hash detection by anti-malware products ineffective.

    After that, the installer starts the previously created task for the running ilasm.exe, which in turn loads the malicious fusion.dll library located in the same directory, under the assumption it is using the legitimate fusion.dll (DLL hijacking technique).

    The malware execution process consists of two loaders: DLL hijacker fusion.dll and the next stage loader {SDBMHash(MachineName)}.dll.

    The DLL hijacker does three things:

  • Hides the console of the ilasm.exe process.
  • Determines whether the name of the process is ilasm.exe. If not, it terminates the process.
  • Based on the SDBM hash function, it builds the path C:ProgramData{SDBMHash(MachineName)}{SDBMHash(MachineName)}.dll and tries to load that DLL into memory via the LoadLibraryA API function.
  • The loaded {SDBMHash(MachineName)}.dll DLL again checks whether the name of the process is ilasm.exe.

    It then generates the file path C:ProgramData{SDBMHash({SDBMHash(MachineName)})} and checks if it exists. If the file exists, it reads the value (decimal number) from it. This decimal number is the PID of the dllhost.exe process multiplied by 0x1F4 created by a previous run of Minas. The loader then tries to terminate the process with that PID.

    It then reads and decrypts (recall that the key is the machine name in lower case) the main payload (the miner) located at C:ProgramData{ApHash(MachineName)}{RSHash(MachineName)}{RSHash(MachineName)}. In addition, the loader creates a process environment variable (SetEnvironmentVariable) configuration with values ​​{“addr”:”185.243.112.239:443″,”p”:”143e256609bcb0be5b9f9c8f79bdf8c9″} (see the configuration description below for more details).

    Passing parameters through the process

    Passing parameters through the process

    After that, {SDBMHash(MachineName)}.dll creates a suspended dllhost.exe process, creates a section, maps it into the dllhost.exe process and writes the previously read and decrypted file (raw loader with the miner component). It then reads the memory of the dllhost.exe process, determines the entry point of the main thread and rewrites it to:

    sub rsp, 48
    call (section with the body of a previously written data)
    nop

    The PID of the created dllhost.exe process multiplied by 0x1F4 is then written to C:ProgramData{SDBMHash({SDBMHash(MachineName)})}, after which the dllhost.exe process resumes. It then terminates the ilasm.exe process.

    Last but not least, dllhost.exe passes control flow to the decrypted raw loader that maps the XMRig miner (assembly of the XMRig miner in the form of a DLL file) in the process memory, and then launches it using reflective loading.

    The miner gets the values ​​of the process environment variable configuration using (GetEnvironmentVariable). These values ​​are used for mining cryptocurrency with the following configuration:

    "-o 185.243.112.239:443" (IP address obtained from environment variable configuration, addr value) — acts as the address of the mining server.
    "--tls" Enables SSL/TLS support (requires pooling support).
    "--tls-fingerprint 14E18CC1BD2F1AF7344B31692CAEDA949A62F71475F43AE4D9EA287E9847B495" Pool TLS certificate thumbprint for certificate hard pinning.
    "cpu-max-threads-hint 64" Maximum number of threads.
    "-B" Runs the miner in the background.
    "--rig-id 143e256609bcb0be5b9f9c8f79bdf8c9" (rig ID obtained from configuration environment variable, p value) — Rig ID for pool statistics (requires pool support).

    Conclusion

    Minas is a miner that uses a standard implementation and aims to hide its presence. The difficulty of detection is achieved due to encryption, the random generation of names and the use of hijacking and injection techniques. It also has the ability to stay on the infected system using persistence techniques.

    Although we were unable to determine with complete certainty how the initial PowerShell command was executed, our indicators pointed to execution via GPO. This is particularly worrisome because it means the attackers have compromised the network, indicating that they are going to great lengths to install their miners.

    Also, it is very likely that a new variant will be released in the future that avoids AV detection. As a rule of thumb, use an AV that doesn’t primarily rely on signature detection, but also looks at (processes) behavior.

    Minas indicators of compromise

    MD5 hashes
    08da41489b4b68565dc77bb9acb1ecb4
    06fe9ab0b17f659486e3c3ace43f0e3a
    f38a1b6b132afa55ab48b4b7a8986181
    63e0cd6475214c697c5fc115d40327b4

    More indicators of compromise and YARA rules for detecting Minas malware are available for TIP subscribers. Contact [email protected] for more details.

    Source:: Securelist