167 lines
4.7 KiB
Python
167 lines
4.7 KiB
Python
#
|
|
#
|
|
#
|
|
import os
|
|
import argparse
|
|
import logging
|
|
from subprocess import Popen, PIPE, check_call
|
|
# our libs
|
|
from libs import fingerprint
|
|
from libs import android
|
|
from libs.fingerprint_index import FingerprintIndex
|
|
|
|
BASE_DIR = "data"
|
|
FP_BASE_DIR = "fingerprints"
|
|
|
|
|
|
def main():
|
|
# logging.basicConfig(filename='dbfp.log', level=logging.DEBUG)
|
|
logging.basicConfig(level=logging.DEBUG)
|
|
parseArgs()
|
|
|
|
#
|
|
def compareFingerprintDir(filein, fpdir):
|
|
db = fingerprint.FingerprintDB()
|
|
fp = FingerprintIndex()
|
|
fp.openIndex()
|
|
|
|
#
|
|
def compareFingerprint(filein, filejson):
|
|
db = fingerprint.FingerprintDB()
|
|
db.scanDBFile(filein)
|
|
percent = db.compareDB(filejson)
|
|
print "Percent match: {}".format(str(percent))
|
|
|
|
#
|
|
def createFingerprint(filein, verbose, app_name, app_ver, notes):
|
|
db = fingerprint.FingerprintDB()
|
|
retVal = db.scanDBFile(filein)
|
|
if (retVal > 0):
|
|
if verbose:
|
|
db.debugFingerprint()
|
|
if app_name:
|
|
db.setAppName(app_name)
|
|
if app_ver:
|
|
db.setAppVer(app_ver)
|
|
if notes:
|
|
db.setNotes(notes)
|
|
db.writeFingerprint()
|
|
else:
|
|
print db.getErrorString(retVal)
|
|
|
|
#
|
|
def androidPull():
|
|
ap = android.AndroidAppPull()
|
|
isRoot = ap.isADBRoot();
|
|
if (not isRoot):
|
|
print "ERROR: adb is not running as root, exec 'adb root'"
|
|
return
|
|
|
|
if (not mkdir(BASE_DIR)):
|
|
logging.error("ERROR creating directory: {}".format(BASE_DIR))
|
|
return
|
|
if (not mkdir(FP_BASE_DIR)):
|
|
logging.error("ERROR creating directory: {}".format(FP_BASE_DIR))
|
|
return
|
|
|
|
dir_names = ap.getAppsDir()
|
|
for dir_name in dir_names:
|
|
fq_dir = BASE_DIR + os.path.sep + dir_name
|
|
ap.pullApp(BASE_DIR, dir_name)
|
|
__createFingerprint(fq_dir, dir_name)
|
|
|
|
#
|
|
def androidData(data_dir):
|
|
dir_names = []
|
|
try:
|
|
dirs = os.listdir(data_dir)
|
|
except:
|
|
return
|
|
|
|
if (not mkdir(FP_BASE_DIR)):
|
|
logging.error("ERROR creating directory: {}".format(FP_BASE_DIR))
|
|
return
|
|
|
|
for ddir in dirs:
|
|
#logging.info("ddir=={}".format(ddir))
|
|
fq_dir = data_dir + os.path.sep + ddir
|
|
__createFingerprint(fq_dir, ddir)
|
|
|
|
# in_dir: fully qualified directory path to find sqlite files
|
|
def __createFingerprint(fq_dir, dir_name):
|
|
try:
|
|
#cdir = BASE_DIR + os.path.sep + dir_name + os.path.sep + "databases"
|
|
db_dir = fq_dir + os.path.sep + "databases"
|
|
logging.info("fq_dir=={}".format(db_dir))
|
|
files = os.listdir(db_dir)
|
|
except:
|
|
# not finding a databases folder is normal, not all apps use sqlite
|
|
return
|
|
db = fingerprint.FingerprintDB()
|
|
fdir = FP_BASE_DIR + os.path.sep + dir_name
|
|
if (not mkdir(fdir)):
|
|
logging.error('Error creating directory "{}"'.format(fdir))
|
|
return
|
|
for filein in files:
|
|
ddir = db_dir + os.path.sep + filein
|
|
logging.info('Parsing file "{}"'.format(ddir))
|
|
retVal = db.scanDBFile(ddir)
|
|
if (retVal > 0):
|
|
fname = dir_name + "__" + filein + "__dbfp" + ".json"
|
|
fdir_name = fdir + os.path.sep + fname
|
|
#fh = open(fdir_name, "w")
|
|
db.setAppName(dir_name)
|
|
db.writeFingerprintFile(fdir_name)
|
|
#fh.close()
|
|
|
|
#
|
|
def __getFileName():
|
|
'''standardize on a file name, use timestamp? '''
|
|
pass
|
|
|
|
#
|
|
def mkdir(fdir):
|
|
retval = False
|
|
try:
|
|
check_call(["mkdir", fdir])
|
|
retval = True
|
|
except:
|
|
logging.error('ERROR: problem creating directory "{}"'.format(fdir))
|
|
return retval
|
|
|
|
#
|
|
def parseArgs():
|
|
print '***** ***** ***** *****'
|
|
print ' DB Fingerprint'
|
|
print '***** ***** ***** *****\n'
|
|
parser = argparse.ArgumentParser(description="Fingerprint a sqlite database based on its schema")
|
|
parser.add_argument('-f', '--file', required=False, help="path to file to be fingerprinted")
|
|
parser.add_argument('-fd', '--fpdir', required=False, help="path to directory of fingerprint files")
|
|
parser.add_argument('-fp', '--fingerprint', required=False, help="fingerprint file to use in comparison")
|
|
parser.add_argument('-dd', '--data_dir', required=False, help="path to a directory with sqlite files")
|
|
parser.add_argument('-an', '--app_name', required=False)
|
|
parser.add_argument('-av', '--app_version', required=False)
|
|
parser.add_argument('-n', '--notes', required=False)
|
|
parser.add_argument('-pull', '--pull', required=False, action='store_true', help="automated physical ")
|
|
parser.add_argument('-v', '--verbose', action='store_true')
|
|
# parser.add_argument('-t', '--title', required=False)
|
|
args = parser.parse_args()
|
|
|
|
if (args.file and args.fingerprint):
|
|
compareFingerprint(args.file, args.fingerprint)
|
|
elif (args.file and args.fpdir):
|
|
compareFingerprintDir(args.file, args.fpdir)
|
|
elif (args.data_dir):
|
|
androidData(args.data_dir)
|
|
elif (args.pull):
|
|
androidPull()
|
|
elif (args.file):
|
|
createFingerprint(args.file, args.verbose, args.app_name, args.app_version, args.notes)
|
|
else:
|
|
parser.print_help()
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|