~/labs/cases/whatsapp-web-hta-dropper
A strange WhatsApp Web file that turned into a contact-spreading dropperA suspicious HTA hides a multi-stage VBScript dropper that installs Python automation tooling and abuses WhatsApp Web to exfiltrate contacts and spread a remote file.
On February 12, 2026, I received a file from a known contact. That was the part
that made it dangerous: the sender was familiar, but the filename was not. The
artifact was not a photo, not a PDF, and not anything I would expect in a normal
WhatsApp Web conversation. It was an HTA file named
A-8dd9b4be89d585d36.hta.
I treated it as hostile and did not execute it. The goal of this analysis was to follow the routine of an analyst receiving the file cold: identify the type, observe the expected first behavior, peel back the obfuscation, reconstruct the execution chain, and understand the final impact.
Sample
File: whats/A-8dd9b4be89d585d36.hta
Type: HTML Application / VBScript HTA
Size: 994,809 bytes
SHA256: 5a822a163d0787bcfd52b2ae3ace6cb6a92eb158a52b0fbe3cf0380acc2cb702
I started with basic triage, without opening the file on Windows:
$ file whats/A-8dd9b4be89d585d36.hta
whats/A-8dd9b4be89d585d36.hta: HTML document, ASCII text, with very long lines (2800)
$ sha256sum whats/A-8dd9b4be89d585d36.hta
5a822a163d0787bcfd52b2ae3ace6cb6a92eb158a52b0fbe3cf0380acc2cb702 whats/A-8dd9b4be89d585d36.hta
$ wc -c whats/A-8dd9b4be89d585d36.hta
994809 whats/A-8dd9b4be89d585d36.hta
$ xxd -g 1 -l 256 whats/A-8dd9b4be89d585d36.hta
00000000: 3c 68 74 6d 6c 3e 0a 3c 68 65 61 64 3e 0a 3c 74 <html>.<head>.<t
00000010: 69 74 6c 65 3e 53 79 73 74 65 6d 20 41 75 74 6f itle>System Auto
00000020: 6d 61 74 69 6f 6e 3c 2f 74 69 74 6c 65 3e 0a 3c mation</title>.<
00000030: 48 54 41 3a 41 50 50 4c 49 43 41 54 49 4f 4e 20 HTA:APPLICATION
00000040: 0a 20 20 20 20 20 41 50 50 4c 49 43 41 54 49 4f . APPLICATIO
00000050: 4e 4e 41 4d 45 3d 22 53 79 73 74 65 6d 20 50 72 NNAME="System Pr
00000060: 6f 63 65 73 73 22 0a 20 20 20 20 20 53 43 52 4f ocess". SCRO
00000070: 4c 4c 3d 22 6e 6f 22 0a 20 20 20 20 20 53 49 4e LL="no". SIN
00000080: 47 4c 45 49 4e 53 54 41 4e 43 45 3d 22 79 65 73 GLEINSTANCE="yes
00000090: 22 0a 20 20 20 20 20 49 4e 4e 45 52 42 4f 52 44 ". INNERBORD
000000a0: 45 52 3d 22 6e 6f 22 0a 20 20 20 20 20 42 4f 52 ER="no". BOR
000000b0: 44 45 52 3d 22 74 68 69 6e 22 0a 20 20 20 20 20 DER="thin".
000000c0: 4d 41 58 49 4d 49 5a 45 42 55 54 54 4f 4e 3d 22 MAXIMIZEBUTTON="
000000d0: 6e 6f 22 0a 20 20 20 20 20 4d 49 4e 49 4d 49 5a no". MINIMIZ
000000e0: 45 42 55 54 54 4f 4e 3d 22 6e 6f 22 0a 20 20 20 EBUTTON="no".
000000f0: 20 20 53 48 4f 57 49 4e 54 41 53 4b 42 41 52 3d SHOWINTASKBAR=
The result changes how the case should be handled. On Windows, .hta is executed
by mshta.exe; it is not just an HTML page. An HTA can run VBScript/JScript with
local access, which makes it a classic format for phishing and malware loaders.
First read: the file tries to disappear
The header did not look like a normal user-facing application:
<title>System Automation</title>
<HTA:APPLICATION
APPLICATIONNAME="System Process"
SHOWINTASKBAR="no"
WINDOWSTATE="minimize">
Sub Window_OnLoad
On Error Resume Next
Self.Close
End Sub
This gave me the first operational hypothesis: the attacker expects the victim to
double-click a file received in a trusted chat. When the file opens, it tries not
to leave a useful window: it runs minimized, does not appear in the taskbar, and
closes its visible window from Window_OnLoad.
To the victim, the expected effect is mundane: “I clicked it and nothing opened.”
To the attacker, that is enough. The click already handed execution to
mshta.exe.
Obfuscation levels
Before discussing the final payload, it helps to separate the layers. This kind of file is confusing because it mixes social tricks, UI tricks, and code tricks.
| Level | Technique | What it hides |
|---|---|---|
| 0 | Delivery through a known contact | The file inherits trust from the chat |
| 1 | HTA with minimized window and Self.Close | The user does not see an app running |
| 2 | On Error Resume Next | Failures are not shown to the user |
| 3 | Empty functions and fake comments | Manual reading becomes noisier |
| 4 | Numeric arrays with modular subtraction | Real strings do not appear in simple searches |
| 5 | Chr((a-b) Xor k) expressions | Another per-character string hiding format |
| 6 | 554 Layer blocks | Artificial volume slows analysis |
| 7 | ExecuteGlobal | The real script only exists at runtime |
| 8 | A second obfuscated stage | The first deobfuscation is not the end |
| 9 | Remote MSI/Python/script download | The first HTA does not need to carry the whole malware |
The important point: this is not strong cryptography. It is a deterministic chain of simple transformations repeated many times.
Array layer: input and output
The first useful block starts like this:
' Layer 1 - Array decode
eSTozhYKiMeDheJ = "178|215|219|142|185|187|227|228|192|223|196|..."
For Each hYz6RqRS5 In Split(eSTozhYKiMeDheJ, "|")
DX8XfEmqzNr = CInt(hYz6RqRS5)
DX8XfEmqzNr = (DX8XfEmqzNr - 110 + 256) Mod 256
cN6ZiOQ0QI8 = cN6ZiOQ0QI8 & Chr(DX8XfEmqzNr)
Next
g9FTeNPd0SD = g9FTeNPd0SD & cN6ZiOQ0QI8
There is nothing magical here. The script takes each number, subtracts a key, and converts the result to a character.
The formula is:
byte = (number - key + 256) % 256
char = Chr(byte)
To demonstrate without executing the HTA, I used only the first numbers from the layer:
$ nums='178|215|219|142|185|187|227|228|192|223|196'
$ key=110
$ tr '|' '\n' <<< "$nums" \
> | awk -v k="$key" '{ printf "%c", ($1-k+256)%256 } END { print "" }'
Dim KMuvRqV
That output matters. The first layer is not already reconstructing a URL or a final command; it starts reconstructing another VBScript. The visible HTA is only a decoder that builds a second script.
XOR layer: different shape, same idea
Some layers do not use arrays. They concatenate many Chr calls:
g9FTeNPd0SD = g9FTeNPd0SD & Chr((242-49) Xor 225) &
Chr((237-44) Xor 225) &
Chr((179-11) Xor 225) & ...
The per-character operation is:
byte = (a - b) XOR key
char = Chr(byte)
A minimal example is saved as a real script in
whats/analysis/decode_xor_example.py:
$ python3 whats/analysis/decode_xor_example.py
If Len(mme
Again, this is not a complex cipher. It is arithmetic hiding text. The attacker’s defense is volume: repeat it hundreds of times.
Safe first-stage deobfuscation
To automate extraction, I wrote a small parser that looks for two patterns:
numeric arrays and Chr((a-b) Xor k) sequences. It does not execute the HTA and
does not call ExecuteGlobal; it only interprets text.
Usage:
$ python3 whats/analysis/decode_vbs_layers.py \
> whats/A-8dd9b4be89d585d36.hta \
> whats/analysis/stage1.vbs
decoded 47051 bytes to whats/analysis/stage1.vbs
The result confirms what layer 1 suggested: the first recovered payload is another
VBScript. It uses a different accumulator (KMuvRqV) and ends with dynamic
execution again:
ExecuteGlobal KMuvRqV
This is the second teaching point in the case. Deobfuscating one layer does not mean reaching the final malware. Many campaigns use “decode -> execute -> decode again” to frustrate quick analysis.
In an isolated lab, another path would be replacing ExecuteGlobal X with
WScript.Echo X and running the VBS in a controlled VM to print the next stage.
For teaching material, I prefer the static parser when possible because it avoids
executing attacker logic.
The end of the first HTA
At the end of the original file, the structure is explicit:
' Layer 554
g9FTeNPd0SD = g9FTeNPd0SD & Chr((196-5) Xor 241)&...
' Execute decoded payload
ExecuteGlobal g9FTeNPd0SD
I counted 554 Layer blocks. The number is more psychological than technical. It
makes the file large, confusing, and unfriendly to manual review. The method,
however, stays the same: rebuild a string and execute it.
What the loader does next
After staged deobfuscation, the chain becomes a dropper:
HTA
-> decoded VBScript
-> second decoded VBScript
-> C:\temp\instalar.bat
-> remote MSI + embedded Python
-> whats.py / whatsz.py
-> WhatsApp Web automation
The batch file at C:\temp\instalar.bat prepares the environment:
- Picks a download URL from
centrogauchodabahia123.com. - Downloads an MSI payload with PowerShell.
- Installs it silently with
msiexec /qn. - Prepares an embedded Python runtime under
C:\temp. - Installs automation libraries: Selenium, PyAutoGUI, keyboard/mouse hooks, OpenCV, Pillow, Requests, webdriver-manager, and related tooling.
- Downloads the final WhatsApp automation script.
- Starts it with
pythonw.exe, without a visible console.
This shows the HTA’s job: it does not need to contain the whole malware. It only needs to gain execution and build the base for the real payload.
The final payload: WhatsApp Web automation
The Python stage is built around browser automation. The goal is not to “break” WhatsApp authentication. It abuses the victim’s local session.
If the victim already uses WhatsApp Web, the malware tries to reuse or copy local browser profile data. It then injects JavaScript into the WhatsApp Web page to operate the victim’s own account.
The recovered behavior shows four main capabilities:
1. Fetch campaign configuration from the attacker's server.
2. Reuse Chrome, Edge, or Firefox profile data when possible.
3. Inject WPPConnect/WA-JS into WhatsApp Web.
4. Enumerate contacts and send messages/files in bulk.
Observed infrastructure:
https://centrogauchodabahia123.com/api/config.php
https://centrogauchodabahia123.com/api/contacts.php
https://centrogauchodabahia123.com/api/log.php
https://centrogauchodabahia123.com/api/contador.php
https://centrogauchodabahia123.com/altor/wppconnect-wa.js
https://centrogauchodabahia123.com/altor/gera2.php
Contact theft is immediate damage. Before the spreading phase even matters, the operator receives names and phone numbers from the victim’s WhatsApp contact graph. Then the same automation can send a greeting, attach a remotely configured file, and send a closing message to many contacts.
That is the attacker’s real expectation: each new victim becomes a trusted sender. The next target receives a file from someone they know, not from a random number.
How the attacker hides intent
The sample combines several simple techniques:
- Social trust: the file arrives from a known account.
- HTA instead of a common document: the user may not realize it is executable.
- Invisible window: the HTA minimizes, disappears from the taskbar, and closes on load.
- Silenced failures:
On Error Resume Nextavoids visible error messages. - Structural noise: empty functions and fake comments simulate complexity.
- Missing strings: URLs and commands do not appear in a first simple grep.
- Dynamic execution:
ExecuteGlobalruns code assembled in memory. - Silent installation:
msiexec /qnand redirected output hide activity. - Console-less Python:
pythonw.exekeeps automation in the background. - Remote configuration: messages, delays, and the distributed file can change on the server.
Impact
The victim does not lose a WhatsApp password in the normal sense. Instead, the malware rides the authenticated local session.
The practical impact is still severe:
- Contacts are exfiltrated to the attacker.
- The victim’s own WhatsApp account can be used to send files and messages.
- Recipients trust the message because it came from a known account.
- The operator can adjust the campaign remotely.
- The machine keeps local tooling under
C:\temp, including Python and browser automation dependencies.
The final result is a propagation loop: one trusted account sends the bait to the next set of trusted contacts.
How I would teach this
For a class, I would split the exercise into four blocks:
- Triage: identify HTA, hash, size, header, and self-closing behavior.
- Obfuscation: explain array decode and XOR decode with small input/output.
- Safe extraction: use a text parser or replace
ExecuteGlobalwith print inside an isolated VM. - Final chain: map the dropper, infrastructure, Python setup, and WhatsApp Web abuse.
The main teaching point is that “looks complex” does not mean “cryptographically strong.” Most of the work is having the discipline to separate noise, deterministic transformation, and real behavior.
Indicators
SHA256
5a822a163d0787bcfd52b2ae3ace6cb6a92eb158a52b0fbe3cf0380acc2cb702
Suspicious local paths
C:\temp\instalar.bat
C:\temp\whats.py
C:\temp\python.exe
C:\temp\python312._pth
Suspicious process chain
mshta.exe -> powershell.exe
mshta.exe -> msiexec.exe
mshta.exe -> pythonw.exe
Network indicators
centrogauchodabahia123.com
/api/config.php
/api/contacts.php
/api/log.php
/api/contador.php
/api/api.php
/altor/wppconnect-wa.js
/altor/gera2.php
Conclusion
The file is a WhatsApp Web propagation dropper. The HTA is the first-stage camouflage: it hides the window, decodes a payload, and moves execution into a script chain. The recovered payload builds a Python automation environment, contacts attacker-controlled infrastructure, reuses the victim’s browser session, extracts WhatsApp contacts, and sends a remotely controlled file to those contacts.
The important lesson is that the attacker does not need to break WhatsApp’s authentication. They use the trust already present on the victim’s machine and in the victim’s social graph.