Analyzing Guloader VBScript: A Beginner’s Guide — Part2

AK1001
5 min readApr 16, 2024

--

From Part 1, we’ve extracted another piece of PowerShell code. Let’s continue our analysis.

Analyzing — PowerShell (2/2)

Below is the PowerShell code that we’ve extracted:

Extracted PowerShell Code

First, work on making the code easier to read.

  1. Refactor the code slightly to enhance readability, particularly focusing on organizing functions and loops.
  2. Eliminate unnecessary comments cluttering the code.
  3. Save the modified file as a_stage2.ps1.
a_stage2.ps1 (1/2)

Scroll down a little bit, set a breakpoint at $Vincibleness, then run the script.

a_stage2.ps1 (2/2)

At this point, print out the variables and try to understand the operation that the script is attempting to perform.

Print out the variables (1/2)

In addition, we can use Write-Output to print the variables.

Print out the variables (2/2)
Execute the script until you hit the breakpoint

There were a couple of execution errors that occurred. Since the second staged PowerShell script still required the variable from the previous script, executing it separately would have resulted in an error.

Copy error occurred

To ensure a successful run, I copied the second staged PowerShell code, pasted it into the previous script, saved it as another file output_test.ps1, and continued our analysis.

Copy the codes from a_stage2.ps1 and paste them into the output.ps1 file, then save it as output_test.ps1

Scroll down to the end of the script, add a $temp variable, set a breakpoint on it, and comment out the last line of code to prevent the execution of the final payload.

Adding a temp variable and setting a breakpoint; comment out the last line to avoid the final execution

Due to the script being obfuscated, it is hard to understand exactly what it does, and you can see the function Forhaandsvarslingerne is used to de-obfuscated.
In such cases, I’ll print the de-obfuscated code to the terminal, offering a clearer view of the actual operations.
Then, I’ll copy the output to a file named de-obfuscated.ps1. Unlike the previous Write-Output command, I’d like to print the variable names at the same time. Therefore, I’ve used the following method:

Write-Output ("{0}{1}" -f '<string>', "<variable>")

For Example:

Write-Output ("{0}{1}" -f "", 'Veltjentes=', "$Veltjentes")
Print the variable names and value at the same time

After run the script, copy the output to a text file. Below is the de-obfuscated code. You can see a couple of Windows APIs, such as VirtuallAlloc, NTProtectVirtuallMemory, and CallWindowsProcA, etc.

De-obfuscated code (1/3)
De-obfuscated code (2/3)

This code could be simplified as follows:

$Misapprehension = $GetConsoleWindow.Invoke(0)
$Borneol = $ShowWindow.Invoke($Misapprehension, 0)
$Enkeltvis = $VirtualAlloc.Invoke(0, 665, 0x3000, 64)
$Enestaaende = $VirtualAlloc.Invoke(0, 10932224, 0x3000, 4)
Copy($Soldierliness112, 0, $Enkeltvis, 665)
$Sandaflejringens=325248-665
Copy($Soldierliness112, 665, $Enestaaende, $Sandaflejringens)
$CallWindowProcA.Invoke($Enkeltvis,$Enestaaende,$NtProtectVirtualMemory,0,0)

The main objective of the code:

  1. Called API GetConsoleWindow and ShowWindow
  2. Allocate memory spaces
  3. Copy shellcode into memory
  4. Using CallWindowProcA callback function to execute shellcode [1]
De-obfuscated code (3/3)
Copy ($Soldierliness112, 0,  $Enkeltvis, 665)

The value of $Soldierliness112 is decoded content from Fedtene.Sen.
Open it with any Hex editor, the script tries to copy its content from offset 0x00 to 0x298 (Length = 665 = 0x299) into variable $Enkeltvis.

decoded payload — offset 0x00 to 0x299
Copy ($Soldierliness112, 665, $Enestaaende, $Sandaflejringens)

Then, the script attempts to copy payload from offset 0x299 to 0x4F67F into variable $Enestaaende.

The size of copy operation would be:
325248–665=324583=0x4F3E7

The end address would be :
0x4F3E7+0x299-1 = 0x4F67F

decoded payload — offset 0x299 to 0x4F67F

The last one is using CallWindowProcA callback function to execute shellcode.

Now that we have a clear understanding of what this script was doing, let’s return to the PowerShell ISE and run the script. It will pause at the breakpoint that we’ve set earlier.

Focus on the parameter of the API CallWindowsProcA that is used.

Print out the value of variables in hex

To print variable in Hex form, you can use:

$variable.ToString("X")

We can use Process Hacker to examine the memory. Please note that your memory addresses may differ from mine:

Address of decryption routine
Address of encrypted shellcode

If you want to continue the shellcode analysis, open x64dbg and attach it to the PowerShell ISE process. Set a breakpoint at the start address of the shellcode.

Attach PowerShell ISE process and set breakpoint at start address of shellcode

Then, use IEX to execute the last variable, $Bunky. The debugger will hit the breakpoint at the start address of the shellcode.

Execute the final variable with IEX command

The analysis of the GuLoader VBScript concludes here. Thank you for reading. I hope you found this article helpful and informative. Happy analyzing!

Reference

[1] UNVEILING THE SHADOWS: THE DARK ALLIANCE BETWEEN GULOADER AND REMCOS
https://research.checkpoint.com/2023/unveiling-the-shadows-the-dark-alliance-between-guloader-and-remcos/

--

--

AK1001
AK1001

Written by AK1001

A cybersecurity researcher. Focusing on malware analysis, threat hunting, and threat intelligence.

No responses yet