Didier Stevens

Thursday 22 January 2015

Converting PEiD Signatures To YARA Rules

Filed under: Forensics,Malware,My Software — Didier Stevens @ 0:56

I converted Jim Clausing’s PEiD rules to YARA rules so that I can use them to detect executable code in suspect Microsoft Office Documents with my oledump tool.

Of course, I wrote a program to do this automatically: peid-userdb-to-yara-rules.py

This program converts PEiD signatures to YARA rules. These signatures are typically found in file userdb.txt. Since PEiD signature names don’t need to be unique, and can contain characters that are not allowed in YARA rules, the name of the YARA rule is prefixed with PEiD_ and a running counter, and non-alphanumeric characters are converted to underscores (_).
Signatures that can not be parsed are ignored.

Here is an example:
PEiD signature:

 [!EP (ExE Pack) V1.0 -> Elite Coding Group]
 signature = 60 68 ?? ?? ?? ?? B8 ?? ?? ?? ?? FF 10
 ep_only = true

Generated YARA rule:

 rule PEiD_00001__EP__ExE_Pack__V1_0____Elite_Coding_Group_
 {
     meta:
         description = "[!EP (ExE Pack) V1.0 -> Elite Coding Group]"
         ep_only = "true"
     strings:
         $a = {60 68 ?? ?? ?? ?? B8 ?? ?? ?? ?? FF 10}
     condition:
         $a
 }

PEiD signatures have an ep_only property that can be true or false. This property specifies if the signature has to be found at the PE file’s entry point (true) or can be found anywhere (false).
This program will convert all signatures, regardless of the value of the ep_only property. Use option -e to convert only rules with ep_only property equal to true or false.

Option -p generates rules that use YARA’s pe module. If a signature has ep_only property equal to true, then the YARA rule’s condition becomes $a at pe.entry_point instead of just $a.

Example:

 import "pe"

 rule PEiD_00001__EP__ExE_Pack__V1_0____Elite_Coding_Group_
 {
     meta:
         description = "[!EP (ExE Pack) V1.0 -> Elite Coding Group]"
         ep_only = "true"
     strings:
         $a = {60 68 ?? ?? ?? ?? B8 ?? ?? ?? ?? FF 10}
     condition:
         $a at pe.entry_point
 }

Specific signatures can be excluded with option -x. This option takes a file that contains signatures to ignore (signatures like 60 68 ?? ?? ?? ?? B8 ?? ?? ?? ?? FF 10, not names like [!EP (ExE Pack) V1.0 -> Elite Coding Group]).

Download my YARA Rules.

peid-userdb-to-yara-rules_V0_0_1.zip (https)
MD5: D5B9B6FA7EC50A107A70419D30FEC9ED
SHA256: F8A12B5522B92AE7E3EDF11ACFAEEA7FDCC7FBDA8DC827D288A2D92B2B2CA5E2

Tuesday 20 January 2015

YARA Rule: Detecting JPEG Exif With eval()

Filed under: Forensics,Malware — Didier Stevens @ 20:39

My first release of 2015 was a new YARA rule to detect JPEG images with an eval() function inside their Exif data.

Such images are not new, but I needed an example to develop a complex YARA rule:

rule JPEG_EXIF_Contains_eval
{
    meta:
        author = "Didier Stevens (https://DidierStevens.com)"
        description = "Detect eval function inside JPG EXIF header (http://blog.sucuri.net/2013/07/malware-hidden-inside-jpg-exif-headers.html)"
        method = "Detect JPEG file and EXIF header ($a) and eval function ($b) inside EXIF data"
    strings:
        $a = {FF E1 ?? ?? 45 78 69 66 00}
        $b = /\Weval\s*\(/
    condition:
        uint16be(0x00) == 0xFFD8 and $a and $b in (@a + 0x12 .. @a + 0x02 + uint16be(@a + 0x02) - 0x06)
}

Here is an example of such an image:

20150120-204954

The YARA rule has 3 conditions that must be satisfied:

  1. JPEG magic header FFD8, tested with: uint16be(0x00) == 0xFFD8
  2. Exif structure: FF E1 ?? ?? 45 78 69 66 00
  3. eval function inside Exif data, tested with a regular expression: \Weval\s*\(

Condition 1 is straightforward: the file must start with FFD8. I’m using test uint16be(0x00) == 0xFFD8 instead of searching for {FF D8} at 0x00. FF D8 is a short string, searching for {FF D8} can cause performance problems (you’ll get a warning from YARA when it compiles rules with such short strings).

Condition 2 checks for the presence of the Exif data header. Bytes 3 and 4 (?? ??) encode the length of the Exif Data.

Condition 3 checks for the presence of the eval function. To reduce the number of false positives that would occur when searching for string eval, we use a regular expression that matches string eval, possibly followed by whitespace characters (\s*), and an opening parenthesis: \(. And we don’t want letters or numbers before the string eval (we don’t want to match a string like deval), eval must be the start of a word. To achieve this with regular expressions, you use a word boundary: \b. So our regular expression would be \beval\s*\(. Unfortunately, YARA’s regular expression engine does not support word boundaries, so I had to come up with something else. I match any character that is not alphanumeric: \W. Be warned that there is a small difference between \W and \b. \b also matches the beginning of a string (like $), while \W has to match a character. So the regular expression I use is \Weval\s*\(.

The eval function must also be found inside the Exif data. We don’t want to trigger on the eval function if it is found somewhere else in the image. That’s where YARA’s in ( .. ) syntax comes in.

The first 18 bytes of the Exif structure are various headers which we ignore, so our eval function $b must start at @a + 0x12 or further.

The total size of the Exif structure is given by expression 0x02 + uint16be(@a + 0x02). We add this to the start of the Exif header (@a): @a + 0x02 + uint16be(@a + 0x02). And finally, we have to subtract the size of the string matched by the regular expression. Unfortunately, YARA has no function to calculate this length. So we will use the minimum length our regular expression can match: 6 characters. So our eval function $b must start no further than @a + 0x02 + uint16be(@a + 0x02) – 0x06. Putting all this together gives: $b in (@a + 0x12 .. @a + 0x02 + uint16be(@a + 0x02) – 0x06)

FYI: Victor told me that he plans to add a string length function to YARA, so our condition will then become: $b in (@a + 0x12 .. @a + 0x02 + uint16be(@a + 0x02) – &b)

You can find all my YARA rules here: YARA Rules.

Friday 16 January 2015

Update: oledump.py Version 0.0.6

Filed under: Malware,My Software,Update — Didier Stevens @ 16:11

My last software release for 2014 was oledump.py V0.0.6 with support for the “ZIP/XML” Microsoft Office fileformat and YARA.

In this post I will highlight support for the “new” Microsoft Office fileformat (.docx, .docm, .xlsx, .xlsm, …), which is mainly composed of XML files stored inside a ZIP container. Except macros which are still stored with OLE files (inside the ZIP container).

When oledump.py detects that the file is actually a ZIP file, it searches through all the files stored inside the ZIP container for OLE files, and analyses these.

Here is an example of a simple spreadsheet with macros. The xlsm file contains one OLE file: xl/vbaProject.bin. oledump gives it the identifier A. All the streams inside the OLE file are reported, and their index is prefixed with the identifier (A in this example).

20150112-232122

If you want to select the stream with the macros, you use A6, like this: oledump.py -s A1

oledump also supports the analysis of an OLE file stored in a password protected ZIP file (typically, malware samples are stored inside ZIP files with password infected). When oledump.py analyses a ZIP file with extension .zip, it assumes that the file is NOT using the “new” Microsoft Office fileformat. Only when the file is a ZIP file but the extension is not .zip does oledump assume that the file is using the “new” Microsoft Office fileformat.

I have another example in my Internet Storm Center Guest Diary Entry.

oledump_V0_0_6.zip (https)
MD5: E32069589FEB7B53707D00D7E0256F79
SHA256: 8FCEFAEF5E6A2779FC8755ED96FB1A8DACDBE037B98EE419DBB974B5F18E578B

Thursday 8 January 2015

Didier Stevens Suite

Filed under: My Software — Didier Stevens @ 20:14

I bundled most of my software in a ZIP file. In all modesty, I call it Didier Stevens Suite.

Friday 26 December 2014

YouTube Video Promo

Filed under: Announcement,Didier Stevens Labs — Didier Stevens @ 10:24

I produced 21 technical videos this year. You can find them on YouTube and my video blog (sometimes I also post beta versions of my new tools along with the video on my video blog).

I decided to run a promo for my Didier Stevens Labs videos: If you buy one of my products, you get to download the original MP4 files I uploaded to my free YouTube channel. This offer is also valid for existing clients.

YouTube Video Promo

Wednesday 24 December 2014

Update: oledump.py Version 0.0.5

Filed under: Malware,My Software,Update — Didier Stevens @ 18:10

A quick bugfix and a new feature.

oledump will now correctly handle OLE files with an empty storage. Here is an example with a malicious sample that blog readers reported to me:

20141224-185748

And when the OLE file contains a stream with VBA code, but this code is just a set of Attribute statements and nothing else, then the indicator will be a lowercase letter m instead of an uppercase letter M.

20141224-190354

This way, you can quickly identify interesting VBA streams to analyze.

oledump_V0_0_5.zip (https)
MD5: A712DCF508C2A0184F751B74FE7F513D
SHA256: E9106A87386CF8512467FDD8BB8B280210F6A52FCBACEEECB405425EFE5532D9

Tuesday 23 December 2014

oledump: Extracting Embedded EXE From DOC

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

RECHNUNG_vom_18122014.doc (6a574342b3e4e44ae624f7606bd60efa) is a malicious Word document with VBA macros that extract and launch an embedded EXE.

This is nothing new, but I want to show you how you can analyze this document with oledump.py. I also have a video on my video blog.

First we have a look at the streams (I put the Word document inside a password (= infected) protected ZIP file to avoid AV interference, oledump can handle such files):

20141221-131242

Stream 7 contains VBA macros, let’s have a look:

20141221-131457

Subroutine v45 is automatically executed when the document is opened. It creates a temporary file, searches for string “1234” inside the text of the Word document (ActiveDocument.Range.Text), writes the encoded bytes following it to disk, and then executes it.

If you take a look at the content of the Word document (stream 14), you’ll see this:

20141221-131551

Following string “1234” you’ll see &H4d&H5a&h90…

&Hxx is the hexadecimal notation for a byte in VBA. It can be converted with function cbyte. We can also convert this sequence of hexadecimally encoded bytes using a decoder specially written for this. The decoder (written in Python) searchers for strings &Hxx with a regular expression, converts the xx hex values to characters and concatenates them into a string, which is returned to oledump.

#!/usr/bin/env python

__description__ = '&H decoder for oledump.py'
__author__ = 'Didier Stevens'
__version__ = '0.0.1'
__date__ = '2014/12/19'

"""

Source code put in public domain by Didier Stevens, no Copyright

https://DidierStevens.com

Use at your own risk

History:
  2014/12/19: start

Todo:
"""

import re

class cAmpersandHexDecoder(cDecoderParent):
    name = '&H decoder'

    def __init__(self, stream, options):
        self.stream = stream
        self.options = options
        self.done = False

    def Available(self):
        return not self.done

    def Decode(self):
        decoded = ''.join([chr(int(s[2:], 16)) for s in re.compile('&H[0-9a-f]{2}', re.IGNORECASE).findall(self.stream)])
        self.name = '&H decoder'
        self.done = True
        return decoded

    def Name(self):
        return self.name

AddDecoder(cAmpersandHexDecoder)

This decoder allows us to analyze the embedded file with the following command: oledump.py -s 14 -D decoder_ah.py RECHNUNG_vom_18122014.doc.zip

20141221-131712

From the MZ and PE headers, you can identify it as a PE file. We can check this with pecheck like this:

oledump.py -s 14 -D decoder_ah.py -d RECHNUNG_vom_18122014.doc.zip | pecheck.py

20141221-131759

20141221-131833
oledump_V0_0_4.zip (https)
MD5: 8AD542ED672E45C45222E0A934033852
SHA256: F7B8E094F5A5B31280E0CDF11E394803A6DD932A74EDD3F2FF5EC6DF99CBA6EF

Wednesday 17 December 2014

Introducing oledump.py

Filed under: Forensics,Malware,My Software — Didier Stevens @ 0:07

If you follow my video blog, you’ve seen my oledump videos and downloaded the preview version. Here is the “official” release.

oledump.py is a program to analyze OLE files (Compound File Binary Format). These files contain streams of data. oledump allows you to analyze these streams.

Many applications use this file format, the best known is MS Office. .doc, .xls, .ppt, … are OLE files (docx, xlsx, … is the new file format: XML insize ZIP).

Run oledump on an .xls file and it will show you the streams:

20141216-223150

The letter M next to stream 7, 8, 9 and 10 indicate that the stream contains VBA macros.

You can select a stream to dump its content:

20141216-223233

The source code of VBA macros is compressed when stored inside a stream. Use option -v to decompress the VBA macros:

20141216-223705

You can write plugins (in Python) to analyze streams. I developed 3 plugins. Plugin plugin_http_heuristics.py uses a couple of tricks to extract URLs from malicious, obfuscated VBA macros, like this:

20141216-224228

You might have noticed that the file analyzed in the above screenshot is a zip file. Like many of my analysis programs, oledump.py can analyze a file inside a (password protected) zip file. This allows you to store your malware samples in password protected zip files (password infected), and then analyze them without having to extract them.

If you install the YARA Python module, you can scan the streams with YARA rules:

20141216-224952

And if you suspect that the content of a stream is encoded, for example with XOR, you can try to brute-force the XOR key with a simple decoder I provide (or you can develop your own decoder in Python):

20141216-225911

This program requires Python module OleFileIO_PL: http://www.decalage.info/python/olefileio

oledump_V0_0_3.zip (https)
MD5: 9D5AA950C9BFDB16D63D394D622C6767
SHA256: 44D8C675881245D3336D6AB6F9D7DAF152B14D7313A77CB8F84A71B62E619A70

Tuesday 16 December 2014

YARA Rules

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

Here are some YARA rules I developed.

contains_pe_file will find embedded PE files.

maldoc is a set of rules derived from Frank Boldewin’s OfficeMalScanner signatures, that I also use in my XORSearch program. Their goal is to find shellcode embedded in documents.

20141215-160602

yara-rules-V0.0.1.zip (https)
MD5: 4D869BD838E662E050BBFCB0B89732E4
SHA256: 0CA778EAD97FF43CF7961E3C17A88B77E8782D082CE170FC779543D67B58FC72

Monday 15 December 2014

router-forensics.net

Filed under: Forensics,Networking — Didier Stevens @ 10:20

Together with Xavier Mertens I proposed a Brucon 5×5 project. Our project was accepted, and we bought 23 Cisco routers to teach memory forensics on network devices.

21 routers are used for workshops, and 2 routers are online.

If you want to practice memory forensics with real Cisco IOS devices, go to http://router-forensics.net.

Next Page »

The Rubric Theme. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 251 other followers