Skip to content

Instantly share code, notes, and snippets.

@jbhardwaj
Last active December 10, 2015 13:59
Show Gist options
  • Select an option

  • Save jbhardwaj/4444877 to your computer and use it in GitHub Desktop.

Select an option

Save jbhardwaj/4444877 to your computer and use it in GitHub Desktop.
A Cuckoo Sandbox processing module to render an entropy graph of the sample.
<!-- cuckoo/data/html/sections/entrophygraph.html -->
<section id="entropygraph">
<div class="section-title">
<h3>Entropy Graph <small>of the binary.</small></h3>
</div>
{% if results.entropygraph %}
<a href="data:image/png;base64,{{results.entropygraph.data}}"><img class="fade" src="data:image/png;base64,{{results.entropygraph.data}}"/></a>
{% else %}
No entropy graph available.
{% endif %}
</section>
#cuckoo/modules/processing/entropygraph.py
""" Entropy scan
H() and entropy_scan() originally by Ero Carrera (blog.dkbza.org)
Modified May 2007 by cyphunk (deadhacker.com)
Modified Dec 2009 by cyphunk
Modified Dec 2012 by jbhardwaj to run as a Cuckoo Sandbox processor module
"""
from lib.cuckoo.common.abstracts import Processing
# FLAGS
PRINTONTHRESHOLD = 6.8 # When block is > than threshold
# print first 16 bytes in both
# hex and ascii. Set to 0 to turn
# off.
ONLYFIRSTBLOCK = 0 # Set to 1 it will only print the first
# block that goes over threshold and not
# blocks > threshold that are only offset
# by 1. By setting to zero block windows
# that match will be printed.
BLOCKSIZE = 256 # size of blocks scanned.
import math
import random
import matplotlib
matplotlib.use('Agg')
from pylab import *
from matplotlib.ticker import MultipleLocator, FormatStrFormatter
from Tkinter import *
from binascii import hexlify
import string
import os
import StringIO
import base64
import urllib
from static import PortableExecutable
class EntropyGraph(Processing):
def H(self, data):
if not data:
return 0
entropy = 0
cts = {}
for c in data:
if(c in cts):
cts[c]+=1
else:
cts[c]=1
for c in cts:
p_x = float(cts[c])/len(data)
if p_x > 0:
entropy += - p_x*math.log(p_x, 256)
return entropy
def entropy_scan (self, data, block_size) :
# creates blocks of block_size for all possible offsets ('x')
blocks = (data[x : block_size + x] for x in range (len (data) - block_size))
i = 0
for block in (blocks) :
i += 1
yield self.H(block)
# run, print graph
def run(self):
self.key = "entropygraph"
raw = open(self.file_path, 'rb').read()
results = list( self.entropy_scan(raw,BLOCKSIZE) )
# Print blocks that are above a defined threshold of entropy
if PRINTONTHRESHOLD > 0:
found = 0
for i in range(len(results)):
if results[i] > PRINTONTHRESHOLD:
if found == 0:
table = string.maketrans("rnt", ' ') # don't like newlines
found = ONLYFIRSTBLOCK
else:
found = 0
# Plot
filesize = os.path.getsize(self.file_path)
imgdpi = 100
imgwidth = 10 #imgwidth = filesize / imgdpi
#majorLocator = MultipleLocator(0x400) # mark every 1024 bytes
majorLocator = MultipleLocator(filesize/20)
majorFormatter = FormatStrFormatter('0x%X') # change to %d to see decimal offsets
ioff()
ax = subplot(111)
plot(results, linewidth=2.0, antialiased=False)
subplots_adjust(left=0.02, right=0.99, bottom=0.2)
ax.axis([0,filesize,0,1])
ax.xaxis.set_major_locator(majorLocator)
ax.xaxis.set_major_formatter(majorFormatter)
xticks(rotation=315)
xlabel('block (byte offset)')
ylabel('entropy')
title('Entropy levels')
grid(True)
img = gcf()
img.set_size_inches(imgwidth, 6)
data = {}
imgfile = StringIO.StringIO()
img.savefig(imgfile, dpi=imgdpi)
imgfile.seek(0)
data['data'] = base64.b64encode(imgfile.buf)
imgfile.close()
return data
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment