Didier Stevens

Tuesday 18 May 2010

Quickpost: More Malformed PDFs

Filed under: Malware,PDF,Quickpost — Didier Stevens @ 12:05

Here’s a heads up for some malicious PDF samples that are deliberately malformed to avoid detection.

The most important case is the missing endobj keyword:

Adobe Reader will happily parse a PDF where the object are not terminated with endobj, but my pdf-parser won’t. I’ll have to update the parser to deal with this case.

The cross-reference table can also be omitted:

This is not an issue for my parser.

And then I also received a sample with a stream object, where the case of the endstream object was wrong: Endstream. First we assumed Adobe Reader was not case-sensitive for the endstream keyword, but I found out it can actually parse a stream object with missing endstream keyword:

This is an issue for my parser.

Tuesday 9 March 2010

Frisky Solitaire – Another Info Stealer

Filed under: Forensics,Malware — Didier Stevens @ 0:00

Marcus Murray gave a great talk at TechEd Berlin 2009: “Hack-Proofing Your Clients Using Windows 7 Security”. In one of his demos, he showed a trojaned Excel spreadsheet. The spreadsheet was a simple text-based game, but it had a malicious component that executed surreptitiously while the game was played.

As I’ve done several hacks with Excel macros in the past, this made me realize that social engineering is a key element to get people to run macros from a spreadsheet of unknown origin.

Several people have asked me about de details of the vulnerability I exploited in my PDF Info Stealer PoC. But that’s not important. It’s not about the exploit, it’s about the payload: the info stealer. As I’ve written in my previous post, I don’t even need an exploit to get users to execute the info stealer. If I put the info stealer inside an Excel spreadsheet and social engineer the targeted users to execute the macros, I’ve achieved my goal without exploiting a software vulnerability.

I present you Frisky Solitaire:

Frisky solitaire is more compelling than text-based Excel games, because of the graphics. I took Solitaire from ReactOS, turned it into a DLL and embedded it with my memory loading shellcode into Excel macros (the same technique as I developed for cmd.dll and regedit.dll). I imagine that a simple game like Solitaire in Excel can go viral inside a company, when you know that many corporations disable standard Windows games on their desktops and Terminal Servers.

But in a crude attempt at social engineering the male population of a targeted company, I added an element of nudity to the game. The implied message of the game’s title is that winning games increases nudity. I know, I’m talking about basic instincts here, but it still does the trick…

So I imagine that this game can become popular with a large part of the male employees of a targeted company. And that they wouldn’t question the fact you have to execute Excel macros to play a game. Sounds plausible, no?

Of course, you guessed it: Frisky Solitaire is trojaned with an info stealer… No need to exploit a software vulnerability to steal info. Given that here too, everything is done in memory, detection is unlikely.

Monday 8 March 2010

PDF Info Stealer PoC

Filed under: Forensics,Malware,PDF — Didier Stevens @ 0:00

An info stealer is malware that steals credentials or files from its victims.

Info stealers don’t require admin rights to perform their task, and can be designed to evade or bypass AV, HIPS, DLP and other security software.

I helped out a friend testing his environment with a PoC PDF info stealer I designed (I will not publish it).

This PDF document exploits a known vulnerability, and executes shellcode to load a DLL (embedded inside the PDF document) from memory into memory. This way, nothing gets written to disk (except the PDF file). The DLL searches the My Documents folder of the currect user for a file called budget.xls, and uploads it to Pastebin.com.

My PDF info stealer was succesful: file budget.xls was posted to Pastebin.com

Preventing an info stealer from operating is not easy. The Windows operating system is designed to give user processes unrestricted access to the user’s data. It’s only starting with the Windows Vista kernel and Windows Integrity Control that a process can be assigned a lower level than user data and be restricted from accessing it. Lowering the Integrity Level of Acrobat Reader will help us in this case, but if I exploit an Excel vulnerability (or just use macros, without exploiting a vulnerability), the integrity levels will not protect us.

Neither is preventing data egress easy. OK, you can decide to block Pastebin.com. But can you block all sites that can be posted to? Like Wikipedia? And if you can, do you block ICMP packets?

To protect confidential data, don’t let it be accessed by systems with Internet access. That’s not very practical, but it’s reliable. Or use strong encryption with strong passwords (not the default RC4 Excel encryption). The info stealer will have the extra difficulty to steal the password too.

I know this is obvious advice, but it’s not easy protecting data from carefully designed info stealers on Windows.

Monday 11 January 2010

Adobe Reader JavaScript Blacklist Framework

Filed under: Malware,PDF,Vulnerabilities — Didier Stevens @ 1:51

The JavaScript Blacklist Framework is a security feature Adobe released with Adobe Reader and Acrobat versions 8.1.7 and 9.2.

When you’re in a case where you need to use Adobe Reader and you can’t disable JavaScript, the JavaScript Blacklist Framework can help you mitigate zero-days in JavaScript API functions by disabling the vulnerable functions.

I produced a video where I disable util.printf:

Notice that when I blacklist util.printf, the script still executes until the blacklisted function util.printf is called. At that moment, the script is cancelled and the user is warned.

On Windows, you can blacklist functions by adding them to registry value tBlackList (HKLM\SOFTWARE\Policies\Adobe\product\version\FeatureLockDown\cJavaScriptPerms\tBlackList). To blacklist more than one function, use the same registry value and separate the functions by the pipe-character (e.g. Util.printf|Collab.getIcon). Pay attention to the fact that the framework is case-sensitive (e.g. Util.printf is correct, util.printf is not correct).

The framework is impervious to bypassing with some basic obfuscation techniques found in malicious PDFs (eval(“util.printf… ; x = util.printf; x(“… ).

It’s too bad that blacklisting is limited to the JavaScript API; the functions to blacklist must be in the form <object-name>.<function-name>. Otherwise we would be able to blacklist some global functions of the JavaScript language that are often used in malicious PDF files, like unescape. According to the ECMAScript specification, unescape is a member function of the Global Object. I tried several ways to blacklist it (unescape, .unescape, this.unescape, Doc.unescape, …), but failed.

If you really want to disable unescape, you could do this by patching the JavaScript plugin EScript.api. Maybe I’ll post a method to do this in-memory with my basic process manipulation tool kit.

Adobe Reader JavaScript Blacklist Framework

Friday 1 January 2010

The Undeletable SafeBoot Key

Filed under: Malware,My Software — Didier Stevens @ 12:53

I present you a new program to create the SafeBoot registry key with special permissions protecting it from deletion. After using this new program, you’ll be able to restore the SafeBoot registry keys with my .REG files.

Many malware deletes the SafeBoot registry key to prevent you from booting into Safe Mode. I provide a registry fix to restore these keys.

But there exists malware that goes even further and actively monitors the registry to thwart every attempt to restore the keys by deleting them as soon as they are restored. Untill now, I recommended to use a Live CD to restore the keys in such a case (this is a complex procedure). This way, the malware is not running while you restore the SafeBoot keys.

Now I developed another solution: a program to create the SafeBoot registry key with permissions to deny Administrators and System accounts to delete the key. This way, the malware can’t delete the keys because it lacks the permissions to do so.

Here are the SafeBoot permissions on a default Windows XP install:

And here are the permissions of the SafeBoot key created with my new program:

I designed my program to create the SafeBoot key only when it is missing, and to set the special permissions while it is created:

My program will not set the special permissions when the key exists. If the SafeBoot keys exists and you can’t boot into Safe Mode, you’re dealing with another issue than a Safe Mode disabling malware (probably a buggy driver).

The program is a console program, but it will pause at the end so you can read its output, even when you launch it from Windows Explorer (i.e. double-click it). If you want to use it in a script and prevent the prompt from appearing, use option -n.

If the SafeBoot key exists, my program will tell this (SYSTEM\CurrentControlSet\Control\SafeBoot exists.) and it will leave the permissions unchanged. If your system is clean but you want to protect the SafeBoot keys, I recommend you change the permissions manually using RegEdit.

My program creates only registry key SYSTEM\CurrentControlSet\Control\SafeBoot, and not the subkeys. To restore the subkeys, you just need to use the appropriate .REG file.

Having read this, you might have thought that malware authors could bypass this protection by changing the permissions before deleting the keys. You’re right. I don’t deny Administrator and System accounts the permission to change the permissions, because I don’t expect there is malware in the wild that changes permissions of the SafeBoot key. I’ll deal with it when it eventually appears.

Download:

UndeletableSafebootKey_V0_0_0_1.zip (https)

MD5: 2FAC291AD547657E31B157B8581D4601

SHA256: 7A1E42A57BBF8E804491318671AE992947C82DCC9C2001E3033B45E4AEAB2DDE

Monday 5 October 2009

Preventing Applications From Starting (Malicious) Applications

Filed under: Malware,My Software,PDF,Vulnerabilities,bpmtk — Didier Stevens @ 0:00

Another very effective way to prevent malicious documents from infecting PCs, is to prevent vulnerable applications from starting other applications. As almost all shellcode found in malicious documents in-the-wild (again, I’m excluding targeted attacks) will ultimately start another process to execute the trojan, blocking this will prevent the trojan from executing.

This is an old idea you’ll find implemented in many sandboxes and HIPS. I added a new DLL to my basic process manipulation tool kit to prevent applications from creating a new process. Loading this DLL inside a process will prevent this process from creating a new process. I’ll explain the technique used in my DLL and how to load it in vulnerable applications in upcoming blogposts, but I want to start with showing how it prevents malicious documents from infecting a PC.

When the DLL is loaded inside a process, it will patch the Create Process API to intercept and block calls to it:

hook-createprocess-010

As a first test, we’ll use my eicar.pdf document.

hook-createprocess-009

Clicking the button will save the eicar.txt file to a temporary folder and launch the editor.

Adobe Acrobat reader will warn you when an application is to be launched:

hook-createprocess-011

But when you accept, the editor will be prevented to execute:

hook-createprocess-012

That’s because the DLL intercepted and blocked the Create Process call:

hook-createprocess-013

As a second test, let’s use a real malicious PDF document. The hooks installed by the DLL prevent it from executing the trojan:

hook-createprocess-014

Adobe Reader starts and then just crashes, without spawning another process:

hook-createprocess-017

When opening the same malicious PDF, but without the protecting DLL, the machine gets trojaned (execution of 1.exe and Internet Explorer):

hook-createprocess-018

This simple way of preventing applications from launching other applications comes with some drawbacks. For example, the Check Update function in Adobe Reader will not function anymore.

When you have a sandboxing system of HIPS installed on the machines you manage, check if you can use it to prevent vulnerable applications from starting other applications. If it doesn’t provide such a feature, try the new DLL I’ll be posting in the new version of bpmtk.

Wednesday 26 August 2009

Yubikey, Trojans and Twitter

Filed under: Encryption,Hardware,Malware — Didier Stevens @ 11:33

Stina, Yubico’s CEO, gave me a Yubikey at RSA London last year. It’s a small keyfob simulating a USB keyboard. Each time you press the button while it’s inserted in a USB port, it generates a one-time-password.

20090825-221451

The Yubikey is a clever little two-factor authentication device.

But I’ve some issues using the Yubikey in a really secure system. As Twitter plays a role in this, and because lately Twitter started to be used by trojans as a communication channel, I decided it’s time to publish the issues I encountered together with mitigating actions.

Technical details

The OTP generated by the Yubikey is an AES-encrypted data stream. I’ve obtained the AES-key embedded in my Yubikey from Yubico and am able to decode the OTP with a simple Python program.

Insert Yubikey and start generating OTPs:

OTP: lkeuuuceeeivjgtbjcbevigeccerfufugdijuhflckrd
public_id = lkeuuuceeeiv
secret_id = ************
counter = 26
counter_session = 1
random_number = 13042
timestamp = 0x8321a8
  • public_id and secret_id identifies the Yubikey (notice that the public_id is the prefix of the OTP).
  • counter: this is a persistent register. It is increased with 1 each time the Yubikey is inserted in a USB port.
  • counter_session: this is a volatile register. It is set to 0 each time the Yubikey is inserted in a USB port, and increased with 1 for each OTP generation
  • random_number is what it says on the tin: a random number, different per OTP
  • timestamp is a volatile 32-bit register. It is set to a random value each time the Yubikey is inserted in a USB port, and is then increased with 1 by a 8Hz clock. Yubico specifies an average variation of 20% on the 8Hz clock per Yubikey. With the measurements I made, I calculate that the 8Hz clock of my key has a 32% deviation.

Validating an OTP is done by successfully decrypting the OTP. Replay attacks are mitigated by comparing the counters and timestamp with historical data.

When trying to design a website that uses the Yubikey to authenticate, I imagined the following attack and found a way to mitigate it.

Attack 1:

Assume a website that uses the Yubikey to logon (i.e. an OTP generated with your Yubikey is needed to log on to the site, possibly together with more classic credentials like a username/password combo).
Because this website has my AES key and can decrypt my OTP, my Yubikey authenticates me and I’m granted access to the site.
A web browser trojan could steal an OTP like this:

  1. I generate an OTP (OTP1) with my Yubikey
  2. The trojan intercepts and stores OTP1, doesn’t send OTP1 to the website, but makes the browser display a fake error message (404, server load too high, Yubikey error, …) prompting me to generate a second OTP
  3. I’m fooled by the fake error, and generate a second OTP (OTP2) with my Yubikey
  4. The trojan intercepts and stores OTP2, and sends OTP1 to the website
  5. The website grants me access, and the trojan stops interfering
  6. OTP2 can be used by the operators of the trojan to get access to the website, as long as I’m not first to access the website at a later time with a new OTP (OTP3). Twitter could be used as a channel to communicate the OTPs in real-time to the trojan operators.

Mitigation:

The website can detect this attack (the malicious use of OTP2) if the following algorithm is implemented:

  1. for every account, the last valid OTP is stored, together with a server-side timestamp (when it was received by the website)
  2. if a new OTP is received, the counter value of the previous OTP is compared with the counter value of the new OTP
  3. when both counters have the same value, the website knows that the OTPs were generated in the same session, and thus that it can compare timestamps.
  4. it calculates the delta of the timestamps of the OTPs, and also the delta of the server-side timestamps when it received the OTPs.
  5. if the 2 deltas differ too much (more than 20% margin), then it refuses the OTP and doesn’t grand access to the website

But now comes the second attack for which I have no mitigation, despite some help from the Yubico forum.

Attack 2:

Assume a website which uses the Yubikey OTP to 1) authenticate users and 2) validate transactions. A classic example of such a site is an online banking site. The user generates an OTP to logon, and then has to generate an OTP for each financial transaction.
A web browser trojan could insert its own transaction like this:

  1. I generate an OTP (OTP1) with my Yubikey
  2. The trojan intercepts and stores OTP1 together with a timestamp, doesn’t send OTP1 to the website, but makes the browser display a fake error message (404, server load too high, Yubikey error, …) prompting me to generate a second OTP
  3. I’m fooled by the fake error, and generate a second OTP (OTP2) with my Yubikey
  4. The trojan intercepts and stores OTP2 together with a timestamp, and sends OTP1 to the website
  5. The website grants me access
  6. After an amount of time equal to the delta between the 2 stored timestamps, the trojan starts a transaction (invisible to the user) and uses OTP2 to validate the transaction.
  7. When I start my own transactions, the trojan passes the OTPs on to the website, but delays them with the same timestamp delta to avoid post-exploitation detection.

I can’t device an algorithm to detect this fraud server-side, if the Yubikey is the only authentication and validation mechanism used. This attack would not work with a challenge-response token, because the keys generated by such a token are different for logon and transaction validation. Typically, these tokens generate one type of keys for logon, and another type of keys based on a challenge for transactions. The challenge encodes data of the transaction, so that a particular challenge can’t be used for another transaction.

One Yubico forum member suggests a type of CAPTCHA to ensure that each submitted OTP is submitted by a human (hence the CAPTCHA), but I don’t believe this is practical, as malware is able to defeat some CAPTCHAs and humans are unable to solve some CAPTCHAs.

Feel free to post a comment with your migitation suggestions, but please keep them practical ;-) .

Wednesday 20 May 2009

Download My Hakin9 Article “Anatomy of Malicious PDF Documents”

Filed under: Malware,PDF — Didier Stevens @ 18:21

Hakin9 has released my article “Anatomy of Malicious PDF Documents” from their latest issue. Get it here in exchange for an e-mail address.

20090520-200713

Thursday 14 May 2009

Malformed PDF Documents

Filed under: Malware,My Software,PDF — Didier Stevens @ 7:55

For the sake of this post, I consider a PDF document malformed when it doesn’t observe the basic structure of a PDF document.

I’ve seen a couple of malicious, malformed PDF documents. The most recent was a malicious swine flu PDF document that contains another, bening, PDF document with information about the swine flu (obtained from the CDC site). This second PDF document is displayed to mislead the user while the exploit runs.

20090513-211945

This second PDF document is XOR-encoded and appended to the end of the malicious PDF document, making the malicious PDF document malformed (FYI: the PDF file format supports embedded files, but this wasn’t used here). A PDF reader like Adobe or Foxit has no problems opening this malformed PDF, because it scans a PDF document for the trailer (%%EOF) starting from the end of the document. Everything that follows this trailer and doesn’t adhere to the PDF syntax is just ignored.

20090513-213940

I’ve added some new features to my PDF tools to handle malformed PDF documents.

PDFiD

The new version of PDFiD has an –extra option. Like it names imply, use it to add extra analysis data to the PDFiD report. The extra option adds entropy calculations to the report:

20090513-220050

For a normal PDF file, expect the total entropy and the entropy of bytes inside stream objects to be close to the maximum value 8.0. This means that the distribution of byte values is close to random, which is characteristic of compressed and encrypted data.

Outside streams objects, the data appears much less random, and the entropy is much lower, usually around 4.0 or 5.0.

However, for malformed PDF documents, where data is added without using stream objects, the entropy outside stream objects is much higher. Here is the report for the malicious swine flu PDF:

20090513-203729

Another datum added to the report by using the –extra option is for the end-of-file marker %%EOF.

The “%%EOF” line mentions the number of times %%EOF appears in the document (more than once usually indicates incremental updates). “After last %%EOF” counts the number of bytes after the last %%EOF. This value will be not be zero when data has been appended.

pdf-parser

The previous versions of pdf-parser output a lot of “todo 10″ data (an indication of malformed PDF data) when they parse a malformed PDF document. I’ve suppresed this behavior, you’ll need to use option –verbose to enable it from now on, should you need it. Since I first use PDFiD to check a PDF document before using pdf-parser, I don’t consider the “todo” output relevant anymore, as PDFiDs entropy and %%EOF report will tell me if a PDF document is malformed.

20090513-223049

But the other new option in pdf-parser, –extract, is more important. Example:

pdf-parser.py –extract payload.bin malformed.pdf

This option will extract all malformed data from malformed.pdf and write it to file payload.bin, giving you easy access to the embedded payload.

Samples

You can download a normal and malformed Hello World PDF file here to get familiarized with my updated tools. 4096 random bytes have been appended to the end of the PDF document to make it malformed.

Here is a last example when the entropy calculation can be handy even if the payload is stored inside a stream object:

20090513-203522

The reason the total entropy and entropy of bytes inside stream objects is very low here, is that this malicious PDF document has a payload with a very long, uncompressed NOP-sled (more than one million times 0×90).

Tuesday 21 April 2009

PDFiD On VirusTotal

Filed under: Malware,My Software,PDF — Didier Stevens @ 16:59

I know my posts here are rather emotionless, and that’s how I prefer them for this blog.

But this time, I’m very proud and I’m not hiding it: my PDFiD tool is now running on VirusTotal!

Thanks for your work Julio!

PDFiD will give you statistics of some very basic elements of the PDF language. This helps you decide if a PDF could be malicious or not.

pdfid-virustotal

Next Page »

Blog at WordPress.com.