Monday, August 24, 2015

Pe Time Stamps and Yara

Lets leverage time stamps within malware with Yara!  I mean, who cares if the time stamp is accurate -- its probably not -- its a know point, often switches between versions or campaigns and can be point of detection.  Let's look at some logic:

1.  PE Time Stamp doesn't exist
2.  PE Time Stamp outside of a certain date (the future, the past, etc.)
3.  PE Time Stamp and Resource Time Stamps (same, different, one older/younger than the other)

Now, with those ideas in mind, let's play.  Oh, and before I forget, Yara uses Unix time for its date matching.  Keep that in mind.

Starting simple.  How about just seeing if a timestamp exists.
import "pe"

rule Atimestamp {
  condition:
    pe.timestamp != 0
}

That's not quite useful, so let's add a bit more into it.  How about an exact date.
import "pe"

rule Exacttimestamp {
  condition:
    pe.timestamp == 1150700835
}

Or, something in a range...
import "pe"
rule timestamprange{
  condition:
    pe.timestamp > 1150700835 and pe.timestamp < 1373882334
}

yara doesn't really have a concept of "now" that I know of, but you can cheat a bit.  If you leverage its ability to import external variables, you can write your "now" value and then assign it at run time with the "-d" option of the command line tool.

Anyway, here's an example of a resource time stamp younger than the pe time stamp.

import "pe"
rule rsrc_tp_younger{
  condition:
    pe.resource_timestamp != 0 and
    pe.resource_timestamp < pe.timestamp
}

Even better, how about any of the resources...that match a particular hash value...

import "pe"
import "hash"

rule all_rsrc_files {
  condition:
    for any i in (0..pe.number_of_resources - 1):
      (hash.md5(pe.resources[i].offset, pe.resources[i].length) == "49f68a5c8493ec2c0bf489821c21fc3b"
      and pe.resource_timestamp < pe.timestamp)
}

While we are at it, how about we check for entropy of a resource and a time stamp...

import "pe"
import "math"

rule rsrc_entropy_timestamp {
  condition:
    for any i in (0..pe.number_of_resources - 1):
      ((math.entropy(pe.resources[i].offset, pe.resources[i].length) > 6) and (pe.resource_timestamp != 0 and pe.resource_timestamp < pe.timestamp))
}

Or, perhaps a particularly high entropy section...

import "pe"
import "math"

rule text_entropy {
 condition:
   math.in_range(math.entropy(pe.sections[pe.section_index(".text")].raw_data_offset, pe.sections[pe.section_index(".text")].raw_data_size), 4.0, 5.0)
}

1 comment: