Skip to content

Commit

Permalink
fix unittests
Browse files Browse the repository at this point in the history
  • Loading branch information
dobin committed Jun 2, 2018
1 parent 9481f3e commit 5513fdc
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 16 deletions.
9 changes: 4 additions & 5 deletions common/corpusdata.py
Expand Up @@ -46,17 +46,16 @@ def createFuzzChild(self, seed):
corpusData._parent = self corpusData._parent = self
corpusData.seed = seed corpusData.seed = seed


corpusData.createNewFilename()
return corpusData return corpusData




def createNewFilename(self): def createNewFilename(self):
self.filename = filenameWithoutExtension(self.filename)
# we are maybe initial corpus (not fuzzed) # we are maybe initial corpus (not fuzzed)
if self.seed and self.networkData.getFuzzMessageIndex(): if self.seed is not None and self.networkData.getFuzzMessageIndex() is not None:
self.filename = filenameWithoutExtension(self.filename)
self.filename += '.' + shortSeed(self.seed) self.filename += '.' + shortSeed(self.seed)
self.filename += '_m' + str(self.networkData.getFuzzMessageIndex()) self.filename += '_m' + str(self.networkData.getFuzzMessageIndex())
self.filename += '.pickle' self.filename += '.pickle'




def getRawData(self): def getRawData(self):
Expand Down Expand Up @@ -84,7 +83,6 @@ def setRawData(self, rawData):




def writeToFile(self): def writeToFile(self):
self.createNewFilename() # update filename with fuzzmsgidx
path = os.path.join(self.basePath, self.filename) path = os.path.join(self.basePath, self.filename)
rawData = self.getRawData() rawData = self.getRawData()
logging.debug("Write corpus to file: " + path) logging.debug("Write corpus to file: " + path)
Expand All @@ -94,6 +92,7 @@ def writeToFile(self):


def readFromFile(self): def readFromFile(self):
filepath = os.path.join(self.basePath, self.filename) filepath = os.path.join(self.basePath, self.filename)
logging.debug("Read corpus from file: " + filepath)
with open(filepath, 'r') as infile: with open(filepath, 'r') as infile:
rawData = pickle.load(infile) rawData = pickle.load(infile)
self.setRawData(rawData) self.setRawData(rawData)
Expand Down
67 changes: 67 additions & 0 deletions mutator/mutator_cmiller.py
@@ -0,0 +1,67 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

# https://github.com/joxeankoret/nightmare/blob/master/mutators/cmiller_mutator.py

"""
Random mutator based on C. Miller 'algorithm' for Nightmare Fuzzing Project.
Pure python implementation compilleable with shedskin.
Created on Sun May 12 10:57:06 2013
@author: joxean
@notes: Can somebody explain to me how the algorithm is any different to
the algorithm used by zzuf? Instead of randomly flipping bits it changes
bytes, right? Anyway, I'll maintain the "cmiller" name...
"""


import sys
import math
import random


class CCMillerMutator(object):

def __init__(self, buf, skip=5):
self.buf = buf
self.skip = 5

def mutate(self):
buf = bytearray(self.buf)
fuzz_factor = 10 # 0.1% of the file
# Original:
numwrites = random.randrange(math.ceil((float(len(buf)) / fuzz_factor)) + 1)

#print "Total of %d" % numwrites
diff = []
for j in range(numwrites):
rbyte = random.randrange(256)
rn = random.randrange(len(buf))
buf[rn] = "%c" % rbyte
diff.append(rn)
return buf, diff


def main(template, output):
mut = CCMillerMutator(open(template, "rb").read())
buf, diff = mut.mutate()

f = open(output, "wb")
f.write(buf)
f.close()

diff.sort()
f = open(output + ".diff", "wb")
f.write("# Original file created by 'CMiller Mutator' was %s\n" % template)
f.write("\n".join(map(str, diff)))
f.close()


def usage():
print "Usage:", sys.argv[0], "<template> <output filename>"


if __name__ == "__main__":
if len(sys.argv) != 3:
usage()
else:
main(sys.argv[1], sys.argv[2])
2 changes: 2 additions & 0 deletions mutator/mutatorinterface.py
Expand Up @@ -139,6 +139,7 @@ def _fuzzFile(self, corpusData, fuzzerData):
fuzzedData = self._readDataFromFile() fuzzedData = self._readDataFromFile()
corpusDataNew.networkData.setFuzzMessageData(fuzzedData) corpusDataNew.networkData.setFuzzMessageData(fuzzedData)
corpusDataNew.fuzzer = fuzzerData['name'] corpusDataNew.fuzzer = fuzzerData['name']
corpusDataNew.createNewFilename() # update filename with fuzzmsgidx/seed


return corpusDataNew return corpusDataNew


Expand All @@ -161,6 +162,7 @@ def _fuzzClass(self, corpusData, fuzzerData):
corpusDataNew = self.fuzzerClassInstances[ fuzzerData['class'] ].fuzz(corpusData) corpusDataNew = self.fuzzerClassInstances[ fuzzerData['class'] ].fuzz(corpusData)
if corpusDataNew is not None: if corpusDataNew is not None:
corpusDataNew.fuzzer = fuzzerData['name'] corpusDataNew.fuzzer = fuzzerData['name']
corpusDataNew.createNewFilename() # update filename with fuzzmsgidx/seed


return corpusDataNew return corpusDataNew


Expand Down
1 change: 1 addition & 0 deletions test/mockupfuzzer.py
Expand Up @@ -20,4 +20,5 @@ def fuzz(self, corpusData):
msg = corpusDataNew.networkData.getFuzzMessageData() msg = corpusDataNew.networkData.getFuzzMessageData()
msg += "A" msg += "A"
corpusDataNew.networkData.setFuzzMessageData(msg) corpusDataNew.networkData.setFuzzMessageData(msg)
corpusDataNew.createNewFilename() # update filename with fuzzmsgidx
return corpusDataNew return corpusDataNew
12 changes: 8 additions & 4 deletions test/test_corpusfile.py
Expand Up @@ -5,12 +5,13 @@
from common.networkdata import NetworkData from common.networkdata import NetworkData
from common.corpusdata import CorpusData from common.corpusdata import CorpusData
from mockupfuzzer import MockupFuzzer from mockupfuzzer import MockupFuzzer
import testutils




class CorpusFileTest(unittest.TestCase): class CorpusFileTest(unittest.TestCase):
def _getConfig(self): def _getConfig(self):
config = { config = {
"input_dir": "/tmp/", "input_dir": "/tmp/ffw-test/in",
} }
return config return config


Expand Down Expand Up @@ -51,8 +52,9 @@ def _getNetworkDataNoCli(self, config):
def test_readwrite(self): def test_readwrite(self):
"""Test if writing+reading file works.""" """Test if writing+reading file works."""
config = self._getConfig() config = self._getConfig()
testutils.prepareFs(config)
networkData = self._getNetworkData(config) networkData = self._getNetworkData(config)
filename = "test" filename = "test.pickle"


corpusData1 = CorpusData(config, filename, networkData) corpusData1 = CorpusData(config, filename, networkData)
corpusData1.writeToFile() corpusData1.writeToFile()
Expand All @@ -67,8 +69,9 @@ def test_readwrite(self):
def test_missingclimsg(self): def test_missingclimsg(self):
"""Test fail-on missing cli message (need one to fuzz).""" """Test fail-on missing cli message (need one to fuzz)."""
config = self._getConfig() config = self._getConfig()
testutils.prepareFs(config)
networkData = self._getNetworkDataNoCli(config) networkData = self._getNetworkDataNoCli(config)
filename = "test" filename = "test.pickle"


corpusData1 = CorpusData(config, filename, networkData) corpusData1 = CorpusData(config, filename, networkData)
corpusData1.writeToFile() corpusData1.writeToFile()
Expand All @@ -80,9 +83,10 @@ def test_missingclimsg(self):
def test_fuzz(self): def test_fuzz(self):
"""Try to fuzz and check if it worked.""" """Try to fuzz and check if it worked."""
config = self._getConfig() config = self._getConfig()
testutils.prepareFs(config)
networkData = self._getNetworkData(config) networkData = self._getNetworkData(config)
fuzzer = MockupFuzzer(config) fuzzer = MockupFuzzer(config)
filename = "test" filename = "test.pickle"


corpusDataParent = CorpusData(config, filename, networkData) corpusDataParent = CorpusData(config, filename, networkData)
corpusDataChild = fuzzer.fuzz(corpusDataParent) corpusDataChild = fuzzer.fuzz(corpusDataParent)
Expand Down
6 changes: 2 additions & 4 deletions test/test_dictionaryfuzzer.py
Expand Up @@ -94,8 +94,8 @@ def test_dictionaryfuzzer(self):
fuzzedCorpusData4.networkData.messages[1]['data'], fuzzedCorpusData4.networkData.messages[1]['data'],
'msg 1 cli test1 test2 test1' 'msg 1 cli test1 test2 test1'
) )
self.assertTrue( self.assertIsNone(
fuzzedCorpusData5 == None fuzzedCorpusData5
) )




Expand All @@ -122,8 +122,6 @@ def test_dictionaryfuzzerWithRadamsa(self):
self.assertEqual(stats['Dictionary'], 4) self.assertEqual(stats['Dictionary'], 4)
self.assertEqual(stats['Radamsa'], 16) self.assertEqual(stats['Radamsa'], 16)


print str(stats)



if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
2 changes: 1 addition & 1 deletion test/test_fuzzer.py
Expand Up @@ -71,7 +71,7 @@ def test_radamsafuzzer(self):
# note that we only have one cli message, which is at index 0 # note that we only have one cli message, which is at index 0
self.assertNotEqual(corpusData.networkData.messages[0]['data'], self.assertNotEqual(corpusData.networkData.messages[0]['data'],
fuzzedCorpusData.networkData.messages[0]['data']) fuzzedCorpusData.networkData.messages[0]['data'])



if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
4 changes: 2 additions & 2 deletions test/test_honggstats.py
Expand Up @@ -10,8 +10,8 @@ def test_honggstats(self):
numThreads = 2 numThreads = 2
honggStats = HonggStats(numThreads) honggStats = HonggStats(numThreads)


stats1 = (0, 10, 2, 1, 2, 2, 33) stats1 = (0, 10, 2, 1, 2, 2, 33, 1, 1)
stats2 = (1, 10, 2, 0, 1, 1, 22) stats2 = (1, 10, 2, 0, 1, 1, 22, 1, 1)


honggStats.addToStats(stats1) honggStats.addToStats(stats1)
honggStats.addToStats(stats2) honggStats.addToStats(stats2)
Expand Down
2 changes: 2 additions & 0 deletions test/test_interceptor.py
Expand Up @@ -25,6 +25,8 @@ def _getConfig(self):
"target_dir": os.path.dirname(os.path.realpath(__file__)), "target_dir": os.path.dirname(os.path.realpath(__file__)),
"target_args": "%(port)i", "target_args": "%(port)i",
"ipproto": "tcp", "ipproto": "tcp",
"recvTimeout": 0.1,
"connectTimeout": 0.2,
} }
return config return config


Expand Down

0 comments on commit 5513fdc

Please sign in to comment.