Research

Archive for the ‘Research’ Category

Zango decision offers legal safeguards to the security community

Tuesday, June 30th, 2009

One of the provisions of the Communications Decency Act (Section 230 of the US Code) established a safe harbor for ISPs so that they couldn’t be held liable for the speech of their users. If you take umbrage at something someone said on the Internet, your remedy is to sue the speaker, not their ISP or telephone company.

That safe harbor is pretty well known, however there is another provision in title 230 that hasn’t received quite as much attention. Subsection (c) (2) provides protection for “Good Samaritan” blocking of offensive material. This states that service providers are not liable for voluntarily blocking access to offensive or otherwise objectionable material.

Kaspersky’s anti-malware product displays warnings and blocks the operation of Zango’s software, which is classified as adware. Zango wasn’t very fond of this practice and thus sued Kaspersky for tortuous interference in Zango’s business. Kasperksy was able to obtain a summary judgment in trial court because of the 230 safe harbor. Zango appealed to the US Court of Appeals for the Ninth Circuit. That court recently handed down a judgment for Kaspersky.

One of the arguments Zango raised in the appeal was that Kaspersky was selling a product, not offering an interactive online service. The court found that Kaspersky’s products count as an interactive computer service based on the fact that they disseminate updates via the Internet. This definition of interactive computer service should be broad enough to cover a good chunk of the security industry.

I am not a lawyer, this post does not constitute legal advice, nor would I be competent to offer such advice. The following is just the speculation of a security geek that thinks that our legal system should be accessible to anyone willing to do the requisite research. That said, for those organizations that would not be covered, I wonder if including a feature that allows users to update content via the Internet would be enough to extend the liability protection to that organization.

Another interesting side effect of including security services under the liability shield is that it could be used to try to shield an individual security researcher from liability. The exact wording of the statue states that no provider or user of an interactive service shall be held liable for:


"any action taken to enable or make available to information content providers
or others the technical means to restrict access to [objectionable content]”

If a researcher were to publish security research online that would allow others to develop countermeasures, that sure sounds a whole lot like it would be included in that definition to me. In theory, this could be used to shield researchers who publish vulnerability information. While this law may offer protection to those who disclose information in a number of different ways, SecureWorks supports and follows guidelines for responsible disclosure.

If this legal tactic were to be accepted in a court of law, there could be two unintended restrictions to when this defense could be employed, that some might consider leading to undesirable outcomes.

First, as the law only protects users or providers of interactive services, this liability shield may not work for someone presenting information in person or dead tree format. Second, if the requirement is to give information which would allow others to be able to restrict access, it might require enough information to write a signature to block the attack. So this could lead to a situation where revealing information online, full disclosure style, could have more legal protections then giving a talk at Blackhat for example. But then again, perhaps videotaping the talk and putting it online would be enough for conferences to be counted as an interactive service. It would be nice to have another tool to defend against legal threats that have unfortunately prevented some security talks.

Share This Blog | SlashDot | del.ico.us | Technorati | Reddit | Digg it

SHA-1 Collision Attacks Now 252

Wednesday, June 3rd, 2009

Summary:

Eurocrypt 2009 was recently held from April 26-30 in Cologne, Germany. Sponsored by the International Association for Cryptologic Research (IACR), the website states that "It is devoted to all aspects of cryptology." This year’s Eurocrypt rump session was held on April 28, which featured a talk entitled "Automatic Differential Path Searching for SHA-1". Authored by researchers at Macquarie University in Sydney, Australia, their work reveals a collision attack on SHA-1 with a complexity of 252 operations (the previous fastest known SHA-1 collision attack had required 263 operations). This is a significant improvement in finding SHA-1 collisions.

Hash Function Attacks:

A cryptographic hash function is an algorithm that takes a message as an input and computes a fixed-size digest. SHA-1 generates 160-bit digests. The generated digest is used for a variety of applications related to information security, information assurance, and digital trust relationships. When designing new algorithms, designers of cryptographic hash functions aim to fulfill three basic properties:

  • Pre-image Resistance:
    Given a hash digest, it is difficult to find any message that will hash to the specified digest value.
  • Second Pre-image Resistance:
    Given a message, it is difficult to find a different message that hashes to the same digest value as the original message.
  • Collision Resistance:
    It is difficult to find any two unique messages that hash to the same digest value.

In this case, the SHA-1 attacks affect collision resistance, not pre-image or second pre-image resistance. This means that after 252 operations, the researchers are able to generate two unique messages that hash to the same digest value. Obtaining a SHA-1 collision via brute force would require 280 operations. To date, it remains computationally infeasible to perform pre-image and second pre-image attacks on SHA-1. At the time of writing, I am unaware of a practical collision that has been found.

One iteration of the SHA-1 function:

Until recently, SHA-1 was widely regarded as the standard in cryptographic hash functions, and remains widely used in a variety crypto systems and as a normative reference in other RFCs and standards. The transition to the stronger SHA-2 functions presents the potential for interoperability issues, as SHA-2 signatures generated by updated systems may be unsupported by older systems. Adoption of the stronger hash functions must be carefully planned in order to reduce disruption to critical business functions.

The Digital Signature Algorithm (DSA) is an example of an important standard that relies in part on SHA-1. It specifies the use of a 160-bit hash function for the signatures used in 1024-bit DSA keys. The SHA-1 algorithm is nearly always the one used to sign these 1024-bit DSA keys. In order to eliminate reliance on SHA-1, users of 1024-bit DSA keys will need to transition to 2048-bit or larger DSA keys.

The OpenPGP Message Format (RFC 4880) also presents a challenge to the transition away from SHA-1. Section 13.3.2 states that SHA-1 is "the MUST-implement algorithm," and that even "if it is not explicitly in the list [of hash functions configured to be supported], it is tacitly at the end. However, it is good form to place it there explicitly." The GNU Privacy Guard (GnuPG) gnupg command-line tool will automatically reenable SHA-1 if you removed it from a key’s list of supported hash functions, visibly adding it to the end of the list just as suggested in RFC 4880. On the bright side, both GnuPG and the proprietary PGP have supported SHA-256 for well over 5 years now, making interoperability during the transition must less of an issue for users of those popular implementations.

The OpenPGP Web of Trust (WOT) is almost exclusively made up of SHA-1 signatures. Abandoning SHA-1 signatures today would immediately "evaporate" the Web of Trust. Because of the decentralized nature of the WOT, transitioning off SHA-1 will require a collective and distributed effort on the part of WOT users. There is much work to be done to eliminate reliance on the SHA-1 hash function.

The Debian Project uses OpenPGP and the WOT extensively, and has begun the process of transitioning Debian Developers and Debian Maintainers onto stronger crypto algorithms. That link contains some valuable guidance on making the switch as non-distruptive as practicable. Debian’s transition might well serve as an example for other organizations they rely heavily PGP-based cryptgraphic infrastructure.

A centralized, Certificate Authority (CA) based chain-of-trust Public Key Infrastucture (PKI) forms the basis for SSL/TLS authentication, and with that, the trust needed for secure use of the Web. Such a system offers a different set of challenges for a transition to the SHA-2 familiy of hash functions. CAs will need to recreate their intermediate chains-of-trust using SHA-2 signatures and make plans to revoke their SHA-1 signed certificate chain. (Will someone please explain to me how you revoke a root CA certificate?). Users and system administrators with certificates signed using SHA-1 will need to be issued SHA-2 replacements, or more likely will receive a new SHA-2 certificate when they go to renew their certificate with a CA. OS and web browser makers will need to build in support for SHA-2 hash functions if they have not already, and update their lists of trusted root CAs. And of course, users will need to update their OSes and web browsers to support SHA-2 and to receive the updated lists of trusted root CAs.

Every actor has a role to play: end users, organizations, software makers, Certificate Authorities, standards bodies, and of course let’s not forget the system administrators.

Share This Blog | SlashDot | del.ico.us | Technorati | Reddit | Digg it

On The New Cybersecurity Bill

Wednesday, May 20th, 2009


On April 1, 2009, while the rest of the cybersecurity world was largely focused on the Conficker worm, Senators John (Jay) Rockefeller and Olympia Snowe introduced the Cybersecurity Act of 2009. Since the hype over Conficker has died down now, I’ve had a chance to review the text of this somewhat controversial bill and add my two cents to the discussion. There are 23 sections to the bill, a few of which have raised some alarm in the infosec community.

The two most often-seen complaints in the blogosphere are:

  1. The bill gives the President of the United States the power to "turn off the Internet" in an emergency.
  2. The bill requires mandatory licenses for practicing infosec professionals.

Complaint number one seems like FUD to an extent; the bill as worded reads "The President– …may declare a cybersecurity emergency and order the limitation or shutdown of Internet traffic to and from any compromised Federal Government or United States critical infrastructure information system or network."

Some have taken "critical infrastructure" to mean communications networks, i.e. the Internet backbone providers. Unfortunately, the bill defines critical infrastructure as whatever the President says is critical infrastructure. So the criticism of the ambiguity here is valid.

But this idea that the White House could shut down the Internet shows a largely U.S.-centric bias when it comes to thinking about what the Internet actually is. Further, such a move during an emergency would likely have worse unforeseen consequences than whatever attack might have prompted it. And it’s unlikely that such an order would be given without consulting technical experts as to the alternatives for mitigating a large-scale attack. I happen to know several Internet infrastructure experts, and I can’t think of any that would say "Hey, let’s just shut off the Internet! That will solve everything!"

Complaint number two has more validity in my book - licensing of security professionals is just plain unnecessary and just creates more bureaucracy. The security industry already has numerous certification programs, all of which already fill the perceived need to have standards in knowledge and practice. If one argues whether a certification proves anything at all, those same arguments could be applied to government licenses as well.

And who gets licensed? According to the bill, this applies to a provider of cybersecurity services to any Federal agency or an information system or network designated by the President, or the President’s designee, as an infrastructure information system or network. I happen to work for a company that provides such services. Do I have to be licensed? Does everyone who works at the company have to be licensed? Where is the delineation?

Despite these and other shortcomings, there are several programs in this Cybercrime bill that I approve of, such as the creation of the Cybersecurity Advisory Panel and the Federal Cyber Scholarship-for-Service program. However, some other provisions seem to be potential boondoggles, such as the state and regional cybersecurity enhancement program.   Throwing money at the problem, at a regional level as opposed to a national level, is not the answer when the majority of skilled security professionals are located in a handful of metropolitan areas.

However, the primary problem with this bill (and any bill put forth by a single government) is that it does nothing to address the larger problem of cybercrime, malware, and the massive outflow of stolen cash from U.S. and European banks to organized crime networks. This is the biggest threat we face on the Internet today, and it won’t be solved by any single piece of legislation (although I wouldn’t mind seeing a Senate bill mandating BCP 38).

The bottom line - until networks everywhere are held responsible for the abuse coming from their systems, the problem won’t get any better.  Note to the Obama administration—if the US government really wants to accomplish something, begin work on a global treaty against Internet and computing abuse, and put an end to the safe havens that cybercriminals currently enjoy in some countries.

 

Share This Blog | SlashDot | del.ico.us | Technorati | Reddit | Digg it

Following the Trojan Trail

Tuesday, May 12th, 2009

In this post I will go over the latest botnet making the headlines. The "Finjan botnet" appears to be large and strikes fear into many. As an average computer user, should you be afraid of the botnet, or should you be scared of being compromised by a Trojan? How bad can one piece of malware be?

I would like to give credit to FireEye for trying to track down the Finjan Botnet that Finjan first reported on. Reading through the Finjan and FireEye write-ups, one is able to reconstruct the trail and also discover the path taken. We can see two major types of Trojans that play a part in this. We have the VBInject Trojan and the AutoIt Trojan.

There are two servers on the same network to which VBInject phones home: x.x.62.2 and x.x.21.186. The server at x.x.21.186 is no longer responsive and appears down at this time. The server at x.x.62.2 is still up and DNS still responds with that IP address for the domain name used in these attacks. If you actually try to browse to that domain though, you will not arrive at this server. As you can see from reading the FireEye article, the Trojan phones home to /ldr/loadlist.php. It downloads more malware from /ldr/dl/. One of the Trojans it downloads is AutoIt.

At the time of this post, if you navigate to /ldr/dl/ you are presented with a directory structure where the Trojans had been kept but now they are gone. If you navigate to the /ldr/ directory you are presented with a login screen. It says "A username and password are being requested by http://.x.x.62.2. The site says: Fun House-10001" Is this a login page to control a botnet?

Now AutoIt looks to phone home to one server with different domain names. I have found at least five different .info domains associated with one particular IP address in the 124.217.x.x range. If you look at /proxy.cfg off of one of those domains it pops up proxy information that says to have everything open and to use the OpenDNS name servers for DNS resolution. When attempting to do a fake phone home I was presented with the below response which is the same response that FireEye got back, however the domains have changed from one ten-letter nonsensical .com domain name to another.

Here is the fake phone home that FireEye posted.

GET /0/x.php?hid=531e237606675012bef96b4bef939b8d&mhid=bd1de70c62b17015b639adb2d30f0f0b&version=7&name=Codec_v.1004.1.exe&os=WIN_XP&_=262604330120091
User-Agent: AutoIt v3

trojan1 

Notice that the user agent is listed as AutoIt. This is the AutoIt Trojan phoning home and the response is to download around 15 pieces of malware. FireEye posted the details of all of the malware in their blog post. Also I found an interesting script where AutoIt sends email through a Gmail account at http://pastie.org/pastes/385624/.

From my investigations into the various malware that use these domains I saw that anIP address in the 124.217.x.x range also pops up. This IP might serve the same function as the one in the 124.217.x.x range but I have not seen any domains for it. Both the ten-letter nonsensical .com domain names resolve to an IP address in the 94.75.x.x range. By using Google and one of the.com domain names in a search I found the whole directory listing for this malware server. When going to /_private/ it asks for a login page. “A username and password are being requested by http://xxxxxxxxxx.com. The site says: "xxxxxxxxxx.info"” The .info domain name also resolves to the same 94.75.x.x IP address.
trojan2 

Other notes in regards to the Finjan article. The Trojan that is partially redacted from their write-up is ZCHMIB.EXE and can be seen phoning home "66.90.x.x/bots /control.php?action=getMessage&version=test|16". An interesting thing about this Trojan is that it uses a site called Decaptcha to bypass captcha’s for sites. The site also has a /bot/captcha/ directory to bypass Gmail captcha so it can send spam.

The other file that was partially redacted on the Finjan site looks to be SENEKA[random].DLL. This might be associated with the TDSS/Seneka rootkit. It performs a phone home to a server in the Ukraine "GET /seneka/engine/ld.php?affid=303350&action=2". This might be the server that Finjan was talking about in regard to the botnet. The IP addresses related to this are both on the same 78.26.x.x network.

The 78.26.x.x IP addresses are no longer in use. The IP addresses resolved to a domain name that now resolves to an IP address in the 94.75.x.x range which is already associated with yet another domain name. The original domain comes to a login page but new domain name does not. At this time there is no “0-day” binary that has been identified by Finjan or anyone else to be the botnet.
trojan3 


As you can see by following the trail, gone are the days where you have just one Trojan infection. When you have an infection it usually comes from what is known as a Trojan dropper or downloader that will then download many more Trojans that each serves a purpose. From the Finjan article, the botnet masters used their dropper to open up a botnet. From this botnet they were able to specify what Trojans to download for whatever purpose they wanted. Trojans now come in many flavors.

You have spamming Trojans, ransomware, keyloggers, ones that steal your personal data, and many more. The end goal is monetary gain. When you become infected today, it is best to just do a complete reformat of your machine instead of trying to recover it, because you really don’t know how many infections you have. I have read plenty of articles where someone cleans their machine and they think everything is fine only to find more malware days to weeks later.

There is not any perfect AV tool; there is no perfect solution for any one problem. Your best defense is to practice what is called defense in depth and to only go to known websites. Don’t open mail from people you don’t know and be careful opening attachments from people that you do know. Update your OS and software regularly, including AV. Just having AV does not mean that you are protected; you also have to keep it updated.

 

Share This Blog | SlashDot | del.ico.us | Technorati | Reddit | Digg it

Speaking at RSA

Friday, April 17th, 2009

RSA speaker badge
The 2009 RSA conference kicks off next week in San Francisco. It looks like a busy week for me - I’ll be presenting first on Tuesday, April 21st at the SecureWorks booth on the showfloor at 1:00 PM PDT. This will be a “Conficker Q&A” session. I’ll be answering questions with the knowledge I’ve gained from reverse-engineering Conficker and also from my participation in the Conficker Working Group. So, if you have any burning questions about the threat posed by the Conficker worm, drop by the booth at that time and I’ll try to answer them.

On Wednesday at 9:10 AM, I’ll be participating in a panel discussion called “Deconstructing The Modern Online Criminal Ecosystem” along with panelists Lawrence Baldwin (MyNetWatchman) and Dr. Robert Bruen (KnujOn). This should be a very interesting discussion, offering some behind-the-scenes insights into the cybercrime economy from experts who are in the trenches fighting it every day. The work being done by my co-panelists is amazing, but rarely do you get to hear about it in a public forum. The panel will be led by Patrick Peterson of Cisco’s IronPort division. Patrick is a Cisco Fellow and a renowned speaker and security expert, so I expect we may reach the highest potential of panel discussions.

Finally, on Thursday I’ll be delivering my own presentation entitled “Demonetizing Botnets” at 2:10 PM. This talk outlines my ideas for how we should restructure our efforts at fighting not just botnets, but cybercrime in general, both long and short-term. In this presentation, I will introduce a concept I call “offense-in-depth”, which I believe is the only approach that can address most of the cybercrime problems we are currently facing, given the current environment with respect to law enforcement’s challenges in cyberspace and pervasive vulnerabilities in computing and networking. I’m not saying my plan is any kind of silver bullet, but I hope it becomes part of the arsenal of everyone out there who is attempting to stem the tide of malicious software and computer intrusion. If you are interested in hearing my take on these matters, please attend. If anything I say inspires you to action, please meet up with me after the talk, and we can discuss the issues further. Hope to see you there!

Share This Blog | SlashDot | del.ico.us | Technorati | Reddit | Digg it

Conficker.C Worm Activity Detected

Tuesday, April 14th, 2009

Previously, the April 1st "activation date" of the Conficker.C worm was hyped as a doomsday. As Joe Stewart explains in the previous post, an update to the worm used a new algorithm to generate 50,000 domain names which could potentially be used as update or command and control servers. Conficker A and B variants chose from a list of only 250 domain names per day.

A week later, Conficker’s authors seem to be up to no good, as Conficker.C has just started delivering a nasty cocktail. It is interesting to note that the updates were sent to infected machines via P2P, not HTTP. This may mean that using the list of 50,000 possible domains for updates was a red herring. Another possible reason behind the use of P2P updates as opposed to HTTP is perhaps controls and mitigations put in place by security vendors were sufficient enough to warrant the use of P2P instead.

The SecureWorks Counter Threat Unit has observed Conficker.C installing Waledac. Waledac then installs the rogue security product Spyware Protect 2009. At some point, users of these machines will see popups trying to get users to pay for the software at a price of $49.95. The SecureWorks CTU continues to monitor and protect against this threat.

Spyware Conficker Waledac Worm

Share This Blog | SlashDot | del.ico.us | Technorati | Reddit | Digg it

Conficker April Fools Hype

Friday, March 27th, 2009

Don’t panic. If you’re reading this, you’re probably not infected with Conficker.C. If you were already infected, you wouldn’t be able to access any page on secureworks.com, due to the worm author’s apparent dislike for the removal instructions we posted for earlier Conficker variants. So we have joined the list of over a hundred sites Conficker.C victims just can’t visit. (Of course, the worm still doesn’t block any sites if you are using an HTTP proxy, but this could change after its author reads this blog post).

If you’ve been reading any news at all on the Internet in the past week, you’ve probably heard that Conficker Armageddon is approaching, and it’s scheduled for April 1st, only a few days from now. The SecureWorks Counter Threat Unit has been receiving an increasing number of inquiries asking what one needs to do to prepare for the impending April 1st outbreak.

The truth is, there will be no April 1st outbreak, despite what some of the press stories have said so far. The only thing that will happen with Conficker on April 1st is that already-infected systems will begin to use a new algorithm to locate potential update servers. There, that’s not so scary, is it?

So why all the fuss over the 1st? It all started over a massive increase in the number of domain names being used by the worm to find control servers. In the A and B variants, there were only 250 possible domain names each day at a handful of top-level domains (TLDs) for the worm to utilize. Then, along came the Conficker Working Group (nee Conficker Cabal) who set about learning the algorithm and disabling the domain names ahead of time. This didn’t sit well with the Conficker author(s), so Conficker.C was released with some additional features.

First, it would now use its own peer-to-peer protocol to allow infected nodes to update each other without the use of a centralized command-and-control server. (One might think this could allow other parties to gain control over the botnet created by the worm, but the author included digital signature checks into the code - no updates will be accepted by Conficker unless they are signed by the author’s private encryption key.)

Second, Conficker.C will use a new algorithm to generate 50,000 unique controller domain names at 110 different TLDs every day. This activity is set to start on April 1st, and since it seems too large a problem for even the Conficker Working Group to handle, the press is worried that this massive botnet might finally be unleashed to wreak havoc upon the world’s networks.

But you should not fear April 1st, 2009, and here’s why:

  1. Conficker.C is already able to receive updates via its P2P protocol today, so focusing on the April 1st date is misguided.
  2. Don’t underestimate the reach of the Conficker Working Group. These are the security industry’s heavy-hitters, and you can be sure they are working diligently to mitigate the domain issue.
  3. Even though there are 50,000 domains to look at, they are being closely monitored, and if any malicious servers do appear, they will likely be taken down or null-routed very quickly.
  4. If the author(s) of Conficker planned some massive update of malicious code, they certainly wouldn’t do it on the one day everyone is watching for it.

My personal opinion is that the April 1st activation of the new algorithm may simply be a distraction, a kind of practical joke on the part of the worm author(s). Conficker may not be something to laugh about, but it’s also not quite as serious as one might believe from reading about it in the press.

If you’ve already taken steps to protect your network against Conficker and similar network worms, you’ll have plenty of time on April 1st to read all the same old fake news stories/blog posts and prank your co-workers.

Share This Blog | SlashDot | del.ico.us | Technorati | Reddit | Digg it

Clever Hack, or Carders-at-Work?

Thursday, March 12th, 2009

Earlier this week, reports began to circulate in the media about Chinese hackers selling $200 USD iTunes gift cards online for 17.90 RMB (about $2.60 USD). It was explained that these hackers were able to acheive the remarkable feat of cracking Apple’s algorithm for generating the gift voucher codes, and were thus able to generate as many cards as they liked, all of which would be redeemable in the iTunes store.



This would be a pretty clever hack if it were true - however, something just isn’t quite right here. Nowhere in these articles does it explain one simple thing - how do they manage to generate activated iTunes gift voucher codes? When you purchase an iTunes gift card, it has to be activated before it will work, otherwise you will get an inactive code message from the iTunes store when attempting to redeem it. If this were not the case, anyone could simply walk into any of the numerous retail outlets that stock iTunes cards, grab a hook-full and run out of the door with hundreds to thousands of dollars in iTunes money. This would be a shoplifter’s dream! But, much to the dismay of those who have already tried this, the cards are simply worthless plastic until they are activated at the point-of-sale. Since this system works well and doesn’t require a “secure” algorithm to generate the numbers, it stands to reason that the same system would be used for the online gift certificate vouchers.

But, third-party reports have confirmed that the voucher codes being sold by the Chinese hackers are in fact redeemable in iTunes (not sure how they verified this without exposing themselves to criminal charges however). So what is actually happening here? I see two likely scenarios: either the Chinese hackers have managed to penetrate Apple’s internal network and/or iTunes gift card database and are directly stealing activated numbers before they can be used, or they are simply using stolen credit card numbers to purchase the cards.

Chinese hackers are certainly no strangers to penetrating networks via targeted attacks (although a targeted attack against Apple would not fit their previous modus operandi of using 0-day Windows exploits). They are also quite adept at SQL injection attacks, so a database hack isn’t an unreasonable suggestion either.

But Occam’s razor suggests that this is more likely to be a case of the hackers using stolen credit card numbers to purchase the gift voucher codes from iTunes and then reselling them. Finding a way to “cash out” stolen credit card numbers is always a primary problem for credit card theives, also known as “carders”. Sometimes carders buy goods online and resell them, but it requires a real-world “drop” where the delivery of the physical items can be made without leading the police to their door. But transferring iTunes codes can be done electronically and anonymously, and since it is something with almost world-wide demand, there is never going to be a shortage of persons willing to buy the discounted codes without asking questions. And they can explain away the mystery of where the codes come from by simply saying “Oh, we hacked the algorithm. Yeah, that’s the ticket…”

Since Apple has yet to comment on this, we can only speculate about these matters until the Chinese government takes some sort of action and arrests are made. In the meantime, if you know anyone whose credit card number has been used to make an unauthorized purchase of a large dollar value of iTunes gift codes, make sure to tell them to report it to the Internet Crime Complaint Center (IC3) right after they notify their credit card company of the fraud.

Share This Blog | SlashDot | del.ico.us | Technorati | Reddit | Digg it

Analysis of CVE-2009-0658 (Adobe Reader 0day)

Tuesday, March 10th, 2009

Bow here again. It has been a while since we posted a binary analysis on our blog, so I figured we would post one for a vuln that has been getting a lot of hoopla the past few weeks :)

Whenever there is a critical vulnerability in a product that is used frequently, we perform an internal binary analysis in order to get a complete picture of the vulnerability and write reliable countermeasures for it. In some cases, we post the analysis to our threat intelligence portal and in others they simply stay internal to SecureWorks. Enough of that, on to the fun part…

The vuln we will be talking about is CVE-2009-0658, which is a code execution vulnerability in Adobe Acrobat. There are a few PoCs hosted over at milw0rm for this vulnerability:

http://www.milw0rm.com/exploits/8099
http://www.milw0rm.com/exploits/8090

The interesting thing about these two PoCs is that they are both supposedly for the same vulnerability, however they crash in two different locations (which will be explained later). I started off debugging the vulnerability using the second exploit (8090). If you attach a debugger to Adobe Reader, you’ll see that the crash occurs here:


.text:009ADAD7 loc_9ADAD7:
.text:009ADAD7 mov ecx, [ebx+edi*4] ; breakpoint #1
.text:009ADADA mov eax, [ecx+1Ch]
.text:009ADADD mov edx, [esi+10h]
.text:009ADAE0 lea eax, [eax+eax*4]
.text:009ADAE3 lea eax, [edx+eax*4-14h]
.text:009ADAE7 mov edx, [eax+4]
.text:009ADAEA test edx, edx
.text:009ADAEC jz short loc_9A

.text:009ADAEE mov ebp, [eax+10h]
.text:009ADAF1 mov [edx+ebp*4], ecx ; Crash #2 occurs here
.text:009ADAF4 add dword ptr [eax+10


An access violation is triggered with a failed write to 0x41414141, which is obviously an attacker controlled value.

In order to go any further in the code, we must have an understanding of the JBIG2 file format and the stream within the PDF that we are dealing with. First, the documentation is available here:

http://www.jpeg.org/public/fcd14492.pdf

The irony being that you have to open it in a PDF reader ;) Now to look at the file. If you search the file for JBIG2 you'll find it in 4 places:


0000ad0: 792f 4669 6c74 6572 2f4a 4249 4732 4465 y/Filter/JBIG2De
00029e0: 7465 722f 4a42 4947 3244 6563 6f64 652f ter/JBIG2Decode/
0009750: 792f 4669 6c74 6572 2f4a 4249 4732 4465 y/Filter/JBIG2De
0010aa0: 4669 6c74 6572 2f4a 4249 4732 4465 636f Filter/JBIG2Deco


These are 4 separate JBIG2 streams within the PDF and any of them could result in the trigger of the vulnerability, however debugging reveals that the first stream triggers the vuln. The first 64 bits or so of the initial stream is here:


0000af0: 3e3e 7374 7265 616d 0d0a 0000 0001 4000 >>stream......@.
0000b00: 0033 3333 1300 000a 0000 000c e400 0001 .333............
0000b10: 2c00 0001 2c50 0000 0000 0001 0001 0100 ,...,P..........
0000b20: 0009 0400 0003 fffd ff02 fefe fe00 0000 ................


So now we need to determine what out of this stream causes the crash. I started this by trying to trace back the values used in the pointer calculation that ends up being 0x41414141 in the crash. Before continuing, it is worth noting that the calculation at 0x009ADAF1 results in a value of 0x41414141, but both registers contain the same value, 0x0D0D0D0D (which is 0x41414141/5), which is again obviously user controlled. Both of the registers used in the calculation, EBP and EDX, obtain their values shortly before the crash, so set a breakpoint just before the crash at 0x009ADAD7. The next few instructions are a fairly annoying sequence of arithmetic operations, so we'll walk through them step by step. Here is another annotated version of the disassembly:


.text:009ADAD7 loc_9ADAD7:
.text:009ADAD7 mov ecx, [ebx+edi*4] ; breakpoint #1, EDI = 0, EBX = pointer [1]
.text:009ADADA mov eax, [ecx+1Ch] ; EAX = 0×00333333 [2]
.text:009ADADD mov edx, [esi+10h]
.text:009ADAE0 lea eax, [eax+eax*4] ; EAX = 0×00FFFFFF [3]
.text:009ADAE3 lea eax, [edx+eax*4-14h] ; Final object calculation prior to crash [4]
.text:009ADAE7 mov edx, [eax+4] ;
.text:009ADAEA test edx, edx
.text:009ADAEC jz short loc_9A


It is important to note before moving on that both values in EBP and EDX during the crash are obtained by accessing a pointer to some object that is pointed to by EAX (which is calculated at [4]). We will need to focus first on what the value inside of EAX is and how we can control it.

The first calculation ([1]) is part of an array processing loop where EDI is the counter and EBX is the base pointer to the array. The array holds a series of objects, the loop is fairly small and just seems to be iterating through every available object and moving around some pointers. The second ([2]) instruction moves an integer into EAX, the value of which is 0×00333333 during exploitation, which should look familiar. If you look at the bytes from the file, 0×00333333 is very clearly at the start of the stream, we can verify this statically or by modifying that value in the file and debugging again. For the sake of time, I will just state that it is indeed from the file and is completely user controlled. If we move down, we see that value is used yet again in a calculation, which results in a value of 0×00FFFFFF ([3]) being placed into EAX. Shortly after this calculation, an array access is performed using our controlled value and the result is put into EAX, which is used later on as a pointer to some object [4]. This is where the vulnerability lies, we are able to read a value outside the array which is then used as a pointer for a memory write. It is worth noting that while debugging the exploit, the memory locations surrounding the array access are filled with 0×0D0D0D0D and it seems to be sprayed across a large portion of memory.

So to summarize all of this, we have an array of objects which are accessed via a user-controlled value and whose member variables are used to calculate an address to write to. This results in us being able to write anywhere in Adobe Reader’s address space by using some trickery. From here we need to see what the values used in the calculation represent in the file. We’ll start by looking at the stream documentations…

We know that we are dealing with the first few bytes in the JBIG2 stream and it is likely to be a stream header of some sorts. The JBIG2 documentation says that encoded JBIG2 streams are broken down into segments which are made up of two parts, the segment header and the segment data (see page 71). The format of the segment data is different depending upon the segment type, however the format for the segment header is the same across all different segment types. Knowing this, we can start looking at the segment header format. Here are the first few bytes of the stream again:


[00 00 00 01] [40] [00] [00 33 33 33] 13 00 00 0a …
[Segment#] [FL] [RT] [SPAssociat] …


According to the documentation, the first DWORD in the stream is always the segment number (pg 72, 7.2.2). The next byte is a flags field ([FL]) which indicates the segment type (the lower 6 bits) and two possible characteristics of the stream, page association field size (bit 7) and deferred non-retain (bit 8). In the proof of concept, the 7th bit (page association field size) is the only bit in the flags that is set. The byte that follows the flag field is a varying length object called the referred-to segment count [RT], in this case, it is only a byte long and the value is zero, indicating that this segment does not refer to any other segments. If this value were non-zero, then the object could be larger and would be followed by another variable length object which contains the numbers of the segments that the current segment refers to. Since the referred-to segment count is zero in the PoC, we don’t need to worry about this too much. Finally, the next DWORD is the segment page association ([SPAssociat]), which will be a byte if the page association field bit is not set or a DWORD if it is. In this case, the bit is set and so this field is a DWORD. The segment page association is the value that is responsible for the access violation.

I like to always verify that whatever I’m reversing actually lives up to the specification, so we’ll take a look at some of the code that processes this header structure. Unfortunately, the Adobe code that processes JBIG2 streams is significantly more complicated than other code I’ve seen dealing with JBIG2, so the only thing I am going to deal with here is whether or not the page association bit needs to be set for exploitation. We know from the documentation this is supposed to be true and we could just fiddle with it in a hex editor, but where is the fun in that ;) So first things first, we need to find where our file is in memory and look for references to it (specifically the 5th byte).

The first routine we will be looking at is sub_9A8D50 (boo no symbols), where var_2C is a pointer to our stream buffer that contains the stream itself. The pointer in var_2C is obtained from the return value of another function, sub_30D220 and is the result of a call to a typical malloc type function (although there is some other code wrapped around it). This occurs during this virtual function call:


.text:009A8FE8 loc_9A8FE8:
.text:009A8FE8 mov ecx, [esi+0D0h]
.text:009A8FEE mov edx, [ecx]
.text:009A8FF0 push eax
.text:009A8FF1 mov eax, [edx+14h]
.text:009A8FF4 push 0
.text:009A8FF6 push ecx
.text:009A8FF7 call eax ; 0×0030D220
.text:009A8FF9 add esp, 0Ch
.text:009A8FFC test eax, eax
.text:009A8FFE mov [esp+44h+var_30], eax
.text:009A9002 jz short loc_9A8F

.text:009A9004 xor edi, edi
.text:009A9006 cmp [esi+78h], edi
.text:009A9009 mov [esp+44h+var_2C], eax ; stream buf pointer moved into var_2C
.text:009A900D mov [esp+44h+var_28], eax


The allocation looks like this:


.text:0030D26B mov ecx, [esp+0Ch+arg_4]
.text:0030D26F cmp eax, ecx
.text:0030D271 mov ebx, eax
.text:0030D273 jb short loc_30

.text:0030D277
.text:0030D277 loc_30D277:
.text:0030D277 push ecx ; allocation size - stream length
.text:0030D278 mov ecx, esi
.text:0030D27A call malloc_wrapper_sub2
.text:0030D27F test edi, edi
.text:0030D281 mov esi, eax


There are two important things to note here, first that the stream length is used for the allocation and second that the stream data is not copied over in sub_30D220, but another routine we’ll look at a little later. Once sub_30D220 returns, we see that the return value is stored into var_28, var_2C, and var_30, so we have three variables holding onto the stream buf pointer. We then run into another virtual function call (yay):


.text:009A9019 mov edx, [esi+78h] ; one iteration
.text:009A901C mov ecx, [ebp+10h]
.text:009A901F mov eax, [esp+44h+var_28]
.text:009A9023 mov ecx, [ecx+8]
.text:009A9026 push ebp
.text:009A9027 sub edx, edi
.text:009A9029 push edx
.text:009A902A push 1
.text:009A902C push eax ; stream buf ptr
.text:009A902D call ecx ; sub_317A80
.text:009A902F add [esp+54h+var_28], eax
.text:009A9033 add edi, eax
.text:009A9035 mov eax, [esp+54h+var_30]
.text:009A9039 add esp, 10h



This virtual function call ends up resolving to sub_317B30, which is a routine with a loop and a number of function calls inside of it. During the second iteration of the loop, the following is executed:


.text:00317BFE loc_317BFE: ;
.text:00317BFE mov eax, [esi+0Ch] ; pointer to the stream buffer (with the data in it)
.text:00317C01 lea ecx, [edi+ebp]
.text:00317C04 cmp ecx, eax
.text:00317C06 jbe short loc_317C22

.text:00317C22
.text:00317C22 loc_317C22:
.text:00317C22 push ebp ; size_t (stream size)
.text:00317C23 push eax ; source pointer (obtained from ESI+0Ch)
.text:00317C24 push edi ; destination pointer (pointer allocated earlier)
.text:00317C25 call memcpy
.text:00317C2A add [esi+0Ch], ebp
.text:00317C2D add esp, 0Ch
.text:00317C30 sub [esi+8], ebp
.text:00317C33 jmp short loc_317


So now we know where the buffer we are dealing with is allocated and filled with the file contents, we can set breakpoints on the flags and see where they are read. The first trigger is here:


.text:009AD509 mov bl, [edx+4] ; Flags byte
.text:009AD50C and bl, 3Fh ; Obtain segment type
.text:009AD50F mov byte ptr [esp+30h+var_8], bl
.text:009AD513 mov edx, [esp+30h+var_8]


Which is simply attempting to obtain the segment type by ANDing the lower 5 bytes. Moving on, the next trigger of the breakpoint should occur here inside sub_9BB160:


.text:009BB176 movzx edx, byte ptr [ecx] ; segment flags, hw bp trigger #2
.text:009BB179 mov [eax+0Ch], dl ; segment flags copied
.text:009BB17C add ecx, 1
.text:009BB17F mov [eax], ecx
.text:009BB181 mov al, dl
.text:009BB183 mov cl, al
.text:009BB185 and cl, 3Fh
.text:009BB188 test al, 40h ; Page association size
.text:009BB18A setnbe dl ; is the 7th bit set? (set dl = 1)
.text:009BB18D mov [esi+4], cl
.text:009BB190 test al, 80h
.text:009BB192 movzx cx, dl ; store value of dl into cx
.text:009BB196 setnbe dl
.text:009BB199 movzx ax, dl
.text:009BB19D mov [esi+8], ax
.text:009BB1A1 mov eax, [esi+2Ch]
.text:009BB1A4 mov [esi+6], cx ; move value of cx (result from the page association test) into memory


You should see a couple of things here. First, the next hardware breakpoint will trigger where indicated above. You then see that the segment flags are copied to another location. Moving down a little ways, the lower byte of the EAX register is TESTed against 0×40. The setnbe instruction will set the destination operand (lower byte of EDX in this case) to 1 if both CF and ZF are equal to zero, or set it to 0 otherwise. Since test performs an AND and the 7th bit of the flags is set, the AND will result in ZF not being set, so DL will be set to 1. Moving down we see that the result of the previous instruction is tossed around and eventually stored back into an object in memory.

Moving a little further down the routine, you’ll see this:


.text:009BB388
.text:009BB388 loc_9BB388:
.text:009BB388 cmp word ptr [esi+6], 0 ; Was page association size field set?
.text:009BB38D jnz short loc_9BB3A3

.text:009BB38F mov eax, [esi+2Ch] ; if the page association size field is 0, this block is executed (only read one byte)
.text:009BB392 mov ecx, [eax]
.text:009BB394 mov dl, [ecx]
.text:009BB396 add ecx, 1
.text:009BB399 mov [eax+0Ch], dl
.text:009BB39C mov [eax], ecx
.text:009BB39E movzx eax, dl
.text:009BB3A1 jmp short loc_9BB3AD

.text:009BB3A3
.text:009BB3A3 loc_9BB3A3:
.text:009BB3A3 mov ecx, [esi+2Ch] ; if page association is set to 1
.text:009BB3A6 push 4
.text:009BB3A8 call sub_9BA6B0 ; read DWORD

.text:009BB3AD loc_9BB3AD:
.text:009BB3AD mov ecx, [esi+2Ch]
.text:009BB3B0 push 4
.text:009BB3B2 mov [esi+1Ch], eax ; store segment page association field in memory



This is testing the result of our previous test against 0×40 and making a function call if it was set. A quick analysis of sub_9BA6B0 indicates that it is looping through and reading the value of the segment page association field byte by byte and returning the full DWORD. The return value is then stored into memory at ESI+1Ch. This is the location where the vulnerable routine will read the page association field value from that results in the access violation. Now, moving back into sub_9AD380 we see that the value read and stored at ESI+1Ch is accessed and tested to see if it has a value:


.text:009AD887 loc_9AD887:
.text:009AD887 mov ecx, [edx]
.text:009AD889 mov eax, [ecx+1Ch] ; segment page association
.text:009AD88C test eax, eax
.text:009AD88E jz loc_9ADB40

.text:009AD894 mov ecx, [esi+10h]
.text:009AD897 lea eax, [eax+eax*4]
.text:009AD89A add dword ptr [ecx+eax*4-14h], 1 ; Crash #1 (8099)
.text:009AD89F lea eax, [ecx+eax*4-14h]
.text:009AD8A3 mov eax, [edx]
.text:009AD8A5 mov ecx, [eax+10h]
.text:009AD8A8 test ecx, ecx
.text:009AD8AA mov [esp+30h+var_4],



It is of interest to note that this is just above where the crash occurs with one of the other PoCs. If you are debugging, it is important to understand why one PoC triggers here, while the other one does not (8099). In 8099 the add instruction which triggers the crash will not be able to resolve to a valid memory address, resulting in the access violation, however in 8090, the fact we have a lot of memory allocated filled with 0D’s increases the likelihood that the address calculation will result in a valid memory address (which is a result of a Javascript heap spray). Moving down, we see that value is accessed once again prior to the final crash:


.text:009ADAD7 loc_9ADAD7:
.text:009ADAD7 mov ecx, [ebx+edi*4]
.text:009ADADA mov eax, [ecx+1Ch] ; segment page association
.text:009ADADD mov edx, [esi+10h]
.text:009ADAE0 lea eax, [eax+eax*4]
.text:009ADAE3 lea eax, [edx+eax*4-14h]
.text:009ADAE7 mov edx, [eax+4]
.text:009ADAEA test edx, edx
.text:009ADAEC jz short loc_9


So, looking back now, we can see where the page association field size is checked and where memory is written accordingly. In addition, we can also see where the value used in the array access is written into memory.

Several sources have indicated that Javascript is not necessary for this vulnerability to be exploited. There is no need for Javascript in order to trigger the vulnerability, however I’ve yet to see any exploits that are reasonably reliable with or without using Javascript. The sample that we debugged from “the wild” used Javascript for the heap spray and had a fairly small rate of success. There are potential ways of increasing the reliability of the exploit without using Javascript, however we have not captured anything of that nature yet in the wild.

This issue was patched by Adobe on March 10th, 2009. A link to the Adobe advisory is available here:

http://www.adobe.com/support/security/bulletins/apsb09-03.html

Share This Blog | SlashDot | del.ico.us | Technorati | Reddit | Digg it

Tornado Malware Kit

Thursday, March 5th, 2009

In this post, we will be taking a look at the Tornado Malware kit. Tornado is a Russian web-attack kit used by hackers to compromise as many machines as possible. “Out of the box,” it comes with 14 exploits, although users have space to add more, thanks to a modular design (handy!). Visitors are greeted with the following login prompt:

The spelling throughout the application is generally poor. After login, users are taken to the stats page (a dashboard of sorts) which shows information about the traffic the kit has seen so far, broken down by OS and web browser. The Tornado kit has a target URL which attackers direct as much traffic to as possible. Once an attacker is able to lure a visitor to the malicious URL, Tornado chooses an exploit most likely to succeed and serves it up. It does this by analyzing the visiting browser’s User-Agent header. Here we can see part of that process:

In some cases, attackers place the link into other compromised sites, so that visitors may have no idea they are browsing a malicious site. Buried in the obfuscated code, several requests are made to Russian web sites. This allows the author of the kit to monitor where the kit is used, and make sure that it is being used, you know, “legally”.

If the browser exploit attempt is successful, the victim’s machine will make a request to download an EXE from the attacker’s site. At this point, it is game over. The loader that Tornado uses is configurable, so it’s easy to add additional payloads, or change to a different payload altogether, as seen in our final screen shot. Overall, this simple exploit kit has some worrisome capabilities.

Share This Blog | SlashDot | del.ico.us | Technorati | Reddit | Digg it
SecureWorks Blogs
Other SecureWorks Blog Categories:
  • General (25)
  • Links (7)
  • Phishing (3)
  • Research (77)
  • Spam (1)
  • Trojans (5)
  • Blogs by Month:
  • June 2009
  • May 2009
  • April 2009
  • March 2009
  • February 2009
  • January 2009
  • December 2008
  • November 2008
  • October 2008
  • September 2008
  • August 2008
  • July 2008
  • June 2008
  • May 2008
  • April 2008
  • March 2008
  • February 2008
  • January 2008
  • December 2007
  • November 2007
  • October 2007
  • September 2007
  • August 2007
  • July 2007
  • June 2007
  • May 2007
  • March 2007
  • January 2007
  • December 2006
  • November 2006
  • October 2006
  • September 2006
  • August 2006
  • June 2006
  • May 2006
  • Next Steps

    Start With SecureWorks Request More Information Now
    Call SecureWorks Call Us Today
    877-905-6661

    Info Request




    Newsletter Signup

    * First Name:
    * Last Name:
    * Email Address:


    SecureWorks Authors
    SecureWorks Blog Topics