public 0.5.2 release :)

This commit is contained in:
dash
2019-05-13 16:57:27 +02:00
parent 55f10eac19
commit d9a4209bcd
13 changed files with 1729 additions and 1 deletions

View File

@@ -6,7 +6,7 @@ This code is for automated analysis of files you may find around the internet. P
The original version had been built in 2007. In the last weeks, i had started to fix a lot of code, add features or clean some parts up. The original version had been built in 2007. In the last weeks, i had started to fix a lot of code, add features or clean some parts up.
FirmwareFudger is far from what it's goal is, but it is already handy :) FirmwareFudger is far from what it's in my head, but it is already handy :)
## How to use the tool: ## How to use the tool:

24
ReleaseNotes_0.5.2.txt Normal file
View File

@@ -0,0 +1,24 @@
Release Notes 0.5.2
===================
After quite some time, i decided to spend some dedication to this old tool i had written. There
lies over a decade between v0.3 and the current version 0.5.2.
Improvements:
* FF has been ported to python3
* speed, 0.3 had a naive approach of parsing files, with a lot of extra requests,
this had been changed, the speed improovements are over 300 times, so analysis of a firmware
currently takes some seconds
* bugs been fixed, one long term bug, was the always wrong suffix of a file type, this is
normally no problem, however tools like gzip do not like it if .gz is missing, so i fixed
the issue
* code cleanups and refactory, had been done a lot, and there is still a lot to add
* using argparse over getopt, as argparse is simply the better and more supportive alternative
* there is an experimental method called strings, while the normal version is known to
everyone, this version also does an analysis to dig up some more information about the file
more code and explanations will come
* FF is now working with threads, which has some extra time improvements during analysis
* FF is now using Queues at several stages

261
ffudger.py Executable file
View File

@@ -0,0 +1,261 @@
#!/usr/bin/env python3
#
# by dash in 2019
############################
import os
import sys
import argparse
import threading
from lib.FUDGEanalyse import *
from lib.FUDGEheader import *
#maybe put that later somewhere else
extractit=0
fileReport=0
def fudge_banner():
ff=ANALYSE()
print ("[+] FirmareFudger %s by dash" % ff.__version__)
print ("[+] tool for firmware analyses, May 2019")
print ("[+] ")
print ("[+] contact: d4shmail@gmail.com")
print
ff=[]
def ff_fudge_routine(ff):
''' the classic ffudger routine
patched and fixed up a bit :)
'''
#print the banner :D
#fudge_banner()
# print some basic information
ff.printargs()
true=0
# check if only one plugin shall be tested
if ff.lonelyplugin!=None:
lonely=ff.lonelyplugin
for category in FUDGEheader.TYPES.keys():
for plugin in FUDGEheader.TYPES[category].keys():
if ff.lonelyplugin == FUDGEheader.TYPES[category][plugin][FUDGEheader.NAME]:
print ('[+] Analyzing for %s' % ff.lonelyplugin)
# checkheader etc.pp.
ff.fftype=lonely
# fill the targetqueue
ff.ff_fill_targetqueue(category,plugin)
# run the check routine
ff.checkheader()
# check if only a group shall be tested
elif ff.ff_cat!=None:
if ff.ff_cat in FUDGEheader.TYPES_DEF:
#print (ff.ff_cat)
category=FUDGEheader.TYPES_DEF[ff.ff_cat]
#only check for the asked TYPE
print ("[+] Testing only for %s plugins" % (ff.ff_cat))
for plugin in range(len(TYPES[category])):
# fill the targetqueue
ff.ff_fill_targetqueue(category,plugin)
# check the file
ff.checkheader()
else:
print ("[-] Unkown plugin class %s !" % ff.plugin)
sys.exit(1)
# if not one_plugin is choosen and also not the ff_cat
# we do check for all FF plugins
elif ff.ff_cat == None and ff.lonelyplugin==None:
print ('[+] Checking for all FF plugins')
#check for all TYPES
for category in range(len(TYPES)):
#print (len(TYPES))
#print (TYPES[category])
for plugin in range(len(TYPES[category])):
#print (len(TYPES[testtype]))
# set the fftype
ff.fftype=TYPES[category][plugin][3]
# fill the targetqueue
ff.ff_fill_targetqueue(category,plugin)
# call the check_routine
#ff_check_routine(ff)
ff.checkheader()
# ok, something went wrong
else:
# was not able to find the named plugin
print ('[-] Sorry, something went wrong.\n[?] Execute tool with -Fl to see a complete fudger plugin list.')
return 1;
# If a report needs to be created, create it now
#generateFilereport(ff)
#print (ff.result_queue.qsize())
# hm, should work :>
while True:
if len(ff.thread_list)>0:
# print ('[.] Waiting for threads to finish %d' % (len(ff.thread_list)))
time.sleep (0.1);
for entry in ff.thread_list:
if (entry.isAlive())==False:
entry.join()
ff.thread_list.remove(entry)
else:
break
# If extract data has been choosen, extract it now
ff.extractdata()
# do strings analysis
if ff.str_analysis:
ff.strings_search()
return 0;
def run(args):
''' main run function, let the fun begin'''
# instanciate FUDGEanalysis Class
ff=ANALYSE()
# Preparations before we can analyse a file
# set threads if given
if args.threads:
ff.thread_cnt=args.threads
# show FirmwareFudgers Plugin Database, and return
if args.fudgelist:
ff.showplugins()
return 0;
# show FirmwareFudgers Plugin Database, and return
#print (args.fudgelist_cat)
if args.fudgelist_cat:
ff.showplugins(cat=args.fudgelist_cat)
return 0;
# set the file to analyse
if args.infile:
ff.infile=args.infile
# set the prefix for every extracted file
# default: FF-Extract
if args.outprefix:
ff.outprefix=args.outprefix
# set the output directory
if args.outdir:
ff.outdir=args.outdir
# check if directory exists, if not create it
# if an error comes along, we abort the complete operation
if not ff.create_dir():
print ('[-] Abort.')
# create a report
if args.create_report:
ff.create_report=args.create_report
# use only one specific plugin
ff.lonelyplugin=args.lonelyplugin
# use only specific plugin group
ff.ff_cat=args.ff_cat
# set extract to true
if args.extract:
ff.extract=True
ff.create_dir()
# set verbose mode
if args.verbose:
ff.verbose=True
# set debug mode
if args.debug:
ff.debug=True
# show version
#print (args.version)
if args.version==True:
fudge_banner()
return 0;
# add flag if strings analysis is wanted
if args.strings == True:
ff.str_analysis=True
ff.str_minlen=args.str_minlen
ff.str_filter=args.str_filter
# try to open our target file
if ff.openfile()==-1:
sys.exit(1)
# use ff method
if args.fudge:
ff_fudge_routine(ff)
def main():
''' yay, we got a main :)'''
ff=ANALYSE()
__tool__ = ff.__tool__
__version__ = ff.__version__
__author__ = ff.__author__
__date__ = ff.__date__
parser_desc = 'FirmwareFudger, written to do better firmware analysis'
prog_desc = __tool__ + ' v' + __version__ + ' by ' + __author__ + ' (' + __date__ + ')'
parser = argparse.ArgumentParser(prog = prog_desc, description=parser_desc)
parser.add_argument('-f','--input-file',action="store",dest='infile',required=False,help='define the file to analyze')
parser.add_argument('-o','--outdir',action="store",dest='outdir',required=False,help='define the directory to save extracted files and logs to')
parser.add_argument('-O','--output-prefix',action="store",dest='outprefix',required=False,help='define the prefix for the extracted name (default: FF-Extract)')
parser.add_argument('-x','--extract',action="store_true",dest='extract',required=False,help='flag if you want to extract found files', default=False)
parser.add_argument('-F','--fudge',action="store_true",dest='fudge',required=False,help='use fudge mode (FirmwareFudgers own database)',default=True)
parser.add_argument('-S','--strings',action="store_true",dest='strings',required=False,help='run strings on file and conduct analysis',default=False)
parser.add_argument('-Sl','--strings-len',action="store",dest='str_minlen',required=False,help='the minimum length for string check',default=4, type=int)
parser.add_argument('-Sf','--strings-filter',action="store",dest='str_filter',required=False,help='the strings check filter, use regular expressions',default="([a-zA-Z0-9 \.\-]{7,})")
parser.add_argument('-M','--magic',action="store_true",dest='magic',required=False,help='use magic mode (libmagic database)',default=True)
parser.add_argument('-Fp','--fudge-plugin',action="store",dest='lonelyplugin',required=False,help='run only one specified plugin test',default=None)
parser.add_argument('-Fc','--fudge-category',action="store",dest='ff_cat',required=False,help='run only a section of possible plugins (e.g. EXEC)',default=None)
parser.add_argument('-Fl','--fudge-list',action="store_true",dest='fudgelist',required=False,help='show plugins of FirmwareFudger',default=False)
parser.add_argument('-Flc','--fudge-list-cat',action="store",dest='fudgelist_cat',required=False,help='show plugins of defined group',default=False)
parser.add_argument('--threads',action="store",dest='threads',required=False,help='define the value of maximum threads used, default is 20',default=None,type=int)
parser.add_argument('-v','--verbose',action="store_true",dest='verbose',required=False,help='run in verbose mode',default=False)
parser.add_argument('--debug',action="store_true",dest='debug',required=False,help='run in debug mode',default=False)
parser.add_argument('-r','--report',action="store_true",dest='create_report',required=False,help='create a report for the session',default=False)
parser.add_argument('-V','--version',action="store_true",dest='version',required=False,help='show version and tool information',default=False)
args = parser.parse_args()
# if no argument is given help is printed
if len(sys.argv)<2:
parser.print_help()
sys.exit(1)
run(args)
if __name__ == "__main__":
main()

596
lib/FUDGEanalyse.py Executable file
View File

@@ -0,0 +1,596 @@
import re
import os
import sys
import queue
import time
import struct
import binascii
import threading
import lib.FUDGEheader as FUDGEheader
from lib.FUDGEheader import TYPES
nor=0x1
ver=0x2
dbg=0x3
def dbgprint():
print ("nothing")
class ANALYSE(object):
def __init__(self):
"""
infile - the file to analyse
stat - os.stat results of self.infile
fftype - the current type of pattern test
plugin - choosen pluginclass to test for
lonelyplugin- choosen lonely plugin for test
fd - the filedescriptor of open and close
search - the search string/bytes
string - for convert2hex
data - the binary data field, where the bytes are filled in
offset - the offset delivered back for writing to self.cut
extract_cnt - number of the found files in file
extract - shall we extract anything?
cut - dict for offsets for the extractfile method
outdir - output directory for putting files
outname - name of the output files part
reportfile - name of the status report
files - list with paths of extracted files
"""
# not in use yet
# self.threads = [] # list of overall threads
# self.thread_cnt = 20 # amount of threads
# erm, check what those are used for :>
self.string=""
self.data=[]
# ff magic search variables
# FIXME must get cleaned up
self.target_queue=queue.Queue() # all plugins to test
self.result_queue=queue.Queue() # all results from the test
self.offset=0 # offset for self.cut, does not need to be global
self.cut={} # this will be replaced with result_queue
self.set_offset=0 # ??
self.set_string=0 # ??
self.length=0 # does not need to be global, can also migrate to local
# category and plugin variables
# what a MESS, this *must* get cleaned up
# FIXME
self.fftype=None # type of the pattern test, see header files
self.ff_cat=None # category to test for
self.plugin=None # pluginclass to test for
self.lonelyplugin=None # one plugin test only, named lonely plugin
self.search=None
# threading variables
self.thread_cnt=20 # default value of concurrent threads is 20
self.thread_alive=0 # variable for actually running threads
self.thread_list=[] # list for all active threads, not active gets removed
# file variables
self.fd=None # filedescriptor of target file
self.instat=None # results of os.stat against infile
self.infile=None # the file to analyze
# output variables
self.outdir=None # output directory
self.outprefix="FF-Extract" # prefix of every file written to output directory
# reporting variables
self.report=False # generate report if variable is True
self.reportname=None # name of the status report file
self.reportfiles=[] # list of files extracted files, for reporting
# logging options
self.debug=False
self.verbose=False
# extraction variables
self.extract=False # extract found files if variable is True
self.extract_cnt=0 # number of files found
# variables for strings search mechanism
self.str_analysis=False
self.str_minlen=4
self.str_filter="([a-zA-Z0-9 \.\-]{"+str(self.str_minlen)+",})"
self.str_resdict={}
self.str_anadict={}
# misc tool variables
self.__author__="dash"
self.__version__="0.5.2"
self.__tool__="FirmwareFudger"
self.__date__="May of 2019"
def privileges(self):
if self.stat.st_uid != os.getuid():
print ("[!] Attention file owner is %d" % self.stat.st_uid)
return False;
else:
return True;
def ffprint(self,data,level):
''' printing wrapper for:
* normal
* verbose
* debug
output
'''
if self.verbose==True and level==ver:
print (data)
elif self.debug==True and level==dbg:
print (data)
elif level==nor:
print (data)
return 0;
def printargs(self):
''' output information about the file
'''
size=self.instat.st_size
Kilo=1024.0
Mega=1048576.0
print ("[+] Fudger Version %s - Fileinformation" % self.__version__)
print ("[+] Filename %s" % self.infile)
if size<=Mega:
sizeK=size/Kilo
print ("[+] Size %.2fK - %dB" % (sizeK,size))
elif size>=Mega:
sizeM=size/Mega
sizeK=size/Kilo
print ("[+] Size %.2fM - %.2fK - %dB" % (sizeM,sizeK,size))
else:
print ("[+] Size %d" % size)
print ("[+] User %d" % self.instat.st_uid)
print ("[+] Group %d" % self.instat.st_gid)
#print "[+] Search for %s" % self.search
def openfile_fd(self):
''' simple open file operation and return fd
'''
try:
self.instat=os.stat(self.infile)
#print ("[+] Open %s" % (self.infile))
fd=open(self.infile,"rb")
except PermissionError as e:
print ('[-]',e)
return -1
except IsADirectoryError as e:
print ('[-]',e)
return -1
except FileNotFoundError as e:
print ('[-]',e)
return -1
return fd;
def openfile(self):
''' simple open file operation
'''
try:
self.instat=os.stat(self.infile)
print ("[+] Open %s" % (self.infile))
self.fd=open(self.infile,"rb")
except PermissionError as e:
print ('[-]',e)
return -1
except IsADirectoryError as e:
print ('[-]',e)
return -1
except FileNotFoundError as e:
print ('[-]',e)
return -1
def closefile(self):
''' simple closefile operaiton'''
print ("[+] Close %s" % self.infile)
self.fd.close()
def create_dir(self):
''' method for checking outdir and properties
and order creation
'''
if self.outdir != None:
try:
result=os.stat(self.outdir)
return 0;
except FileNotFoundError as e:
self.__create_dir()
elif self.outdir==None and self.extract==True:
# self.outdir is not specified, but it has been asked to extract data
# let us generate a directory for that usecase
dirname = self.infile.replace('/','_')
dirname = dirname.replace('..','_')
dirname = dirname.replace('.','_')
dirname = dirname.replace('!','_')
dirname = dirname.replace('-','_')
dirname = dirname.lower()
self.outdir=dirname
try:
result=os.stat(self.outdir)
return 0;
except FileNotFoundError as e:
self.__create_dir()
return 0;
def __create_dir(self):
''' this function tests if the output directory does exist, if not a new
one is created. if the name exists but it is not a directory
an error is thrown and the process is aborted.
'''
try:
print ("[+] Creating directory %s" % (self.outdir))
os.mkdir(self.outdir)
return(0)
except OSError as e:
print ("[-] Error %d %s" % (e.args[0], e.args[1]))
return(1)
def convert2array(self):
for byte in range(len(self.string)):
print ("\'%c\'," % self.string[byte],)
def ff_fill_targetqueue(self,category,plugin):
''' here starts the calls for the magic behind the scenes
category and plugin type are delivered and the target queue is build up
self.target_queue - consists of all information necessary for finding magic and
later extraction
'''
# print (TYPES[testtype][plugin])
header1=TYPES[category][plugin][1]
header2=TYPES[category][plugin][2]
name=TYPES[category][plugin][3]
desc=TYPES[category][plugin][4]
suffix=TYPES[category][plugin][5]
# now fill up the target queue
self.target_queue.put({ 'category':category,\
'plugin':plugin,\
'Header1':header1,\
'Header2':header2,\
'name':name,\
'desc':desc,\
'suffix':suffix})
#print (self.target_queue.qsize())
return 0;
def __checkheader(self,target):
''' new version of checkheader, that time with impressive speed
as a simpler search algorithm is used and an awesome class: re
and not working :(
'''
fd=self.openfile_fd()
#print ('[d] __checkheader')
header1=target['Header1']
category=target['category']
plugin=target['plugin']
suffix=target['suffix']
name=target['name']
hh=''
cut={}
# due a not sooo good design of ff database this has to be done
# obviously ff database needs a redesign :)
for i in header1:
hh = hh+i
# lets create our re pattern
hh = re.escape(hh)
hh=bytes(hh,'latin-1')
re_comp=re.compile(hh)
#print ('[v] Checking %s' % target['name'])
#print ('[d] Header1:',header1)
#print ('[d] HH:',hh)
for match in re.finditer(re_comp, fd.read()):
#print('match', match.span())
#print('match.group',match.group())
offstart, offend = match.span()
print ("[+] FOUND %s at Offset %d to %d" % (target['name'],offstart,offend))
#print(match.span(), match.group())
dataend=self.instat.st_size
cut={'offstart':offstart,'offend':offend,'dataend':dataend,'category':category,'plugin':plugin,'suffix':suffix}
#print ('checkheader:',cut)
self.result_queue.put(cut)
# self.str_resdict[match.span()]=match.group()
cut={}
self.extract_cnt+=1
fd.close()
def checkheader(self):
''' threaded checkheader wrapper
'''
while self.target_queue.qsize()>0:
# set current thread count
self.thread_alive=len(self.thread_list)
# check if we have crossed the limit of maximum threads
if self.thread_alive<self.thread_cnt:
# get a value from the target queue
target=self.target_queue.get()
# set variables for the thread, make it daemon and start it
thrd = threading.Thread(target=self.__checkheader,args=(target,))
thrd.daemon=True
thrd.start()
# add the thread to our list
self.thread_list.append(thrd)
#print ('thrd cnt: %d' % len(self.thread_list))
# this part watches that dead threads can join and it is removed from the list
for entry in self.thread_list:
if entry.isAlive()==False:
entry.join()
self.thread_list.remove(entry)
def seekinto(self):
allbytes=""
self.fd=open(self.infile,"rb")
self.fd.seek(0,0)
self.fd.seek(self.set_offset,0)
for byte in self.fd.read(self.length):
byte=binascii.hexlify(byte)
allbytes=allbytes + "\\x"+byte
print ("%s" % allbytes,)
def manglefile(self):
mangle_file=open(self.infile,"r")
for part in range(self.extract):
mangle_file.seek(0,0)
mangle_file.seek(self.cut[part],0)
readbytes=mangle_file.read(8)
print ("read %s " % readbytes)
mangle_file.close()
mangle_file=open(self.infile,"r+")
mangle_file.seek(0,0)
mangle_file.seek(self.cut[part],0)
mangle_file.write(self.set_string)
mangle_file.close()
def extractcount(self):
''' let's print some information about the files to extract
'''
print ("[+] Found %d possible types" % (self.extract_cnt))
return 0;
def extractdata(self):
''' simple wrapper function, which gets called by program
'''
# ram some info
self.extractcount()
# lets go to file extraction
self.extractfile()
return 0;
def extractfile(self):
""" its working just need some cleanups, and small fixes """
if self.extract_cnt == 0:
self.ffprint('[-] Sorry, nothing to extract. Counter is zer0.',nor)
return -1;
if self.extract==False:
return -1
exo_file=open(self.infile,"rb")
# as long as we have results in the queue
while self.result_queue.qsize()>0:
# place result in target variable
target = self.result_queue.get()
#cut[self.extract_cnt]=(offstart,offend,dataend,category,plugin,suffix)
# print (target)
# print (len(target))
offstart=target['offstart']
suffix=target['suffix']
if suffix==None:
suffix=''
# go to start of file
exo_file.seek(0,0)
exo_file.seek(offstart,0)
#print (self.cut)
#print (self.cut[part])
FILENAME=self.outdir+"/"+self.outprefix+"-"+str(self.extract)+"-"+str(offstart)+"." + suffix
print ("[+] FILENAME: %s" % FILENAME)
try:
exw_file=open(FILENAME,"wb")
except PermissionError as e:
print ('[-] ',e)
return -1;
# data to write to the extracted file
# please note that currently the end of the
# original file is the end - for reasons ;)
TOWRITE=(self.instat.st_size)-offstart
# depending on the file size this might get problematic
buf = exo_file.read()
exw_file.write(buf)
# close the file
exw_file.close()
#lets add it to files if reportfile shall be written
self.reportfiles.append(FILENAME)
def generateReport(self):
print ("[+] Found %d extracted files" % len(self.files))
print
print ("file Report")
print ("="*11)
for extracted in self.files:
#print "[+] %s " % extracted
os.spawnl(os.P_WAIT,"/usr/bin/file","file",extracted)
def __print_categories(self):
''' sub-method for printing all categories
'''
print ('[+] Categories')
for cat in FUDGEheader.TYPES_DEF:
print ('\t%s' % cat)
return 0;
def showplugins(self,cat=None):
""" all plugins currently supported by FF own database
"""
i=0
if cat!=None:
if cat in FUDGEheader.TYPES_DEF:
print ("[+] Plugins:")
# print ('[v] FOUND %s' % cat)
catid = FUDGEheader.TYPES_DEF[cat]
print ("[+] %s:" % cat)
for plugin in range(len(FUDGEheader.TYPES[catid])):
print ("\t\t- %s - %s" % (FUDGEheader.TYPES[catid][plugin][FUDGEheader.NAME],FUDGEheader.TYPES[catid][plugin][FUDGEheader.DESC]))
i+=1
else:
print ('[-] Category "%s" does not exist' % cat);
self.__print_categories()
return -1;
# show all plugins supported
else:
for fftype in range(len(FUDGEheader.TYPES)):
if fftype==0:
stringtype="FS"
elif fftype==1:
stringtype="EXEC"
elif fftype==2:
stringtype="PACKERS"
elif fftype==3:
stringtype="DOCS"
elif fftype==4:
stringtype="BOOT"
elif fftype==5:
stringtype="ASM"
elif fftype==6:
stringtype="PICTURES"
elif fftype==7:
stringtype="DEVICES"
elif fftype==8:
stringtype="CRYPTO"
# elif fftype==9:
# stringtype="CRYPTO"
print ("%s:" % stringtype)
for plugin in range(len(FUDGEheader.TYPES[fftype])):
print ("\t\t- %s - %s" % (FUDGEheader.TYPES[fftype][plugin][FUDGEheader.NAME],FUDGEheader.TYPES[fftype][plugin][FUDGEheader.DESC]))
i+=1
print ("\n[+] Found %d plugins." % i)
print ("[+] Done")
#####################################
# #
# strings analysis section #
# #
#####################################
def strings_analysis(self):
''' method for analysing and giving hints to the analyst
self.str_resdict, the result dictionary of self.string_search method
self.str_anadict, the reuslt dictionary for self.string_analysis method
'''
ana = open('supply/strings.txt','r')
# read strings supply file
for line in ana.readlines():
# is it a comment, no? then proceed
if not line.startswith('#'):
a = line.split(';')
needle=a[0]
desc=a[1]
tools=a[2]
for k in self.str_resdict.keys():
if self.str_resdict[k].find(needle)!=-1:
self.str_anadict[needle]=(needle,desc,tools)
print ('[+] %s - %s - %s' % (needle,desc,tools))
print ('[+] Found %d interesting string(s) during analysis.' % len(self.str_anadict))
ana.close()
return 0;
def strings_output(self):
''' method for writing results of strings search
self.str_resdict, the result dictionary of self.string_search method
'''
return 0;
def strings_search(self):
''' this method does the work of the unix userland tool "strings"
it searches a binary for possible strings, for later manual
analysis. in this particular case an automatic analysis is added
as well to hint the analyst on something interesting found
self.str_minlen, the default is 4
self.str_filter, the regular expression filter
self.str_resdict, the result dictionary with string, start/end position
'''
# variables for strings search mechanism
self.openfile()
# print (re.findall(re_filter, str(self.fd.read())))
for match in re.finditer(self.str_filter, str(self.fd.read())):
#print('match', match.span())
#print('match.group',match.group())
# print(match.span(), match.group())
self.str_resdict[match.span()]=match.group()
# place this somewhere else later
self.strings_analysis()

BIN
lib/FUDGEanalyse.pyc Normal file

Binary file not shown.

813
lib/FUDGEheader.py Executable file
View File

@@ -0,0 +1,813 @@
#complete list
TYPES = 0x00
#categories
FS = 0x00
EXEC = 0x01
PACKERS = 0x02
DOCS = 0x03
BOOT = 0x04
ASM = 0x05
PICTURES = 0x06
DEVICES = 0x07
#ROUTERS = 0x08
CRYPTO = 0x08
#Filesystem Type Definitions
MSDOS = 0x00
CRAMFS1 = 0x01
CRAMFS2 = 0x02 #difference is another searchstring
ROM1FS = 0x03
SQUASHFS1 = 0x04 #difference is another searchstring
SQUASHFS2 = 0x05
FAT32 = 0x06
CDUNIX = 0x07
ADF = 0x08
SGI = 0x09
SGIXFS = 0x0a
ST40 = 0x0b
CBM = 0x0c
WINIMAGE = 0x0d
COB = 0x0e
UFS1 = 0x0f
QEMU1 = 0x10
JFFSL = 0x11
JFFSB = 0x12
JFFS2L = 0x13
JFFS2B = 0x14
FAT12 = 0x15
FAT16 = 0x16
#Executeable File Definitions
ELF = 0x00
BFLT = 0x01
PE = 0x02
MSDOSCOM = 0x03
DOSCOM = 0x04
SPSSPORTABLE= 0x05
SPSSSYSTEM = 0x06
PPCPEF = 0x07
#Packing Specific definitions
ZIP1 = 0x00
ZIP2 = 0x01
BZIP = 0x02
GZIP = 0x03
ACE = 0x04
TAR = 0x05
TRX1 = 0x06
TRX2 = 0x07
LZMA = 0x08
UPX = 0x09
GNUTAR = 0x0A
CRUSH = 0x0B
HLSQZ = 0x0B
SQWEZ = 0x0C
HPAK = 0x0D
LZOP = 0x0E
MDCD = 0x0F
MSCOMPRESS = 0x10
INSTALLSHIELD = 0x11
PAQ = 0x12
JARARJ = 0x13
STUFFIT = 0x14
VAX3 = 0x15
VAX5 = 0x16
ARCHIVE = 0x17
ARCHIVEFILE = 0x18
HRB = 0x19
RISCOS = 0x1a
HAP = 0x1b
LIM = 0x1c
FREEZE = 0x1d
ZOO = 0x1e
RAR = 0x1f
EET = 0x20
RZIP = 0x21
SQSH = 0x22
ISC = 0x23
NWFILE = 0x24
DSIGDCC = 0x25
ARJ = 0x26
#Document Fileformats
PDF = 0x00
DOC = 0x01
RTF = 0x02
#Bootloader Definitions
UBOOT = 0x00
#Assembler object codes
AVR = 0x00
#Image Files(pictures etc.)
GIMPXCF = 0x00
#Devices Specific Firmware characteristics
LTRX1 = 0x00
LTRX2 = 0x01
WGR614BOOT = 0x02
WGR614 = 0x03
#Router Specific Firmware characteristics specifications
#Crypto stuff, certificates, keys, typical indications of crypto
DSAPRIV = 0x00 #-----BEGIN DSA PRIVATE KEY----- -----END DSA PRIVATE KEY-----
RSAPRIV = 0x01 #-----BEGIN RSA PRIVATE KEY----- -----END RSA PRIVATE KEY-----
SSHPUB = 0x02 # ssh-dss
CACERT = 0x03 #-----BEGIN CERTIFICATE----- -----END CERTIFICATE-----
CERTREQ = 0x04 #-----BEGIN CERTIFICATE REQUEST----- -----END CERTIFICATE REQUEST-----
PGPMSG = 0x05 #-----BEGIN PGP MESSAGE----- -----END PGP MESSAGE-----
#Header definitions
HEADER1 = 0x01 #start header
HEADER2 = 0x02 #stop trailer/header
NAME = 0x03 #the format name
DESC = 0x04 #teh description
SUFFIX = 0x05 #the ending of the file, some tools want to have a proper ending, gzip for instance
CHANCE = 0x06 #chance calculator, if at least "chance" bytes are correct print out possibility...
TOOLS = 0x07 #tools of trade to work with that kind of files
#Filesystem Specifications
#
#still much too add
###########################################
TYPES = { FS: { \
MSDOS:{ \
HEADER1: ('M','Z','H','H'),\
HEADER2: None,\
NAME: 'MSDOS',\
DESC: "MSDOS - Filesystem",\
SUFFIX: 'img',\
CHANCE: 2},
CRAMFS1:{ \
HEADER1: ('\x45','\x3d','\xcd','\x28'),\
HEADER2: None,\
NAME: 'CRAMFS1',\
DESC: "CRAMFS - Compressed ROMFS",\
SUFFIX: 'img',\
CHANCE: 2},
CRAMFS2:{ \
HEADER1: ('C','o','m','p','r','e','s','s','e','d','\x20','R','O','M','F','S'),\
HEADER2: None,\
NAME: 'CRAMFS2',\
DESC: "CRAMFS2 - Compressed ROMFS",\
SUFFIX: 'img',\
CHANCE: 8},
ROM1FS:{ \
HEADER1: ('-','r','o','m','1','f','s'),\
HEADER2: None,\
NAME: 'ROM1FS',\
DESC: "ROM1FS - ROM FILE SYSTEM",\
SUFFIX: 'img',\
CHANCE: 3},
SQUASHFS1:{ \
HEADER1: ('h','s','q','s'),\
HEADER2: None,\
NAME: 'SQUASHFS',\
DESC: "SQUASHFS - Big Endian",\
SUFFIX: 'img',\
CHANCE: 2},
SQUASHFS2:{ \
HEADER1: ('s','q','s','h'),\
HEADER2: None,\
NAME: 'SQUASHFS2',\
DESC: "SQUASHFS - Little Endian",\
SUFFIX: 'img',\
CHANCE: 2},
FAT32:{ \
HEADER1: ('\x46','\x41','\x54','\x33','\x32'),\
HEADER2: None,\
NAME: 'FAT32',\
DESC: "FAT32 - Filessystem",\
SUFFIX: 'img',\
CHANCE: 2},
FAT12:{ \
HEADER1: ('\x46','\x41','\x54','\x31','\x32'),\
HEADER2: None,\
DESC: "FAT12 - Filessystem",\
NAME: 'FAT12',\
SUFFIX: 'img',\
CHANCE: 2},
FAT16:{ \
HEADER1: ('\x46','\x41','\x54','\x31','\x36'),\
HEADER2: None,\
NAME: 'FAT16',\
DESC: "FAT16 - Filessystem",\
SUFFIX: 'img',\
CHANCE: 2},
CDUNIX:{ \
HEADER1: ('\x01','\x43','\x44','\x30','\x30','\x31','\x01'),\
HEADER2: None,\
NAME: 'CDUNIX',\
DESC: "CDUNIX - Filessystem",\
SUFFIX: 'img',\
CHANCE: 2},
ADF:{ \
HEADER1: ('D','O','S','\x00'),\
HEADER2: None,\
NAME: 'ADF',\
DESC: "ADF - Amiga Filessystem",\
SUFFIX: 'img',\
CHANCE: 2},
SGI:{ \
HEADER1: ('\x0B','\xE5','\xA9','\x41'),\
HEADER2: None,\
NAME: 'SGI',\
DESC: "SGI - SGI disk label (volume header)",\
SUFFIX: 'img',\
CHANCE: 2},
SGIXFS:{ \
HEADER1: ('\x58','\x46','\x53','\x42'),\
HEADER2: None,\
NAME: 'SGIXFS',\
DESC: "SGI XFS - filesystem data",\
SUFFIX: 'img',\
CHANCE: 2},
ST40:{ \
HEADER1: ('\x13','\xa9','\xf1','\x7e'),\
HEADER2: None,\
NAME: 'ST40',\
DESC: "ST40 - component image format",\
SUFFIX: 'img',\
CHANCE: 2},
CBM:{ \
HEADER1: ('C','B','M'),\
HEADER2: None,\
NAME: 'POWER64',\
DESC: "Power 64 - C64 Emulator Snapshot",\
SUFFIX: 'img',\
CHANCE: 2},
WINIMAGE:{ \
HEADER1: ('W','I','N','I','M','A','G','E'),\
HEADER2: None,\
NAME: 'WinImage',\
DESC: "WinImage - WinImage Archive data",\
SUFFIX: 'img',\
CHANCE: 2},
COB:{ \
HEADER1: ('C','o','B','1'),\
HEADER2: None,\
NAME: 'COB1',\
DESC: "CoB1 - lantronix html/webserver filesystem",\
SUFFIX: 'img',\
CHANCE: 2},
UFS1:{ \
HEADER1: ('\x00','\x01','\x19','\x54'),\
HEADER2: None,\
NAME: 'UFS1',\
DESC: "UFS1 - Unix Fast File system [v1] (little-endian)",\
SUFFIX: 'img',\
CHANCE: 2},
QEMU1:{ \
HEADER1: ('\x51','\x46','\x49','\xfb'),\
HEADER2: None,\
NAME: 'QEMU1',\
DESC: "QEMU1 - Qemu Image, Format: Qcow",\
SUFFIX: 'img',\
CHANCE: 2},
JFFSL:{ \
HEADER1: ('\x31','\x39','\x38','\x34'),\
HEADER2: None,\
NAME: 'JFFS1_LE',\
DESC: "JFFS1 - version 1, little endian",\
TOOLS: "mtd-tools, mkfs.jffs etc.",\
SUFFIX: 'img',\
CHANCE: 2},
JFFSB:{ \
HEADER1: ('\x34','\x38','\x39','\x31'),\
HEADER2: None,\
NAME: 'JFFS1_BE',\
DESC: "JFFS1 - version 1, big endian",\
SUFFIX: 'img',\
TOOLS: "mtd-tools, mkfs.jffs etc.",\
CHANCE: 2},
JFFS2L:{ \
HEADER1: ('\x85','\x19','\x03','\x20'),\
HEADER2: None,\
NAME: 'JFFS2_LE',\
DESC: "JFFS2 - version 2, little endian",\
SUFFIX: 'img',\
TOOLS: "mtd-tools, mkfs.jffs etc.",\
CHANCE: 2},
JFFS2B:{ \
HEADER1: ('\x19','\x85','\x20','\x03'),\
HEADER2: None,\
NAME: 'JFFS2_BE',\
DESC: "JFFS2 - version 2, big endian",\
SUFFIX: 'img',\
TOOLS: "mtd-tools, mkfs.jffs etc.",\
CHANCE: 2}
},
EXEC: {
ELF:{ \
HEADER1: ('\x7f','E','L','F'),\
HEADER2: None,\
NAME: 'ELF',\
DESC: "ELF - File Format",\
SUFFIX: 'elf',\
CHANCE: 2},
BFLT:{ \
HEADER1: ('b','F','L','T'),\
HEADER2: None,\
NAME: 'BFLT',\
DESC: "bFLT - File Format",\
SUFFIX: 'bflf',\
CHANCE: 2},
PE:{ \
HEADER1: ('P','E','\x00','\x00'),\
HEADER2: None,\
NAME: 'PE',\
DESC: "PE - File Format",\
SUFFIX: 'exe',\
CHANCE: 2},
MSDOSCOM:{ \
HEADER1: ('\xfc','\x57','\xf3','\xa5','\xc3'),\
HEADER2: None,\
NAME: 'COM',\
DESC: "COM executable for MS-DOS",\
SUFFIX: 'com',\
CHANCE: 2},
DOSCOM:{ \
HEADER1: ('\xfc','\x57','\xf3','\xa4','\xc3'),\
HEADER2: None,\
NAME: 'COMDOS',\
DESC: "COM executable for DOS",\
SUFFIX: 'com',\
CHANCE: 2},
SPSSPORTABLE:{ \
HEADER1: ('\xc1','\xe2','\xc3','\xc9'),\
HEADER2: None,\
NAME: 'SPSS',\
DESC: "SPSS Portable File",\
SUFFIX: None,\
CHANCE: 2},
SPSSSYSTEM:{ \
HEADER1: ('$','F','L','2'),\
HEADER2: None,\
NAME: 'SPSS2',\
DESC: "SPSS System File",\
SUFFIX: None,\
CHANCE: 2},
PPCPEF:{ \
HEADER1: ('J','o','y','!','p','e','f','f','p','w','p','c'),\
HEADER2: None,\
NAME: 'PPC_PEF',\
DESC: "header for PowerPC PEF executable",\
SUFFIX: None,\
CHANCE: 2}
},
PACKERS: {
ZIP1:{ \
HEADER1: ('\x50','\x4b','\x03','\x04'),\
HEADER2: None,\
NAME: 'ZIP1',\
DESC: "ZIP1 - Phil Katz ",\
SUFFIX: 'zip',\
CHANCE: 2},
ZIP2:{ \
HEADER1: ('\x50','\x4b','\x01','\x02'),\
HEADER2: None,\
NAME: 'ZIP2',\
DESC: "ZIP2 - Phil Katz ",\
SUFFIX: 'zip',\
CHANCE: 2},
BZIP:{ \
HEADER1: ('\x42','\x5a','\x68'),\
HEADER2: None,\
NAME: 'BZIP',\
DESC: "BZIP - a block-sorting file compressor",\
SUFFIX: 'bz2',\
CHANCE: 2},
GZIP:{ \
HEADER1: ('\x1f','\x8b'),\
HEADER2: None,\
NAME: 'GZIP',\
DESC: "GZIP - Lempel-Ziv coding (LZ77)",\
SUFFIX: 'gz',\
CHANCE: 2},
ACE:{ \
HEADER1: ('*','*','A','C','E','*','*'),\
HEADER2: None,\
NAME: 'ACE',\
DESC: "ACE - e-merge GmbH - winace.com",\
SUFFIX: 'ace',\
CHANCE: 2},
TAR:{ \
HEADER1: ('\x00','u','s','t','a','r','\x00'),\
HEADER2: None,\
NAME: 'TAR',\
DESC: "TAR - tape archiver",\
SUFFIX: 'tar',\
CHANCE: 2},
TRX1:{ \
HEADER1: ('\x30','\x52','\x44','\x48'),\
HEADER2: None,\
NAME: 'TRX1',\
DESC: "TRX1 - ",\
SUFFIX: None,\
CHANCE: 2},
TRX2:{ \
HEADER1: ('H','D','R','0'),\
HEADER2: ('0','R','D','H'),\
NAME: 'TRX2',\
DESC: "TRX2 - ",\
SUFFIX: None,\
CHANCE: 2},
LZMA:{ \
HEADER1: ('\x5d','\x00','\x00','\x80'),\
HEADER2: None,\
NAME: 'LZMA',\
DESC: "LZMA - Lempel-Ziv-Markov chain-Algorithm",\
SUFFIX: 'lzma',\
CHANCE: 2},
UPX:{ \
HEADER1: ('U','P','X','!'),\
HEADER2: None,\
NAME: 'UPX',\
DESC: "UPX - Ultimate Packer for eXecuteables",\
SUFFIX: 'upx',\
CHANCE: 2},
GNUTAR:{ \
HEADER1: ('u','s','t','a','r','\x20','\x20','\x00'),\
HEADER2: None,\
NAME: 'GNUTAR',\
DESC: "GNUTAR - tar == teer + tape archiver",\
SUFFIX: 'tar',\
CHANCE: 2},
CRUSH:{ \
HEADER1: ('C', 'R', 'U', 'S', 'H'),\
HEADER2: None,\
NAME: 'CRUSH',\
DESC: "CRUSH - Crush archive data",\
SUFFIX: None,\
CHANCE: 2},
HLSQZ:{ \
HEADER1: ('H', 'L', 'S', 'Q', 'Z'),\
HEADER2: None,\
NAME: 'HLSQZ',\
DESC: "HLSQZ - Squeeze It archive data",\
SUFFIX: None,\
CHANCE: 2},
SQWEZ:{ \
HEADER1: ('S', 'Q', 'W', 'E', 'Z'),\
HEADER2: None,\
NAME: 'SQWEZ',\
DESC: "SQWEZ - archive data",\
SUFFIX: None,\
CHANCE: 2},
HPAK:{ \
HEADER1: ('H', 'P', 'A', 'K'),\
HEADER2: None,\
NAME: 'HPAK',\
DESC: "HPAK - archive data",\
SUFFIX: None,\
CHANCE: 2},
LZOP:{ \
HEADER1: ('\x89','\x4c','\x5a','\x4f','\x00','\x0d','\x0a','\x1a','\x0a'),\
HEADER2: None,\
NAME: 'LZOP',\
DESC: "LZOP - lzop comrpressed data",\
SUFFIX: None,\
CHANCE: 2},
MDCD:{ \
HEADER1: ('M', 'D', 'm', 'd'),\
HEADER2: None,\
NAME: 'MDCD',\
DESC: "MDCD - archive data",\
SUFFIX: None,\
CHANCE: 2},
MSCOMPRESS:{ \
HEADER1: ('\x88','\xf0','\x27'),\
HEADER2: None,\
NAME: 'MS',\
DESC: "MS Compress archive data",\
SUFFIX: None,\
CHANCE: 2},
INSTALLSHIELD:{ \
HEADER1: ('\x13','\x5d','\x65','\x8c'),\
HEADER2: None,\
NAME: 'MSIS',\
DESC: "InstallShield - Z archive Data",\
SUFFIX: None,\
CHANCE: 2},
PAQ:{ \
HEADER1: ('\xaa','\x40','\x5f','\x77','\x1f','\xe5','\x82','\x0d'),\
HEADER2: None,\
NAME: 'PAQ',\
DESC: "PAQ - archive data",\
SUFFIX: None,\
CHANCE: 2},
JARARJ:{ \
HEADER1: ('\x1a','J','a','r','\x1b'),\
HEADER2: None,\
NAME: 'JAR',\
DESC: "JAR (ARJ Software, Inc.) archive data",\
SUFFIX: 'arj',\
CHANCE: 2},
STUFFIT:{ \
HEADER1: ('S','t','u','f','f','I','t'),\
HEADER2: None,\
NAME: 'STUFFIT',\
DESC: "StuffIt Archive",\
SUFFIX: 'stuffit',\
CHANCE: 2},
VAX3:{ \
HEADER1: ('\x65','\xff','\x00','\x00'),\
HEADER2: None,\
NAME: 'VAX3',\
DESC: "VAX 3.0 archive",\
SUFFIX: None,\
CHANCE: 2},
VAX5:{ \
HEADER1: ('\x3c','\x61','\x72','\x3e'),\
HEADER2: None,\
NAME: 'VAX5',\
DESC: "VAX 5.0 archive",\
SUFFIX: None,\
CHANCE: 2},
ARCHIVE:{ \
HEADER1: ('=','<','a','r','>'),\
HEADER2: None,\
NAME: 'AR',\
DESC: "archive",\
SUFFIX: 'ar',\
CHANCE: 2},
ARCHIVEFILE:{ \
HEADER1: ('21','3c','61','72'),\
HEADER2: None,\
NAME: 'ARfile',\
DESC: "archive file",\
SUFFIX: 'ar',\
CHANCE: 2},
HRB:{ \
HEADER1: ('\xc0','H','R','B'),\
HEADER2: None,\
NAME: 'HRB',\
DESC: "Harbour HRB file",\
SUFFIX: 'hrb',\
CHANCE: 2},
RISCOS:{ \
HEADER1: ('A','r','c','h','i','v','e'),\
HEADER2: None,\
NAME: 'RISCOS',\
DESC: "RISC OS archive (ArcFS format)",\
SUFFIX: None,\
CHANCE: 2},
HAP:{ \
HEADER1: ('\x91','\x33','H','F'),\
HEADER2: None,\
NAME: 'HAP',\
DESC: "HAP archive data",\
SUFFIX: None,\
CHANCE: 2},
LIM:{ \
HEADER1: ('L','I','M','\x1a'),\
HEADER2: None,\
NAME: 'LIM',\
DESC: "LIM archive data",\
SUFFIX: None,\
CHANCE: 2},
FREEZE:{ \
HEADER1: ('\x1f','\x9f','\x4a','\x10','\x0a'),\
HEADER2: None,\
NAME: 'FREEZE',\
DESC: "Freeze archive data",\
SUFFIX: None,\
CHANCE: 2},
ZOO:{ \
HEADER1: ('\xfd','\xc4','\xa7','\xdc'),\
HEADER2: None,\
NAME: 'ZOO',\
DESC: "Zoo archive data",\
SUFFIX: None,\
CHANCE: 2},
RAR:{ \
HEADER1: ('R','a','r','!'),\
HEADER2: None,\
NAME: 'RAR',\
DESC: "RAR archive data",\
SUFFIX: 'rar',\
CHANCE: 2},
EET:{ \
HEADER1: ('\x1e','\xe7','\xff','\x00'),\
HEADER2: None,\
NAME: 'EET',\
DESC: "EET archive",\
SUFFIX: None,\
CHANCE: 2},
RZIP:{ \
HEADER1: ('R','Z','I','P'),\
HEADER2: None,\
NAME: 'RZIP',\
DESC: "rzip compressed data",\
SUFFIX: None,\
CHANCE: 2},
SQSH:{ \
HEADER1: ('S','Q','S','H'),\
HEADER2: None,\
NAME: 'SQUISH',\
DESC: "squished archive data (Acorn RISCOS)",\
SUFFIX: None,\
CHANCE: 2},
ISC:{ \
HEADER1: ('I','S','c','('),\
HEADER2: None,\
NAME: 'CAB',\
DESC: "InstallShield CAB",\
SUFFIX: None,\
CHANCE: 2},
NWFILE:{ \
HEADER1: ('P','a','c','k','e','d','\\',' ','F','i','l','e','\\'),\
HEADER2: None,\
NAME: 'NETWARE',\
DESC: "Personal NetWare Packed File",\
SUFFIX: None,\
CHANCE: 2},
DSIGDCC:{ \
HEADER1: ('D','S','I','G','D','C','C'),\
HEADER2: None,\
NAME: 'CROSSEPAC',\
DESC: "CrossePAC archive data",\
SUFFIX: None,\
CHANCE: 2},
ARJ:{ \
HEADER1: ('\x60','\xea'),\
HEADER2: None,\
NAME: 'ARJ',\
DESC: "ARJ",\
SUFFIX: 'arj',\
CHANCE: 2}
},
DOCS: { \
PDF:{ \
HEADER1: ('\x25','\x50','\x44','\x46','\x2e'),\
HEADER2: None,\
NAME: 'PDF',\
DESC: "PDF - Portable Document Format",\
SUFFIX: 'pdf',\
CHANCE: 2},
DOC:{ \
HEADER1: ('\xd0','\xcf','\x11','\xe0','\xa1','\xb1','\x1a','\xe1'),\
HEADER2: None,\
NAME: 'DOC',\
DESC: "DOC - Microsoft Document Format",\
SUFFIX: 'doc',\
CHANCE: 2},
RTF:{ \
HEADER1: ('{','\\','\\','r','t','f'),\
HEADER2: None,\
NAME: 'RTF',\
DESC: "RTF - Rich Text Format data",\
SUFFIX: 'rtf',\
CHANCE: 2}
},
BOOT: { \
UBOOT:{ \
HEADER1: ('\x27','\x05','\x19','\x56'),\
HEADER2: None,\
NAME: 'UBOOT',\
DESC: "UBOOT - PPCBoot Image - maybe bootloader",\
SUFFIX: 'uboot',\
CHANCE: 2}
},
ASM: { \
AVR:{ \
HEADER1: ('a','v','a','o','b','j'),\
HEADER2: None,\
NAME: 'AVR',\
DESC: "AVR assembler object code",\
SUFFIX: 'avr',\
CHANCE: 2}
},
PICTURES: { \
GIMPXCF:{ \
HEADER1: ('g','i','m','p','\\',' ','x','c','f'),\
HEADER2: None,\
NAME: 'GIMP_XCF',\
DESC: "GIMP XCF image data",\
SUFFIX: 'xcf',\
CHANCE: 2}
},
DEVICES: { \
LTRX1:{ \
HEADER1: ('D','S','T','-','L','T','R','X'),\
HEADER2: None,\
NAME: 'LTRX1',\
DESC: "LTRX1 - Lantronics Firmware Part detected",\
SUFFIX: None,\
CHANCE: 2},
LTRX2:{ \
HEADER1: ('L','T','R','X'),\
HEADER2: None,\
NAME: 'LTRX2',\
DESC: "LTRX2 - Lantronics Firmware Part detected",\
SUFFIX: None,\
CHANCE: 2},
WGR614BOOT:{ \
HEADER1: ('*','#','$','^'),\
HEADER2: None,\
NAME: 'NETGEAR_BOOT',\
DESC: "NETGEAR WGR614v9 Bootware - unknown bootloader maybe",\
SUFFIX: None,\
CHANCE: 2},
WGR614:{ \
HEADER1: ('@','U','1','2','H','0','9','4','T'),\
HEADER2: None,\
NAME: 'NETGEAR_FW',\
DESC: "NETGEAR WGR614v9 Firmware",\
SUFFIX: None,\
CHANCE: 2}
},
CRYPTO: {
DSAPRIV:{ \
HEADER1: ('-----BEGIN DSA PRIVATE KEY-----'),\
HEADER2: ('-----END DSA PRIVATE KEY-----'),\
NAME: 'DSAPRIV',\
DESC: "DSAPRIV - Private Key in DSA Format",\
SUFFIX: None,\
CHANCE: 2},
RSAPRIV:{ \
HEADER1: ('-----BEGIN RSA PRIVATE KEY-----'),\
HEADER2: ('-----END RSA PRIVATE KEY-----'),\
NAME: 'RSAPRIV',\
DESC: "RSAPRIV - Private Key in RSA Format",\
SUFFIX: None,\
CHANCE: 2},
SSHPUB:{ \
HEADER1: ('ssh-dss'),\
HEADER2: None,\
NAME: 'SSHDSS',\
DESC: "SSHDSS - Public ssh key",\
SUFFIX: None,\
CHANCE: 2},
CACERT:{ \
HEADER1: ('-----BEGIN CERTIFICATE-----'),\
HEADER2: ('-----END CERTIFICATE-----'),\
NAME: 'CACERT',\
DESC: "CACERT - Certificate Format",\
SUFFIX: None,\
CHANCE: 2},
CERTREQ:{ \
HEADER1: ('-----BEGIN CERTIFICATE REQUEST-----'),\
HEADER2: ('-----END CERTIFICATE REQUEST-----'),\
NAME: 'CERTREQ',\
DESC: "CERTREQ - Certificate Request Format",\
SUFFIX: None,\
CHANCE: 2},
PGPMSG:{ \
HEADER1: ('-----BEGIN PGP MESSAGE-----'),\
HEADER2: ('-----END PGP MESSAGE-----'),\
NAME: 'PGPMSG',\
DESC: "PGPMSG - Pretty Good Privacy Message Format",\
SUFFIX: None,\
CHANCE: 2},
}
}
TYPES_DEF = { 'FS':FS,\
'EXEC':EXEC,\
'PACKERS':PACKERS,\
'DOCS':DOCS,\
'BOOT':BOOT,\
'ASM':ASM,\
'PICTURES':PICTURES,\
'DEVICES':DEVICES,\
'CRYPTO':CRYPTO
}

BIN
lib/FUDGEheader.pyc Normal file

Binary file not shown.

4
lib/__init__.py Executable file
View File

@@ -0,0 +1,4 @@
"""
Fudge init library
"""

BIN
lib/__init__.pyc Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

30
supply/strings.txt Normal file
View File

@@ -0,0 +1,30 @@
# this is a header file for the strings analysis function
# it is kept in simple csv style; so it can easily edited
# the idea is to add strings possibly found in firmwares
# hints on what it is and a description
#
# it is *not* made to repeat magic strings already existing in
# fudge database or libmagic/magic.mgc database
#
# needle:
# all search strings(needle) are written in lower case; however FF will check
# for lower and capital letters
#
# shortdesc:
# add a short description
#
# tools:
# possible tools or url?
#
# format
# needle;shortdesc;tools
linux;Linux string has been found; possibly linux OS or file;http://www.kernel.org
kernel;Kernel strings has been found; sneak around and check if more information is existing;hexdump -C
supertask;Supertask(RTOS) found;google
trontask;Trontask(RTOS) found;google
ILC 150 GSM Upgrade;inline gsm modem;https://www.phoenixcontact.com/online/portal/de?uri=pxc-oc-itemdetail:pid=2916545&library=dede&tab=1
SPI Flash Image; SPI access available;http://linux-sunxi.org/Bootable_SPI_flash
/etc;linux etc directory;google
/mnt;linux mnt directory;google
/etc/shadow;shadow file;shadow
/etc/passwd;passwd file;passwd