Tracking PavinLoader across ClickFix and fake download campaigns
In our previous analysis of the malicious RenPy campaigns, we identified a multi-stage loader deployed as part of the infection chain.
Further threat hunting has since shown that the same loader, which we track as PavinLoader, is being used across several different campaigns, including ClickFix attacks and fake software downloads.
Despite differences in how these campaigns reach victims, we found several common elements. These include multi-stage infection chains involving heavily obfuscated and trojanized .NET DLLs; abuse of MSBuild, .csproj, and .bat files to execute them; and EtherHiding to retrieve the command-and-control (C2) domain.
What an attack looks like
The campaigns don’t all start the same way. A victim might encounter a fake CAPTCHA that tells them to run a command, download what appears to be legitimate software, or install a malicious game.
What happens next is much more consistent. PavinLoader uses legitimate Windows tools alongside malicious .NET files to run several stages of malware. It also uses EtherHiding, a technique that uses a blockchain to hide information about its infrastructure, to find the server from which it should retrieve additional malware.
In the RenPy campaign we analyzed, that process ultimately led to Amatera Stealer, malware designed to steal information from an infected computer. We also observed PavinLoader infections delivering additional malware.
PavinLoader appears across multiple campaigns
We have identified PavinLoader in several campaign clusters:
- Malicious RenPy campaigns, as analyzed in our earlier blog post
- Several ClickFix campaigns, including recent activity from the operator(s) covered in our previous analysis
- Fake software campaigns that used Dropbox to download PavinLoader.
The loader’s use across multiple campaigns raises the possibility that PavinLoader is offered as a Loader-as-a-Service.
We also found several artifacts that support this possibility, although they are not enough to confirm it. One specific artifact on VirusTotal is shared by more than 200 files associated with PavinLoader, suggesting it may be a compilation artifact of the build process.
We also found a PowerShell script uploaded to VirusTotal containing comments such as EDIT HERE and REPLACE with a real direct link to your .bat. The associated BAT file contains the string Automated builder helper.
However, we haven’t found a build panel or sales channels that would confirm PavinLoader is being offered commercially.

Although PavinLoader has changed over time, the campaigns we analyzed share several characteristics:
- Inno Setup or MSI installers generated with different builders that run the
.batand/or.csprojfiles - Trojanized .NET DLLs, including DotNetZip, Nancy, Renci.SshNet, and OpenXML. In most of the cases analyzed, the inserted malicious methods follow a
TwoWordsorTwoWordsNumbernaming pattern, such asDefaultEvaluator5, andFallbackFactory5 - A common obfuscation technique used across the .NET DLLs
- A naming convention based on two random words, such as
GollopDevest,UnbrandRunover, andPavinWide, for DLL names, functions, strings, C2 paths, and other artifacts - EtherHiding to obtain the C2 domain, followed by HTTP requests using paths such as
assets/{two random words}.jsonto retrieve subsequent stages. C2 domains commonly use the.lat,.icu,.shop, and.cfdtop-level domains - MSBuild mechanisms for loading and executing code from DLLs, including property functions such as
[System.Reflection.Assembly]::Load(...)andUsingTask - Recurring filename patterns such as
name_4characters.cmd/bat/msi/exe—for example,prefetch_9a59.cmd,telemetry_55db.cmd, andbootstrap_64be.cmd—or random nine-character names such asaegZpQ4C7.bat. We also observed short names includingSmall.msi,small.bat, andsmall.cmd
PavinLoader consists of several .NET DLLs, and in the cases analyzed we identified the following stages:
- Loader DLL: A trojanized DLL—such as the Nancy one analyzed in our previous RenPy article—or a custom DLL. It performs anti-forensics and anti-analysis operations, changes network settings needed for the next operations, and loads the EtherHiding Loader
- EtherHiding Loader DLL: Obtains the C2 through EtherHiding and downloads the next stages from it
- Anti-Analysis DLL: Performs extensive anti-analysis checks to detect virtualized environments.
- PE Loader DLL: Loads the final PE payload.
Intermediate payloads can vary depending on the campaign configuration. First, we’ll look at some of the methods used to distribute the initial PavinLoader stages. We’ll then return to the RenPy loader campaign we analyzed in our previous article to examine the loader’s later stages.
Technical analysis
The rest of this article takes a closer look at how PavinLoader is distributed and how each stage of the loader works.
How PavinLoader is delivered
We have observed PavinLoader being delivered through several ClickFix campaigns.
In particular, we detected that the ClickFix cluster analyzed in a previous article has recently started using PavinLoader. Abuse of MSBuild and the use of .csproj and .bat files remain common across the infection chains we observed.
We covered one example in our previous RenPy analysis. Here, we’ll look at several other distribution methods.

As we saw in our previous analysis of these ClickFix campaigns, the associated PowerShell scripts change frequently. We found several versions in this activity, including both obfuscated and unobfuscated scripts.

In this example, the downloaded MSI from the Cloudflare bucket is called Installer_57be78.msi.

The package contains:
prefetch_2f76.exe: The legitimate MSBuild executableprefetch_2f76.csproj: Used to execute the Loader DLL throughUsingTaskDotNetZip.dll: The Loader DLL
The .csproj file is executed with:
"C:\Users\{USER}\AppData\Local\Logitech\Device Configuration Helper\prefetch_2f76.exe" /nologo "C:\Users\{USER}\AppData\Local\Logitech\Device Configuration Helper\prefetch_2f76.csproj" /nr:falseThe Loader DLL is a trojanized version of DotNetZip and is executed using the UsingTask element.


Unlike the RenPy example discussed in our previous article, the EtherHiding Loader is extracted from the DLL itself. An embedded resource is used as an index to extract bytes directly from the DLL, rather than obtaining those indexes from the .csproj file.
We detected another campaign that uses BAT files containing fake BUILD VERIFICATION REPORT comments, apparently intended to make analysis and detection more difficult.
In this case, the MSI CustomAction executes the BAT script with:
cmd.exe /c C:\Users\{USER}\AppData\Local\Conexant\lite_bootstrap_2.1.7\updater_8219.cmd /launchedThe obfuscated code appears below the fake comments. It concatenates multiple strings and uses indices generated through simple mathematical operations to reconstruct them. We found this type of obfuscation in most of the BAT files we analyzed.
The BAT file locates conhost.exe and relaunches itself with:
"C:\WINDOWS\System32\conhost.exe" --headless cmd.exe /c "C:\Users\{USER}\AppData\Local\Conexant\lite_bootstrap_2.1.7\updater_8219.cmd" /launchedIt then sets the MSBUILDENABLEALLPROPERTYFUNCTIONS=1 environment variable, locates MSBuild.exe, and executes it using the same file as input:
"C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe" "C:\Users\{USER}\AppData\Local\Conexant\lite_bootstrap_2.1.7\updater_8219.cmd"In this case, the Loader DLL is reconstructed by concatenating and decoding four Base64-encoded variables.

The Loader DLL has a random name and appears to be an older version because it does not contain the custom bytecode and encrypted strings in its resources.
As in the RenPy campaign analyzed previously, this stage retrieves the EtherHiding Loader stored between a Build-... marker in the CMD file through the _vezr environment variable, then decodes it using XOR with a 32-byte key.

Having looked at several methods used to distribute PavinLoader’s first two stages, we will now return to the RenPy infection chain from our previous analysis and examine the loader itself in more detail.
Analyzing PavinLoader
The .NET DLLs associated with PavinLoader are heavily obfuscated using control-flow flattening, custom bytecode, indirect calls through calli/ldftn, string encryption with different algorithms, API hashing and delegates, redundant methods, and junk code and strings.
We did not identify a known obfuscator associated with the samples, so to the best of our knowledge, PavinLoader uses a custom obfuscator.
Because fully deobfuscating the samples would be complex, we used a hybrid approach combining dynamic analysis with method invocation through reflection. We identified important methods based on their imports and parameters, invoked them, and analyzed the resulting output.
This approach does not provide complete coverage of the execution flow, but it allowed us to identify the loader’s core functionality and extract its intermediate stages. Because different functions frequently share the same names, we use metadata tokens to identify methods throughout the analysis.
Nancy trojanized DLL: Loader DLL
We covered this stage in detail in our previous blog post, so we’ll provide only an overview here.
In most of the cases analyzed, the Loader DLL is a trojanized legitimate DLL. The malicious method typically uses a {RandomWord} or {RandomWord_Number} naming convention.
The DLL contains a resource associated with the custom bytecode interpreted by the main method, two resources containing encrypted strings, and, in some cases, additional resources used as an index for extracting the next stage. Other resources appear to be decoys designed to slow analysis. In the samples we analyzed, this DLL typically:
- Decrypts strings from resources using multi-key XOR
- Resolves APIs using API hashing and
GetDelegateForFunctionPointer() - Changes network settings, including disabling TLS certificate validation and setting the default system proxy
- Performs an anti-analysis timing check using
CreateEventW(),GetTickCount(), andWaitForSingleObject() - Performs anti-forensics operations
- Loads the EtherHiding Loader either by extracting it from a marker inside
.csprojor BAT files, or by using a resource as an index to retrieve bytes directly from the DLL
GollopDevest: EtherHiding Loader
The EtherHiding Loader has two main functions: obtaining the C2 domain through EtherHiding, and downloading and loading subsequent stages from that C2.
Class 0x02000762 is responsible for decrypting strings associated with blockchain and network communication.
The strings are decrypted by 0x060027BD as follows:
- Function
0x060027BBinitializes the S-box using the XOR of the master keyactiveValuesand the Base64-decodedoptionsCollectionstring - Function
0x060027BEtakeschildSyncObjectas input and returns index bytes using XOR and permutations based on header values encoded in the first two characters of the string - Function
0x060027B9returns the decrypted string using the indexes and the previously generated S-box
This was the only class we found with encryption parameters encoded in this format.
For the remaining strings, we identified functions that returned decrypted data based on their parameter signatures—for example, methods returning strings or bytes—and invoked them through reflection. This allowed us to recover more than 1,300 strings.

Among them were strings associated with AMSI and ETW patching:
AmsiScanStringSystem.Management.Automation.AmsiUtils
System.Management.Automation.AmsiUtils+AmsiNativeMethods
ntdll
EtwEventWriteNtQueryInformationProcess
NtSetInformationThread
VirtualProtect
More than 100 URLs belonging to legitimate services are also decrypted and used to generate HTTP requests and network noise. We did not observe this behavior in every sample, suggesting it may be build-specific.
The Server class (0x02000052) generates the X-Timestamp, X-Nonce, and X-Signature HTTP headers and makes requests used to retrieve subsequent stages.
Two HTTP requests are made to synchronize parameters and obtain the payload, with HMAC used to validate the requests. Using reflection, we executed method 0x06000A77 to obtain the header values needed to retrieve the subsequent stages.
The C2 domain is obtained by making an ETH RPC (Remote Procedure Call) to bsc-dataseed.binance.org with the following JSON-RPC body:
{"jsonrpc":"2.0","method":"eth_call","params":[{"to":"0x328a1fadff154290f0ce1389a4e633698cdfdaa7","data":"0x06fdde03"},"latest"],"id":1783436775} The next stages are downloaded from the resulting C2 domain. The XOR-encoded payload is stored in the JSON response under cache.content:
{"type":"cache-binary","meta":{"version":"2.3.1","timestamp":"…","platform":"win32-x64"},"cache":{"id":"e2b69…","content":"1c.."}} In this case, the C2 paths and XOR keys decrypted from this stage and the anti-analysis DLL are:
The next stage executed is the anti-analysis DLL.
PavinWride: Anti-analysis DLL
This DLL is responsible for performing several anti-analysis checks.
The anti-analysis DLL executes system calls in different ways:
- Standard .NET Base Class Library (BCL) calls, including for registry and network operations
- Win32 P/Invoke calls, including
GetCurrentThread,NtQueryInformationThread,NtQueryInformationProcess, andNtCurrentTeb - Win32 APIs resolved through API hashing and a Process Environment Block (PEB) export table walk
The function MenuItemService.ProcessDirectory (0x06000151) is the main method responsible for delegate caching and Win32 API resolution:
- It checks if the delegate is already resolved using
managerMap.TryGetValue() - If not, it calls
ProcessDirectory (0x06000150)to obtain the HMODULE handle - It calls
ProcessDirectory (0x0600003A)that performs the PE export table walk and matches the hash. We detected that the same hashing output is obtained in several other methods (e.g.,0x06000039,0x0600003B,0x0600004E) - It obtains the delegate with
GetDelegateForFunctionPointer()and saves it in the dictionary

We used the same reflection approach to get the strings. Many strings are encrypted with the XOR key 4B729A1F5CE387D6.

The loader obtains the system’s LCID using GetKeyboardLayoutList() and compares it against more than 17 languages, including Russian, Ukrainian, Belarusian, and Armenian.
It also performs extensive system reconnaissance, including enumerating registry keys and calling Win32 APIs such as GetSystemFirmwareTable() and EnumSystemFirmwareTables() to identify virtualized environments.

We also observed decrypted references to APIs including GetCurrentProcess(), CreateToolhelp32Snapshot(), Process32First(), Process32Next(), and OpenMutex(), although we did not observe these functions being called during our execution flow.
An HTTP request is also made to one of these services:
https://ipv4[.]ipleak[.]net/json/https://get[.]geojs[.]io/v1/ip/geo[.]jsonhttps://ipapi[.]co/json/https://api[.]ipapi[.]is/https://ipinfo[.]io/json
It also checks the returned data against 96 hosting or infrastructure providers and tests whether the region code is one of: RU, UA, BY, AM, KZ, KG, TJ, UZ, GE, AZ, or MD.

If the anti-analysis checks pass, the next two stages are downloaded and decrypted using XOR keys.
We patched SelectionScope.ProcessDirectory (0x06000014) to recover the C2 paths and XOR keys for those stages:
/assets/MailersKogasin.json|WjcsVTKmuoBRqe|/assets/LanoseThrip.json|WwUX66BrGollopDevest: PE Loader DLL and Amatera Stealer
The third DLL has the same name as the second, GollopDevest, but performs PE loading.
Among its decrypted strings are:
'GollopMailers LDR DllBase VeneryCondole EdiyaFoully=0x{0:X} EdiyaStelae=0x{1:X}'
'GollopMailers LDR Flags missing IMAGE_DLL 0x{0:X8}'
'GollopMailers LDR SaranPisco invalid 0x{0:X}'
'GollopMailers LDR TlsIndex invalid {0}'
'GollopMailers LDR sanity exception: '
'HIGHLOW relocation'
'Import DLL name'
'Import FunctusAurata'
'Import INT'
'Import descriptor'
'Import hint/name'
'Import thunk'
'LdrpHandleTlsData outside ntdll .text'
'LdrpReleaseTlsEntry outside ntdll .text'
'LoadConfig32'
'OK'
'PE headers'
'Required API resolve failed: type={0}, FreshBubals={1}, module=0x{2:X}'
'TLS32'
'TLS64'
'x86 disabled until ABI proof'
ntdll.dll
kernel32.dll
LdrpInitializeTls
"STATUS_SUCCESS"
UNKNOWN(0x00000001)
UNKNOWN(0x00000002)
UNKNOWN(0x00000003)The ServerEditor.SortMemory method (0x06000014) checks the PE structure and flags before loading the payload.
To confirm this behavior, we invoked the method through reflection using the downloaded WPA.exe file as input. The PE loaded successfully.
The C++-compiled PE disguises itself as WPA.exe (Windows Performance Analyzer). We identified the payload as an obfuscated version of Amatera Stealer 4.2.3-alpha1.
It uses control-flow flattening, API hashing, anti-debugging checks, and opaque predicates to complicate analysis. We also detected use of the Heaven’s Gate technique, DNS-over-HTTPS (DoH) resolution through Google DNS, and raw sockets using \Device\Afd\Endpoint for network communication.

After this stage executes, we also observed additional payloads being downloaded and run from C2 IP addresses.
In some cases, WiX Burn bundles downloaded another payload associated with PavinLoader. In others, we detected HijackLoader. This gives the campaign operators the ability to deploy multiple payloads on a compromised machine.
IOCs
SHA-256 hashes
bdf313a019e025ebf58ccef4619444ee70e661bd444e0644ebeabd8f5caad14c
e3830f5747e3f46537d217124d80c9f3bb4d89f8d4f5138dce69ee54ea4fb6b9
a4f03272cf96732dc9f58bb466d16f358e7f50d46dba30526a9fbebfec11717b
bf04160dd1ce3571e0eb6d6dda1713c788797b5599399d4a93665a757eec376e
54fa8083c05334aa360256fbbb0ca901ce7e244a0359dd664cae78977371ec91
c1ea6d169565c70ac5d812e73483814929e9b3548ead6633595937e71a334adb
001337488c32d8610c2aef6f9330acca825f0afacd071bf6ebfc06b5a1a69f09
2837099af431e9afee76ce5e6ab5cb86bedce06e31c22be46250cb453cfdb978
252c5a3d150275013f52b4820097d7163ced4aa2f1be0fca032f8a5017673816
0c9c64b7383ec249bcf6271a4b73206d94de130ca401d16ab77fe01e5193a312
6700f62e1a3b33340cd678c388ecc8bac2e5943c0627df5d1b99b879c3ca42c9
IP addresses
93.152.224[.]75: downloads PavinLoader
65.21.80[.]170: downloads PavinLoader
195.63.142[.]49: downloads PavinLoader
Domains
perfectverified[.]com: ClickFix
PavinLoader C2
catalyst-pro[.]lat
twigoamwu[.]cfd
trusaifi[.]cfd
stellar-minds[.]cfd
pinnacle-labs[.]lat
nexahub[.]lat
fimwoglea[.]shop
velodium[.]lat
rpcsecnoweb[.]pro
more-arpc[.]icu
echo-systems[.]cfd
kelemet[.]shop
zarwieciv[.]cfd
URLs
telegra[.]ph/Project-PySynth-06-28: Amatera dead drop
Acknowledgements
- Previous analysis of the loader: https://www.derp.ca/research/hellsuchecker-clickfix-etherhiding/#26-anti-sandbox-checks-and-a-nintendo-bypass (possible AI-generated content)
- Possible related activity: https://cyberowi.pl/lumma-stealer-renpy-fitgirl-osmiowarstwowy-loader/
- Possible related activity: https://medium.com/@djordje.brankovic/from-fake-captcha-to-in-memory-execution-unraveling-a-multi-stage-malware-chain-part-1-496c603f3641
- Analysis of a forum user: https://forums.malwarebytes.com/topic/338102-solution-of-gollopdevestdll-renpy-loader-malware-from-malwarebytes-blog/
From reporting threats to removing them.
Cybersecurity risks should never spread beyond a headline. Keep threats off your devices by downloading Malwarebytes today.