Failure Is An Option

Published: 2016-01-01. Last Updated: 2016-01-01 10:07:39 UTC
by Didier Stevens (Version: 1)
2 comment(s)

6D713031CD29F69C679DE72C234E45AA !

You can not always be successful in your undertakings. Failure will happen too. But failure is not necessarily negative, for example, it's positive when you can learn something while failing. I'm happy when I learn something, even when I fail.

This diary entry is about one of my failures, I hope you'll learn something from it.

Malware authors often use social engineering to mislead their victims. One trick is to make believe their victims that an executable is a PDF document. For this they add an Adobe Reader icon to their executable.

I had the idea to try to detect such executables with YARA. Look for PE files with resources (icons are stored as resources), and then try to find the byte sequence that makes up the icon. Here is the YARA rule:

/*
  Version 0.0.1 2015/10/31
  Source code put in public domain by Didier Stevens, no Copyright
  https://DidierStevens.com
  Use at your own risk

  Shortcomings, or todo's ;-) :

  History:
    2015/10/27: start
    2015/10/31: added second rule
*/

import "hash"
import "pe"

...
rule PE_File_Contains_Acrobat_Icon_2

{
    meta:
        author = "Didier Stevens (https://DidierStevens.com)"
        description = "Detect the presence of the Acrobat Icon"
        sample = "c94255d2b4f68da6c0bbf669c87141b7"
        method = "Find hex sequence present in the icon and then calculate the hash of the bitmap and compare)"
    strings:
        $a = {07 07 07 00 00 00 00 00 EE EE EE FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF}
    condition:
        pe.number_of_resources > 0 and
        pe.sections[pe.section_index(".rsrc")].raw_data_offset < @a - 0x110 and
        hash.md5(@a - 0x110, 9640) == "95f41b1d89e6ad15ec5012f74d49d7de"
}

First I check that the file is a PE file, and that it has resources: pe.number_of_resources > 0

The raw bitmap of the ICON in this sample is 9640 bytes. That is too long as a search expression, so I search for a distinct substring of this icon, $a: 07 07 07 00 00 00 00 00 EE EE EE FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF F9 F9 F9 FF. This substring starts at position 0x110 into the raw bitmap.

So I check that string $a does not appear earlier in the PE file than the resource section: pe.sections[pe.section_index(".rsrc")].raw_data_offset < @a - 0x110

And finally, I check that the complete raw bitmap of the icon is present by calculating the md5 hash of the 9640 bytes that contain $a: hash.md5(@a - 0x110, 9640) == "95f41b1d89e6ad15ec5012f74d49d7de"

Remark: the hash.md5 method returns the md5 hash as a lowercase string, so make sure that the md5 hash you want to compare it to is also lowercase.

You can easily find the size and md5 of the raw bitmap with PeStudio (and also extract the raw bitmap):

This rule works. It triggers on the sample.

But it is one of my failures, because this rule has never detected any other samples with the same icon. And since I wrote the rule, I was able to check different new samples using the same social engineering trick. But for each sample the icon looked slightly different, and thus the hash was different.

Didier Stevens
SANS ISC Handler
Microsoft MVP Consumer Security
blog.DidierStevens.com DidierStevensLabs.com
IT Security consultant at Contraste Europe.

Keywords: malware pdf icon YARA
2 comment(s)

Comments

A 6D713031CD29F69C679DE72C234E45AA to you too!

I wonder if it would be easier to detect the icon using an image processing library that looks for the presence of specific colors that are used in the icon. Maybe possible to throw the bitmap into a temporary folder and process it with Python + Pillow? I'm not sure if Yara can do this.
In theory it's possible to do with YARA, but you have to code your own module to do the image processing.

Diary Archives