Skip to content

Commit

Permalink
Merge pull request #9 from crits/totalhash
Browse files Browse the repository at this point in the history
Totalhash
  • Loading branch information
mgoffin committed Jun 13, 2014
2 parents 786f120 + 433a2e2 commit 4565e75
Show file tree
Hide file tree
Showing 7 changed files with 326 additions and 128 deletions.
126 changes: 0 additions & 126 deletions pehash_service/__init__.py

This file was deleted.

93 changes: 91 additions & 2 deletions peinfo_service/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
# Copyright (c) 2014, The MITRE Corporation. All rights reserved.
# Copyright (c) 2014, Adam Polkosnik, Team Cymru. All rights reserved.

# Source code distributed pursuant to license agreement.
# PEhash computing code is from Team Cymru.
# Wrapping into the CRITs module done by Adam Polkosnik.

import pefile
import bitstring
import string
import bz2
import binascii
import hashlib
import logging
import struct
from time import localtime, strftime

import pefile

from crits.services.core import Service, ServiceConfigOption

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -35,13 +44,93 @@ def valid_for(context):
# Only run on PE files
return context.is_pe()

def _get_pehash(self, exe):
#image characteristics
img_chars = bitstring.BitArray(hex(exe.FILE_HEADER.Characteristics))
#pad to 16 bits
img_chars = bitstring.BitArray(bytes=img_chars.tobytes())
img_chars_xor = img_chars[0:7] ^ img_chars[8:15]

#start to build pehash
pehash_bin = bitstring.BitArray(img_chars_xor)

#subsystem -
sub_chars = bitstring.BitArray(hex(exe.FILE_HEADER.Machine))
#pad to 16 bits
sub_chars = bitstring.BitArray(bytes=sub_chars.tobytes())
sub_chars_xor = sub_chars[0:7] ^ sub_chars[8:15]
pehash_bin.append(sub_chars_xor)

#Stack Commit Size
stk_size = bitstring.BitArray(hex(exe.OPTIONAL_HEADER.SizeOfStackCommit))
stk_size_bits = string.zfill(stk_size.bin, 32)
#now xor the bits
stk_size = bitstring.BitArray(bin=stk_size_bits)
stk_size_xor = stk_size[8:15] ^ stk_size[16:23] ^ stk_size[24:31]
#pad to 8 bits
stk_size_xor = bitstring.BitArray(bytes=stk_size_xor.tobytes())
pehash_bin.append(stk_size_xor)

#Heap Commit Size
hp_size = bitstring.BitArray(hex(exe.OPTIONAL_HEADER.SizeOfHeapCommit))
hp_size_bits = string.zfill(hp_size.bin, 32)
#now xor the bits
hp_size = bitstring.BitArray(bin=hp_size_bits)
hp_size_xor = hp_size[8:15] ^ hp_size[16:23] ^ hp_size[24:31]
#pad to 8 bits
hp_size_xor = bitstring.BitArray(bytes=hp_size_xor.tobytes())
pehash_bin.append(hp_size_xor)

#Section chars
for section in exe.sections:
#virutal address
sect_va = bitstring.BitArray(hex(section.VirtualAddress))
sect_va = bitstring.BitArray(bytes=sect_va.tobytes())
pehash_bin.append(sect_va)

#rawsize
sect_rs = bitstring.BitArray(hex(section.SizeOfRawData))
sect_rs = bitstring.BitArray(bytes=sect_rs.tobytes())
sect_rs_bits = string.zfill(sect_rs.bin, 32)
sect_rs = bitstring.BitArray(bin=sect_rs_bits)
sect_rs = bitstring.BitArray(bytes=sect_rs.tobytes())
sect_rs_bits = sect_rs[8:31]
pehash_bin.append(sect_rs_bits)

#section chars
sect_chars = bitstring.BitArray(hex(section.Characteristics))
sect_chars = bitstring.BitArray(bytes=sect_chars.tobytes())
sect_chars_xor = sect_chars[16:23] ^ sect_chars[24:31]
pehash_bin.append(sect_chars_xor)

#entropy calulation
address = section.VirtualAddress
size = section.SizeOfRawData
raw = exe.write()[address+size:]
if size == 0:
kolmog = bitstring.BitArray(float=1, length=32)
pehash_bin.append(kolmog[0:7])
continue
bz2_raw = bz2.compress(raw)
bz2_size = len(bz2_raw)
#k = round(bz2_size / size, 5)
k = bz2_size / size
kolmog = bitstring.BitArray(float=k, length=32)
pehash_bin.append(kolmog[0:7])

m = hashlib.sha1()
m.update(pehash_bin.tobytes())
output = m.hexdigest()
self._add_result('PEhash value', "%s" % output, {'Value': output})

def _scan(self, context):
try:
pe = pefile.PE(data=context.data)
except pefile.PEFormatError as e:
self._error("A PEFormatError occurred: %s" % e)
return
self._get_sections(pe)
self._get_pehash(pe)

if hasattr(pe, 'DIRECTORY_ENTRY_RESOURCE'):
self._dump_resource_data("ROOT", pe.DIRECTORY_ENTRY_RESOURCE, pe)
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ The pehash service requires:

pefile: https://code.google.com/p/pefile/
bitstring: https://pypi.python.org/pypi/bitstring
lxml: https://pypi.python.org/pypi/lxml
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 4565e75

Please sign in to comment.