· 9 years ago · Oct 08, 2016, 03:58 AM
1#!/usr/bin/python
2
3# Anthony Masi -- am4376@nyu.edu
4# Digital Forensics - Homework 6
5
6import argparse
7import errno
8import os
9import PIL.ExifTags
10import PIL.Image
11import pyPdf
12import sqlite3
13import subprocess
14import types
15
16DATABASE = "database.db"
17
18def main():
19 parser = argparse.ArgumentParser()
20 parser.add_argument("-o", "--output", help="Destination directory for output", required="true")
21 parser.add_argument("-i", "--images", help="Disk images to analyze (comma delimited)", required="true")
22 args = parser.parse_args()
23
24 if validate(args.output, args.images):
25 carve_files(args.output, args.images)
26
27 conn = sqlite3.connect(DATABASE, isolation_level=None)
28
29 c = conn.cursor()
30
31 c.execute("DROP TABLE IF EXISTS recovered_files;")
32 c.execute("CREATE TABLE recovered_files (filename BLOB, fullpath BLOB, exif_data BLOB, pdf_data BLOB, metadata BLOB, md5 BLOB);")
33
34 c.close()
35 conn.close()
36
37 traverse_dir(args.output)
38 dump_to_file()
39 else:
40 print ("Error occurred: one or more of your disk image files could not be found!")
41
42def validate(output, images):
43 # "How to check if a directory exists and create it if necessary" (avoids race condition)
44 # http://tinyurl.com/zjxnv3t
45 # BEGIN
46 try:
47 os.makedirs(output)
48 except OSError as exception:
49 if exception.errno != errno.EEXIST:
50 raise
51 # END
52
53 files = images.strip().split(",")
54
55 for file in files:
56 if not os.path.isfile(file):
57 return 0
58
59 return 1
60
61def carve_files(output, images):
62 files = images.strip().split(",")
63
64 for file in files:
65 fn = file.split(".")
66 try:
67 # Same directory creation code sourced on line 23
68 # TODO: Modularize lines 50-54
69 # BEGIN
70 try:
71 os.makedirs(output + "/" + str(fn[0]))
72 except OSError as exception:
73 if exception.errno != errno.EEXIST:
74 raise
75 # END
76 subprocess.check_output(["tsk_recover", "-e", file, output + "/" + str(fn[0])])
77 except:
78 raise Exception("Error: unable to carve image " + str(file))
79
80def traverse_dir(output):
81 conn = sqlite3.connect(DATABASE, isolation_level=None)
82 conn.text_factory = str
83 c = conn.cursor()
84 for root, dirs, files in os.walk(output):
85 for fn in files:
86 try:
87 filepath = os.path.join(root,fn)
88 file_type = subprocess.check_output(["file", filepath])
89 exif = "NULL"
90 pdf_metadata = "NULL"
91 if "JPEG" in file_type or "TIFF" in file_type or "WAV" in file_type or "DCF" in file_type:
92 img = PIL.Image.open(os.path.join(root,fn))
93 exif = scrape_exif(img)
94 elif "PDF" in file_type:
95 pdf_metadata = scrape_pdf_meta(os.path.join(root,fn))
96 metadata = os.stat(os.path.join(root,fn))
97 md5 = subprocess.check_output(["md5sum", os.path.join(root,fn)])
98 md5 = md5.split(" ")
99 md5 = md5[0]
100 try:
101 c.execute("INSERT INTO recovered_files VALUES (?,?,?,?,?,?)", (str(fn),str(filepath),str(exif),str(pdf_metadata),str(metadata),str(md5)))
102 except sqlite3.Error as er:
103 print 'er: ', er.message
104 except Exception as exception:
105 continue
106 c.close()
107 conn.close()
108
109def scrape_exif(img):
110 exif = {}
111 try:
112 info = img._getexif()
113 for tag, value in info.items():
114 decoded = PIL.ExifTags.TAGS.get(tag, tag)
115 exif[decoded] = value
116 except Exception as exception:
117 exif = exif
118
119 return exif
120
121def scrape_pdf_meta(fn):
122 metadata = ""
123 pdf = pyPdf.PdfFileReader(file(fn, 'rb'))
124 info = pdf.getDocumentInfo()
125 metadata = fn
126 for item, data in info.items():
127 try:
128 metadata = metadata + "\n" + item + " " + pdf.resolvedObjects[0][1][item]
129 except:
130 metadata = metadata + "\n" + item + " " + data
131 return metadata
132
133def dump_to_file():
134 conn = sqlite3.connect(DATABASE)
135 c = conn.cursor()
136 data = c.execute("SELECT * FROM recovered_files").fetchall()
137
138 with open("database.txt", "a") as file:
139 for row in data:
140 file.write(str(row))
141
142if __name__ == '__main__':
143 main()