├── .gitattributes ├── Chapter01 ├── copy_metadata.py ├── file_metadata.py ├── hashing.py ├── logging_recipe.py ├── multiproc_example.py ├── os_walk.py ├── progressbars.py └── simple_arguments.py ├── Chapter02 ├── .DS_Store ├── ftk_parser.py ├── html_dashboard.py ├── light-bootstrap-dashboard │ ├── .DS_Store │ ├── LICENSE.md │ ├── README.md │ └── assets │ │ ├── css │ │ ├── animate.min.css │ │ ├── bootstrap.min.css │ │ ├── demo.css │ │ ├── light-bootstrap-dashboard.css │ │ └── pe-icon-7-stroke.css │ │ ├── fonts │ │ ├── Pe-icon-7-stroke.eot │ │ ├── Pe-icon-7-stroke.svg │ │ ├── Pe-icon-7-stroke.ttf │ │ └── Pe-icon-7-stroke.woff │ │ ├── img │ │ ├── default-avatar.png │ │ ├── faces │ │ │ ├── face-0.jpg │ │ │ ├── face-1.jpg │ │ │ ├── face-2.jpg │ │ │ ├── face-3.jpg │ │ │ ├── face-4.jpg │ │ │ ├── face-5.jpg │ │ │ ├── face-6.jpg │ │ │ ├── face-7.jpg │ │ │ └── tim_vector.jpe │ │ ├── favicon.ico │ │ ├── loading-bubbles.svg │ │ ├── mask.png │ │ ├── new_logo.png │ │ ├── sidebar-1.jpg │ │ ├── sidebar-2.jpg │ │ ├── sidebar-3.jpg │ │ ├── sidebar-4.jpg │ │ ├── sidebar-5.jpg │ │ └── tim_80x80.png │ │ ├── js │ │ ├── bootstrap-checkbox-radio-switch.js │ │ ├── bootstrap-notify.js │ │ ├── bootstrap-select.js │ │ ├── bootstrap.min.js │ │ ├── chartist.min.js │ │ ├── jquery-1.10.2.js │ │ └── light-bootstrap-dashboard.js │ │ └── sass │ │ ├── lbd │ │ ├── _alerts.scss │ │ ├── _buttons.scss │ │ ├── _cards.scss │ │ ├── _chartist.scss │ │ ├── _checkbox-radio-switch.scss │ │ ├── _dropdown.scss │ │ ├── _footers.scss │ │ ├── _inputs.scss │ │ ├── _misc.scss │ │ ├── _mixins.scss │ │ ├── _navbars.scss │ │ ├── _responsive.scss │ │ ├── _sidebar-and-main-panel.scss │ │ ├── _tables.scss │ │ ├── _typography.scss │ │ ├── _variables.scss │ │ └── mixins │ │ │ ├── _buttons.scss │ │ │ ├── _cards.scss │ │ │ ├── _chartist.scss │ │ │ ├── _icons.scss │ │ │ ├── _inputs.scss │ │ │ ├── _labels.scss │ │ │ ├── _morphing-buttons.scss │ │ │ ├── _navbars.scss │ │ │ ├── _social-buttons.scss │ │ │ ├── _tabs.scss │ │ │ ├── _transparency.scss │ │ │ └── _vendor-prefixes.scss │ │ └── light-bootstrap-dashboard.scss ├── output_writer.py ├── redacted_sample_event_log.csv ├── screenshotter.py ├── utility │ ├── __init__.py │ └── utilcsv.py └── xlsx_writer.py ├── Chapter03 ├── iBackup.py ├── plist_parser.py ├── sqlite_carver.py ├── sqlite_gaps.py ├── sqlite_sms.py └── wifi_lookup.py ├── Chapter04 ├── apple_genres.json ├── av_metadata.py ├── exe_metadata.py ├── msoffice_metadata.py ├── pdf_metadata.py └── pic_metadata.py ├── Chapter05 ├── beautiful_preservation.py ├── ief_parser.py ├── ief_yahoo_cache_parser.py ├── passive_lookup.py ├── total_virus.py └── virus_hashset.py ├── Chapter06 ├── eml_parser.py ├── mbox_parser.py ├── msg_parser.py └── pff_parser.py ├── Chapter07 ├── axiom_daily_out.py ├── daily_parser.py ├── date_parser.py ├── iis_parser.py ├── splunk_connector.py └── yara_scanner.py ├── Chapter08 ├── evidence_metadata.py ├── extract_file_type.py ├── open_evidence.py ├── recurse_files.py └── search_evidence_hashes.py ├── Chapter10 ├── .DS_Store ├── evt_explorer.py ├── index_parser.py ├── pf_parser.py ├── srum_parser.py ├── utility │ ├── __init__.py │ ├── pytskutil.py │ └── vss.py └── vss_explorer.py ├── LICENSE └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /Chapter01/copy_metadata.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import argparse 3 | from datetime import datetime as dt 4 | import os 5 | import pytz 6 | from pywintypes import Time 7 | import shutil 8 | from win32file import SetFileTime, CreateFile, CloseHandle 9 | from win32file import GENERIC_WRITE, FILE_SHARE_WRITE 10 | from win32file import OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL 11 | 12 | """ 13 | MIT License 14 | 15 | Copyright (c) 2017 Chapin Bryce, Preston Miller 16 | 17 | Please share comments and questions at: 18 | https://github.com/PythonForensics/PythonForensicsCookbook 19 | or email pyforcookbook@gmail.com 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy 22 | of this software and associated documentation files (the "Software"), to deal 23 | in the Software without restriction, including without limitation the rights 24 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25 | copies of the Software, and to permit persons to whom the Software is 26 | furnished to do so, subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in all 29 | copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 34 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 37 | SOFTWARE. 38 | """ 39 | 40 | __authors__ = ["Chapin Bryce", "Preston Miller"] 41 | __date__ = 20170815 42 | __description__ = "Utility to copy files and associated metadata on Windows" 43 | 44 | parser = argparse.ArgumentParser( 45 | description=__description__, 46 | epilog="Developed by {} on {}".format( 47 | ", ".join(__authors__), __date__) 48 | ) 49 | parser.add_argument("source", help="Source file") 50 | parser.add_argument("dest", help="Destination directory or file") 51 | parser.add_argument("--timezone", help="Timezone of the file's timestamp", 52 | choices=['EST5EDT', 'CST6CDT', 'MST7MDT', 'PST8PDT'], 53 | required=True) 54 | args = parser.parse_args() 55 | 56 | source = os.path.abspath(args.source) 57 | if os.sep in args.source: 58 | src_file_name = args.source.split(os.sep, 1)[1] 59 | else: 60 | src_file_name = args.source 61 | 62 | dest = os.path.abspath(args.dest) 63 | tz = pytz.timezone(args.timezone) 64 | 65 | shutil.copy2(source, dest) 66 | if os.path.isdir(dest): 67 | dest_file = os.path.join(dest, src_file_name) 68 | else: 69 | dest_file = dest 70 | 71 | created = dt.fromtimestamp(os.path.getctime(source)) 72 | created = Time(tz.localize(created)) 73 | modified = dt.fromtimestamp(os.path.getmtime(source)) 74 | modified = Time(tz.localize(modified)) 75 | accessed = dt.fromtimestamp(os.path.getatime(source)) 76 | accessed = Time(tz.localize(accessed)) 77 | 78 | print("Source\n======") 79 | print("Created: {}\nModified: {}\nAccessed: {}".format( 80 | created, modified, accessed)) 81 | 82 | handle = CreateFile(dest_file, GENERIC_WRITE, FILE_SHARE_WRITE, 83 | None, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, None) 84 | SetFileTime(handle, created, accessed, modified) 85 | CloseHandle(handle) 86 | 87 | created = tz.localize(dt.fromtimestamp(os.path.getctime(dest_file))) 88 | modified = tz.localize(dt.fromtimestamp(os.path.getmtime(dest_file))) 89 | accessed = tz.localize(dt.fromtimestamp(os.path.getatime(dest_file))) 90 | print("\nDestination\n===========") 91 | print("Created: {}\nModified: {}\nAccessed: {}".format( 92 | created, modified, accessed)) 93 | -------------------------------------------------------------------------------- /Chapter01/file_metadata.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import argparse 3 | from datetime import datetime as dt 4 | import os 5 | import sys 6 | 7 | """ 8 | MIT License 9 | 10 | Copyright (c) 2017 Chapin Bryce, Preston Miller 11 | 12 | Please share comments and questions at: 13 | https://github.com/PythonForensics/PythonForensicsCookbook 14 | or email pyforcookbook@gmail.com 15 | 16 | Permission is hereby granted, free of charge, to any person obtaining a copy 17 | of this software and associated documentation files (the "Software"), to deal 18 | in the Software without restriction, including without limitation the rights 19 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 20 | copies of the Software, and to permit persons to whom the Software is 21 | furnished to do so, subject to the following conditions: 22 | 23 | The above copyright notice and this permission notice shall be included in all 24 | copies or substantial portions of the Software. 25 | 26 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 29 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 30 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 31 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32 | SOFTWARE. 33 | """ 34 | 35 | __authors__ = ["Chapin Bryce", "Preston Miller"] 36 | __date__ = 20170815 37 | __description__ = "Gather filesystem metadata of provided file" 38 | 39 | parser = argparse.ArgumentParser( 40 | description=__description__, 41 | epilog="Developed by {} on {}".format(", ".join(__authors__), __date__) 42 | ) 43 | parser.add_argument("FILE_PATH", 44 | help="Path to file to gather metadata for") 45 | args = parser.parse_args() 46 | file_path = args.FILE_PATH 47 | 48 | stat_info = os.stat(file_path) 49 | if "linux" in sys.platform or "darwin" in sys.platform: 50 | print("Change time: ", dt.fromtimestamp(stat_info.st_ctime)) 51 | elif "win" in sys.platform: 52 | print("Creation time: ", dt.fromtimestamp(stat_info.st_ctime)) 53 | else: 54 | print("[-] Unsupported platform {} detected. Cannot interpret " 55 | "creation/change timestamp.".format(sys.platform) 56 | ) 57 | print("Modification time: ", dt.fromtimestamp(stat_info.st_mtime)) 58 | print("Access time: ", dt.fromtimestamp(stat_info.st_atime)) 59 | 60 | print("File mode: ", stat_info.st_mode) 61 | print("File inode: ", stat_info.st_ino) 62 | major = os.major(stat_info.st_dev) 63 | minor = os.minor(stat_info.st_dev) 64 | print("Device ID: ", stat_info.st_dev) 65 | print("\tMajor: ", major) 66 | print("\tMinor: ", minor) 67 | 68 | print("Number of hard links: ", stat_info.st_nlink) 69 | print("Owner User ID: ", stat_info.st_uid) 70 | print("Group ID: ", stat_info.st_gid) 71 | print("File Size: ", stat_info.st_size) 72 | 73 | print("Is a symlink: ", os.path.islink(file_path)) 74 | print("Absolute Path: ", os.path.abspath(file_path)) 75 | print("File exists: ", os.path.exists(file_path)) 76 | print("Parent directory: ", os.path.dirname(file_path)) 77 | print("Parent directory: {} | File name: {}".format( 78 | *os.path.split(file_path))) 79 | -------------------------------------------------------------------------------- /Chapter01/hashing.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import argparse 3 | import hashlib 4 | import os 5 | 6 | """ 7 | MIT License 8 | 9 | Copyright (c) 2017 Chapin Bryce, Preston Miller 10 | 11 | Please share comments and questions at: 12 | https://github.com/PythonForensics/PythonForensicsCookbook 13 | or email pyforcookbook@gmail.com 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy 16 | of this software and associated documentation files (the "Software"), to deal 17 | in the Software without restriction, including without limitation the rights 18 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 | copies of the Software, and to permit persons to whom the Software is 20 | furnished to do so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in all 23 | copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 | SOFTWARE. 32 | """ 33 | 34 | __authors__ = ["Chapin Bryce", "Preston Miller"] 35 | __date__ = 20170815 36 | __description__ = "Script to hash a file's name and contents" 37 | 38 | available_algorithms = { 39 | "md5": hashlib.md5, 40 | "sha1": hashlib.sha1, 41 | "sha256": hashlib.sha256, 42 | "sha512": hashlib.sha512 43 | } 44 | 45 | parser = argparse.ArgumentParser( 46 | description=__description__, 47 | epilog="Developed by {} on {}".format(", ".join(__authors__), __date__) 48 | ) 49 | parser.add_argument("FILE_NAME", help="Path of file to hash") 50 | parser.add_argument("ALGORITHM", help="Hash algorithm to use", 51 | choices=sorted(available_algorithms.keys())) 52 | args = parser.parse_args() 53 | 54 | input_file = args.FILE_NAME 55 | hash_alg = args.ALGORITHM 56 | 57 | file_name = available_algorithms[hash_alg]() 58 | abs_path = os.path.abspath(input_file) 59 | file_name.update(abs_path.encode()) 60 | 61 | print("The {} of the filename is: {}".format( 62 | hash_alg, file_name.hexdigest())) 63 | 64 | file_content = available_algorithms[hash_alg]() 65 | with open(input_file, 'rb') as open_file: 66 | buff_size = 1024 67 | buff = open_file.read(buff_size) 68 | 69 | while buff: 70 | file_content.update(buff) 71 | buff = open_file.read(buff_size) 72 | 73 | print("The {} of the content is: {}".format( 74 | hash_alg, file_content.hexdigest())) 75 | -------------------------------------------------------------------------------- /Chapter01/logging_recipe.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import logging 3 | import sys 4 | 5 | """ 6 | MIT License 7 | 8 | Copyright (c) 2017 Chapin Bryce, Preston Miller 9 | 10 | Please share comments and questions at: 11 | https://github.com/PythonForensics/PythonForensicsCookbook 12 | or email pyforcookbook@gmail.com 13 | 14 | Permission is hereby granted, free of charge, to any person obtaining a copy 15 | of this software and associated documentation files (the "Software"), to deal 16 | in the Software without restriction, including without limitation the rights 17 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 18 | copies of the Software, and to permit persons to whom the Software is 19 | furnished to do so, subject to the following conditions: 20 | 21 | The above copyright notice and this permission notice shall be included in all 22 | copies or substantial portions of the Software. 23 | 24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 29 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 | SOFTWARE. 31 | """ 32 | 33 | logger = logging.getLogger(__file__) 34 | logger.setLevel(logging.DEBUG) 35 | 36 | msg_fmt = logging.Formatter("%(asctime)-15s %(funcName)-20s" 37 | "%(levelname)-8s %(message)s") 38 | 39 | strhndl = logging.StreamHandler(sys.stdout) 40 | strhndl.setFormatter(fmt=msg_fmt) 41 | 42 | fhndl = logging.FileHandler(__file__ + ".log", mode='a') 43 | fhndl.setFormatter(fmt=msg_fmt) 44 | 45 | logger.addHandler(strhndl) 46 | logger.addHandler(fhndl) 47 | 48 | logger.info("information message") 49 | logger.debug("debug message") 50 | 51 | 52 | def function_one(): 53 | logger.warning("warning message") 54 | 55 | 56 | def function_two(): 57 | logger.error("error message") 58 | 59 | 60 | function_one() 61 | function_two() 62 | -------------------------------------------------------------------------------- /Chapter01/multiproc_example.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import logging 3 | import multiprocessing as mp 4 | from random import randint 5 | import sys 6 | import time 7 | 8 | """ 9 | MIT License 10 | 11 | Copyright (c) 2017 Chapin Bryce, Preston Miller 12 | 13 | Please share comments and questions at: 14 | https://github.com/PythonForensics/PythonForensicsCookbook 15 | or email pyforcookbook@gmail.com 16 | 17 | Permission is hereby granted, free of charge, to any person obtaining a copy 18 | of this software and associated documentation files (the "Software"), to deal 19 | in the Software without restriction, including without limitation the rights 20 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 21 | copies of the Software, and to permit persons to whom the Software is 22 | furnished to do so, subject to the following conditions: 23 | 24 | The above copyright notice and this permission notice shall be included in all 25 | copies or substantial portions of the Software. 26 | 27 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 28 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 29 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 30 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 31 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 32 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 33 | SOFTWARE. 34 | """ 35 | 36 | 37 | def sleepy(seconds): 38 | proc_name = mp.current_process().name 39 | logger.info("{} is sleeping for {} seconds.".format( 40 | proc_name, seconds)) 41 | time.sleep(seconds) 42 | 43 | 44 | logger = logging.getLogger(__file__) 45 | logger.setLevel(logging.DEBUG) 46 | msg_fmt = logging.Formatter("%(asctime)-15s %(funcName)-7s " 47 | "%(levelname)-8s %(message)s") 48 | strhndl = logging.StreamHandler(sys.stdout) 49 | strhndl.setFormatter(fmt=msg_fmt) 50 | logger.addHandler(strhndl) 51 | 52 | num_workers = 5 53 | workers = [] 54 | for w in range(num_workers): 55 | p = mp.Process(target=sleepy, args=(randint(1, 20),)) 56 | p.start() 57 | workers.append(p) 58 | 59 | for worker in workers: 60 | worker.join() 61 | logger.info("Joined process {}".format(worker.name)) 62 | -------------------------------------------------------------------------------- /Chapter01/os_walk.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import argparse 3 | import os 4 | 5 | """ 6 | MIT License 7 | 8 | Copyright (c) 2017 Chapin Bryce, Preston Miller 9 | 10 | Please share comments and questions at: 11 | https://github.com/PythonForensics/PythonForensicsCookbook 12 | or email pyforcookbook@gmail.com 13 | 14 | Permission is hereby granted, free of charge, to any person obtaining a copy 15 | of this software and associated documentation files (the "Software"), to deal 16 | in the Software without restriction, including without limitation the rights 17 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 18 | copies of the Software, and to permit persons to whom the Software is 19 | furnished to do so, subject to the following conditions: 20 | 21 | The above copyright notice and this permission notice shall be included in all 22 | copies or substantial portions of the Software. 23 | 24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 29 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 | SOFTWARE. 31 | """ 32 | 33 | __authors__ = ["Chapin Bryce", "Preston Miller"] 34 | __date__ = 20170815 35 | __description__ = "Directory tree walker" 36 | 37 | parser = argparse.ArgumentParser( 38 | description=__description__, 39 | epilog="Developed by {} on {}".format( 40 | ", ".join(__authors__), __date__) 41 | ) 42 | parser.add_argument("DIR_PATH", help="Path to directory") 43 | args = parser.parse_args() 44 | path_to_scan = args.DIR_PATH 45 | 46 | # Iterate over the path_to_scan 47 | for root, directories, files in os.walk(path_to_scan): 48 | # Iterate over the files in the current "root" 49 | for file_entry in files: 50 | # create the relative path to the file 51 | file_path = os.path.join(root, file_entry) 52 | print(file_path) 53 | -------------------------------------------------------------------------------- /Chapter01/progressbars.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | from time import sleep 3 | import tqdm 4 | 5 | """ 6 | MIT License 7 | 8 | Copyright (c) 2017 Chapin Bryce, Preston Miller 9 | 10 | Please share comments and questions at: 11 | https://github.com/PythonForensics/PythonForensicsCookbook 12 | or email pyforcookbook@gmail.com 13 | 14 | Permission is hereby granted, free of charge, to any person obtaining a copy 15 | of this software and associated documentation files (the "Software"), to deal 16 | in the Software without restriction, including without limitation the rights 17 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 18 | copies of the Software, and to permit persons to whom the Software is 19 | furnished to do so, subject to the following conditions: 20 | 21 | The above copyright notice and this permission notice shall be included in all 22 | copies or substantial portions of the Software. 23 | 24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 29 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 | SOFTWARE. 31 | """ 32 | 33 | fruits = [ 34 | "Acai", "Apple", "Apricots", "Avocado", "Banana", "Blackberry", 35 | "Blueberries", "Cherries", "Coconut", "Cranberry", "Cucumber", 36 | "Durian", "Fig", "Grapefruit", "Grapes", "Kiwi", "Lemon", "Lime", 37 | "Mango", "Melon", "Orange", "Papaya", "Peach", "Pear", "Pineapple", 38 | "Pomegranate", "Raspberries", "Strawberries", "Watermelon" 39 | ] 40 | 41 | contains_berry = 0 42 | for fruit in tqdm.tqdm(fruits): 43 | if "berr" in fruit.lower(): 44 | contains_berry += 1 45 | sleep(.1) 46 | print("{} fruit names contain 'berry' or 'berries'".format(contains_berry)) 47 | 48 | contains_berry = 0 49 | pbar = tqdm.tqdm(fruits, desc="Reviewing names", unit="fruits") 50 | for fruit in pbar: 51 | if "berr" in fruit.lower(): 52 | contains_berry += 1 53 | pbar.set_postfix(hits=contains_berry) 54 | sleep(.1) 55 | print("{} fruit names contain 'berry' or 'berries'".format(contains_berry)) 56 | 57 | for i in tqdm.trange(10000000, unit_scale=True, desc="Trange: "): 58 | pass 59 | -------------------------------------------------------------------------------- /Chapter01/simple_arguments.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import argparse 3 | 4 | """ 5 | MIT License 6 | 7 | Copyright (c) 2017 Chapin Bryce, Preston Miller 8 | 9 | Please share comments and questions at: 10 | https://github.com/PythonForensics/PythonForensicsCookbook 11 | or email pyforcookbook@gmail.com 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 29 | SOFTWARE. 30 | """ 31 | 32 | __authors__ = ["Chapin Bryce", "Preston Miller"] 33 | __date__ = 20170815 34 | __description__ = 'A simple argparse example' 35 | 36 | 37 | parser = argparse.ArgumentParser( 38 | description=__description__, 39 | epilog="Developed by {} on {}".format( 40 | ", ".join(__authors__), __date__) 41 | ) 42 | 43 | parser.add_argument("INPUT_FILE", help="Path to input file") 44 | parser.add_argument("OUTPUT_FILE", help="Path to output file") 45 | 46 | parser.add_argument("--hash", help="Hash the files", action="store_true") 47 | 48 | parser.add_argument("--hash-algorithm", 49 | help="Hash algorithm to use. ie md5, sha1, sha256", 50 | choices=['md5', 'sha1', 'sha256'], default="sha256" 51 | ) 52 | 53 | parser.add_argument("-v", "--version", "--script-version", 54 | help="Displays script version information", 55 | action="version", version=str(__date__) 56 | ) 57 | 58 | parser.add_argument('-l', '--log', help="Path to log file", required=True) 59 | 60 | args = parser.parse_args() 61 | 62 | input_file = args.INPUT_FILE 63 | output_file = args.OUTPUT_FILE 64 | 65 | if args.hash: 66 | ha = args.hash_algorithm 67 | print("File hashing enabled with {} algorithm".format(ha)) 68 | if not args.log: 69 | print("Log file not defined. Will write to stdout") 70 | -------------------------------------------------------------------------------- /Chapter02/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonForensics/Python-Digital-Forensics-Cookbook/18a7bec2d70321db820b07c10bf311428efe3950/Chapter02/.DS_Store -------------------------------------------------------------------------------- /Chapter02/ftk_parser.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import argparse 3 | from datetime import datetime 4 | import os 5 | import sys 6 | import html_dashboard 7 | 8 | """ 9 | MIT License 10 | 11 | Copyright (c) 2017 Chapin Bryce, Preston Miller 12 | 13 | Please share comments and questions at: 14 | https://github.com/PythonForensics/PythonForensicsCookbook 15 | or email pyforcookbook@gmail.com 16 | 17 | Permission is hereby granted, free of charge, to any person obtaining a copy 18 | of this software and associated documentation files (the "Software"), to deal 19 | in the Software without restriction, including without limitation the rights 20 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 21 | copies of the Software, and to permit persons to whom the Software is 22 | furnished to do so, subject to the following conditions: 23 | 24 | The above copyright notice and this permission notice shall be included in all 25 | copies or substantial portions of the Software. 26 | 27 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 28 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 29 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 30 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 31 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 32 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 33 | SOFTWARE. 34 | """ 35 | 36 | __authors__ = ["Chapin Bryce", "Preston Miller"] 37 | __date__ = 20170815 38 | __description__ = "Read FTK acquisition logs into a HTML dashboard" 39 | 40 | 41 | def main(in_dir, out_dir): 42 | ftk_logs = [x for x in os.listdir(in_dir) 43 | if x.lower().endswith(".txt")] 44 | print("[+] Processing {} potential FTK Imager Logs found in {} " 45 | "directory".format(len(ftk_logs), in_dir)) 46 | ftk_data = [] 47 | for log in ftk_logs: 48 | log_data = {"e_numb": "", "custodian": "", "type": "", 49 | "date": "", "size": ""} 50 | log_name = os.path.join(in_dir, log) 51 | if validate_ftk(log_name): 52 | with open(log_name) as log_file: 53 | bps, sec_count = (None, None) 54 | for line in log_file: 55 | if "Evidence Number:" in line: 56 | log_data["e_numb"] = line.split( 57 | "Number:")[1].strip() 58 | elif "Notes:" in line: 59 | log_data["custodian"] = line.split( 60 | "Notes:")[1].strip() 61 | elif "Image Type:" in line: 62 | log_data["type"] = line.split("Type:")[1].strip() 63 | elif "Acquisition started:" in line: 64 | acq = line.split("started:")[1].strip() 65 | date = datetime.strptime( 66 | acq, "%a %b %d %H:%M:%S %Y") 67 | log_data["date"] = date.strftime( 68 | "%M/%d/%Y %H:%M:%S") 69 | elif "Bytes per Sector:" in line: 70 | bps = int(line.split("Sector:")[1].strip()) 71 | elif "Sector Count:" in line: 72 | sec_count = int( 73 | line.split("Count:")[1].strip().replace( 74 | ",", "") 75 | ) 76 | if bps is not None and sec_count is not None: 77 | log_data["size"] = calculate_size(bps, sec_count) 78 | 79 | ftk_data.append( 80 | [log_data["e_numb"], log_data["custodian"], 81 | log_data["type"], log_data["date"], log_data["size"]] 82 | ) 83 | 84 | print("[+] Creating HTML dashboard based acquisition logs " 85 | "in {}".format(out_dir)) 86 | html_dashboard.process_data(ftk_data, out_dir) 87 | 88 | 89 | def validate_ftk(log_file): 90 | with open(log_file) as log: 91 | first_line = log.readline() 92 | if "Created By AccessData" not in first_line: 93 | return False 94 | else: 95 | return True 96 | 97 | 98 | def calculate_size(bytes, sectors): 99 | return (bytes * sectors) / (1024**3) 100 | 101 | 102 | if __name__ == "__main__": 103 | # Command-line Argument Parser 104 | parser = argparse.ArgumentParser( 105 | description=__description__, 106 | epilog="Developed by {} on {}".format( 107 | ", ".join(__authors__), __date__) 108 | ) 109 | parser.add_argument("INPUT_DIR", help="Input Directory of Logs") 110 | parser.add_argument("OUTPUT_DIR", help="Desired Output Path") 111 | args = parser.parse_args() 112 | 113 | if os.path.exists(args.INPUT_DIR) and os.path.isdir(args.INPUT_DIR): 114 | main(args.INPUT_DIR, args.OUTPUT_DIR) 115 | else: 116 | print("[-] Supplied input directory {} does not exist or is not " 117 | "a file".format(args.INPUT_DIR)) 118 | sys.exit(1) 119 | -------------------------------------------------------------------------------- /Chapter02/light-bootstrap-dashboard/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonForensics/Python-Digital-Forensics-Cookbook/18a7bec2d70321db820b07c10bf311428efe3950/Chapter02/light-bootstrap-dashboard/.DS_Store -------------------------------------------------------------------------------- /Chapter02/light-bootstrap-dashboard/LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Creative Tim 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Chapter02/light-bootstrap-dashboard/README.md: -------------------------------------------------------------------------------- 1 | # [Light Bootstrap Dashboard](http://www.creative-tim.com/product/light-bootstrap-dashboard) 2 | 3 | ![alt text](http://s3.amazonaws.com/creativetim_bucket/products/32/original/opt_lbd_thumbnail.jpg "Light Bootstrap Dashboard") 4 | 5 | Light Bootstrap Dashboard is an admin dashboard template designed to be beautiful and simple. It is built on top of Bootstrap 3 and it is fully responsive. It comes with a big collections of elements that will offer you multiple possibilities to create the app that best fits your needs. It can be used to create admin panels, project management systems, web applications backend, CMS or CRM. 6 | 7 | The product represents a big suite of front-end developer tools that can help you jump start your project. We have created it thinking about things you actually need in a dashboard. Light Bootstrap Dashboard contains multiple handpicked and optimised plugins. Everything is designed to fit with one another. As you will be able to see, the dashboard you can access on Creative Tim is a customisation of this product. 8 | 9 | It comes with 6 filter colors for the sidebar (“black”, “azure”,”green”,”orange”,”red”,”purple”) and an option to have a background image. 10 | 11 | Special thanks go to: 12 | Robert McIntosh for the notification system 13 | Chartist for the wonderful charts 14 | We are very excited to share this dashboard with you and we look forward to hearing your feedback! 15 | 16 | ## Links: 17 | 18 | + [Live Preview](http://demos.creative-tim.com/light-bootstrap-dashboard) 19 | + [Video Tutorial](https://www.youtube.com/watch?v=c3M3NQtFyqM) 20 | + [Light Bootstrap Dashboard PRO](http://www.creative-tim.com/product/light-bootstrap-dashboard-pro) (from $39) 21 | 22 | ## Quick start 23 | 24 | Quick start options: 25 | 26 | - [Download from Github](https://github.com/creativetimofficial/light-bootstrap-dashboard.git). 27 | - [Download from Creative Tim](http://www.creative-tim.com/product/light-bootstrap-dashboard). 28 | - Clone the repo: `git clone https://github.com/creativetimofficial/light-bootstrap-dashboard.git`. 29 | 30 | 31 | ### What's included 32 | 33 | Within the download you'll find the following directories and files: 34 | 35 | ``` 36 | x_lbd_free/ 37 | ├── assets/ 38 | | ├── css/ 39 | | | ├── animate.min.css 40 | | | ├── bootstrap.min.css 41 | | | ├── demo.css 42 | │ | ├── light-bootstrap-dashboard.css 43 | │ | └── pe-icon-7-stroke.css 44 | | ├── js/ 45 | | | ├── bootstrap-checkbox-radio-switch.js 46 | | | ├── bootstrap-notify.js 47 | | | ├── bootstrap-select.js 48 | | | ├── bootstrap.min.js 49 | │ | ├── chartist.min.js 50 | │ | ├── demo.js 51 | │ | ├── jquery-1.10.2.js 52 | │ | └── light-bootstrap-dashboard.js 53 | | ├── fonts/ 54 | | | ├── Pe-icon-7-stroke.eot 55 | | | ├── Pe-icon-7-stroke.svg 56 | | | ├── Pe-icon-7-stroke.ttf 57 | | | └── Pe-icon-7-stroke.woff 58 | | └── img/ 59 | | 60 | ├── Creative Tim License.pdf 61 | ├── dashboard.html 62 | ├── icons.html 63 | ├── maps.html 64 | ├── notifications.html 65 | ├── table.html 66 | ├── template.html 67 | ├── typography.html 68 | ├── upgrade.html 69 | └── user.html 70 | 71 | ``` 72 | 73 | ### Version logs 74 | 75 | V1.0 - 20 August 2015 initial release 76 | 77 | V1.1 - 08 September 2015 - bug fixing [current version] 78 | - added company name/logo inside the sidebar for small screens 79 | - fixed bug for notification with close button on small screens 80 | - fix live preview bug for download on small screens 81 | - fix table responsive for small screens 82 | - added new labels for chartist on small screens 83 | 84 | V1.2 - 17 January 2016 - New Page 85 | - for those who want to upsell inside their dashboard we added a new page "Upgrade to PRO" with a pricing and options table 86 | 87 | V1.3 - 22 January 2016 - New Template page + Video Tutorial 88 | - added the default template page + youtube video tutorial on how to create an Admin Template (link coming soon) 89 | 90 | V1.3.1 - 19 January 2017 [current version] 91 | - switched to MIT license 92 | 93 | ### License 94 | 95 | - Copyright 2017 Creative Tim (http://www.creative-tim.com) 96 | - Licensed under MIT (https://github.com/creativetimofficial/light-bootstrap-dashboard/blob/master/LICENSE.md) 97 | 98 | ## Useful Links 99 | 100 | More products from Creative Tim: 101 | 102 | Tutorials: 103 | 104 | Freebies: 105 | 106 | Affiliate Program (earn money): 107 | 108 | Social Media: 109 | 110 | Twitter: 111 | 112 | Facebook: 113 | 114 | Dribbble: 115 | 116 | Google+: 117 | 118 | Instagram: 119 | -------------------------------------------------------------------------------- /Chapter02/light-bootstrap-dashboard/assets/css/demo.css: -------------------------------------------------------------------------------- 1 | @media (min-width: 992px){ 2 | .typo-line{ 3 | padding-left: 140px; 4 | margin-bottom: 40px; 5 | position: relative; 6 | } 7 | 8 | .typo-line .category{ 9 | transform: translateY(-50%); 10 | top: 50%; 11 | left: 0px; 12 | position: absolute; 13 | } 14 | } 15 | 16 | .all-icons [class*="pe-"]{ 17 | font-size: 40px; 18 | } 19 | .all-icons input{ 20 | border: 0; 21 | } 22 | .all-icons .font-icon-detail{ 23 | text-align: center; 24 | padding: 45px 0px 30px; 25 | border: 1px solid #e5e5e5; 26 | border-radius: 6px; 27 | margin: 15px 0; 28 | } 29 | .all-icons .font-icon-detail input{ 30 | margin: 25px auto 0; 31 | width: 100%; 32 | text-align: center; 33 | display: block; 34 | color: #aaa; 35 | font-size: 13px; 36 | } 37 | 38 | #map{ 39 | position:relative; 40 | width:100%; 41 | height: calc(100% - 60px); 42 | } 43 | 44 | .places-buttons .btn{ 45 | margin-bottom: 30px 46 | } 47 | .sidebar .nav > li.active-pro{ 48 | position: absolute; 49 | width: 100%; 50 | bottom: 10px; 51 | } 52 | .sidebar .nav > li.active-pro a{ 53 | background: rgba(255, 255, 255, 0.14); 54 | opacity: 1; 55 | color: #FFFFFF; 56 | } 57 | 58 | .table-upgrade td:nth-child(2), 59 | .table-upgrade td:nth-child(3){ 60 | text-align: center; 61 | } 62 | -------------------------------------------------------------------------------- /Chapter02/light-bootstrap-dashboard/assets/fonts/Pe-icon-7-stroke.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonForensics/Python-Digital-Forensics-Cookbook/18a7bec2d70321db820b07c10bf311428efe3950/Chapter02/light-bootstrap-dashboard/assets/fonts/Pe-icon-7-stroke.eot -------------------------------------------------------------------------------- /Chapter02/light-bootstrap-dashboard/assets/fonts/Pe-icon-7-stroke.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonForensics/Python-Digital-Forensics-Cookbook/18a7bec2d70321db820b07c10bf311428efe3950/Chapter02/light-bootstrap-dashboard/assets/fonts/Pe-icon-7-stroke.ttf -------------------------------------------------------------------------------- /Chapter02/light-bootstrap-dashboard/assets/fonts/Pe-icon-7-stroke.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonForensics/Python-Digital-Forensics-Cookbook/18a7bec2d70321db820b07c10bf311428efe3950/Chapter02/light-bootstrap-dashboard/assets/fonts/Pe-icon-7-stroke.woff -------------------------------------------------------------------------------- /Chapter02/light-bootstrap-dashboard/assets/img/default-avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonForensics/Python-Digital-Forensics-Cookbook/18a7bec2d70321db820b07c10bf311428efe3950/Chapter02/light-bootstrap-dashboard/assets/img/default-avatar.png -------------------------------------------------------------------------------- /Chapter02/light-bootstrap-dashboard/assets/img/faces/face-0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonForensics/Python-Digital-Forensics-Cookbook/18a7bec2d70321db820b07c10bf311428efe3950/Chapter02/light-bootstrap-dashboard/assets/img/faces/face-0.jpg -------------------------------------------------------------------------------- /Chapter02/light-bootstrap-dashboard/assets/img/faces/face-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonForensics/Python-Digital-Forensics-Cookbook/18a7bec2d70321db820b07c10bf311428efe3950/Chapter02/light-bootstrap-dashboard/assets/img/faces/face-1.jpg -------------------------------------------------------------------------------- /Chapter02/light-bootstrap-dashboard/assets/img/faces/face-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonForensics/Python-Digital-Forensics-Cookbook/18a7bec2d70321db820b07c10bf311428efe3950/Chapter02/light-bootstrap-dashboard/assets/img/faces/face-2.jpg -------------------------------------------------------------------------------- /Chapter02/light-bootstrap-dashboard/assets/img/faces/face-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonForensics/Python-Digital-Forensics-Cookbook/18a7bec2d70321db820b07c10bf311428efe3950/Chapter02/light-bootstrap-dashboard/assets/img/faces/face-3.jpg -------------------------------------------------------------------------------- /Chapter02/light-bootstrap-dashboard/assets/img/faces/face-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonForensics/Python-Digital-Forensics-Cookbook/18a7bec2d70321db820b07c10bf311428efe3950/Chapter02/light-bootstrap-dashboard/assets/img/faces/face-4.jpg -------------------------------------------------------------------------------- /Chapter02/light-bootstrap-dashboard/assets/img/faces/face-5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonForensics/Python-Digital-Forensics-Cookbook/18a7bec2d70321db820b07c10bf311428efe3950/Chapter02/light-bootstrap-dashboard/assets/img/faces/face-5.jpg -------------------------------------------------------------------------------- /Chapter02/light-bootstrap-dashboard/assets/img/faces/face-6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonForensics/Python-Digital-Forensics-Cookbook/18a7bec2d70321db820b07c10bf311428efe3950/Chapter02/light-bootstrap-dashboard/assets/img/faces/face-6.jpg -------------------------------------------------------------------------------- /Chapter02/light-bootstrap-dashboard/assets/img/faces/face-7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonForensics/Python-Digital-Forensics-Cookbook/18a7bec2d70321db820b07c10bf311428efe3950/Chapter02/light-bootstrap-dashboard/assets/img/faces/face-7.jpg -------------------------------------------------------------------------------- /Chapter02/light-bootstrap-dashboard/assets/img/faces/tim_vector.jpe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonForensics/Python-Digital-Forensics-Cookbook/18a7bec2d70321db820b07c10bf311428efe3950/Chapter02/light-bootstrap-dashboard/assets/img/faces/tim_vector.jpe -------------------------------------------------------------------------------- /Chapter02/light-bootstrap-dashboard/assets/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonForensics/Python-Digital-Forensics-Cookbook/18a7bec2d70321db820b07c10bf311428efe3950/Chapter02/light-bootstrap-dashboard/assets/img/favicon.ico -------------------------------------------------------------------------------- /Chapter02/light-bootstrap-dashboard/assets/img/loading-bubbles.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 9 | 10 | 11 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Chapter02/light-bootstrap-dashboard/assets/img/mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonForensics/Python-Digital-Forensics-Cookbook/18a7bec2d70321db820b07c10bf311428efe3950/Chapter02/light-bootstrap-dashboard/assets/img/mask.png -------------------------------------------------------------------------------- /Chapter02/light-bootstrap-dashboard/assets/img/new_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonForensics/Python-Digital-Forensics-Cookbook/18a7bec2d70321db820b07c10bf311428efe3950/Chapter02/light-bootstrap-dashboard/assets/img/new_logo.png -------------------------------------------------------------------------------- /Chapter02/light-bootstrap-dashboard/assets/img/sidebar-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonForensics/Python-Digital-Forensics-Cookbook/18a7bec2d70321db820b07c10bf311428efe3950/Chapter02/light-bootstrap-dashboard/assets/img/sidebar-1.jpg -------------------------------------------------------------------------------- /Chapter02/light-bootstrap-dashboard/assets/img/sidebar-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonForensics/Python-Digital-Forensics-Cookbook/18a7bec2d70321db820b07c10bf311428efe3950/Chapter02/light-bootstrap-dashboard/assets/img/sidebar-2.jpg -------------------------------------------------------------------------------- /Chapter02/light-bootstrap-dashboard/assets/img/sidebar-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonForensics/Python-Digital-Forensics-Cookbook/18a7bec2d70321db820b07c10bf311428efe3950/Chapter02/light-bootstrap-dashboard/assets/img/sidebar-3.jpg -------------------------------------------------------------------------------- /Chapter02/light-bootstrap-dashboard/assets/img/sidebar-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonForensics/Python-Digital-Forensics-Cookbook/18a7bec2d70321db820b07c10bf311428efe3950/Chapter02/light-bootstrap-dashboard/assets/img/sidebar-4.jpg -------------------------------------------------------------------------------- /Chapter02/light-bootstrap-dashboard/assets/img/sidebar-5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonForensics/Python-Digital-Forensics-Cookbook/18a7bec2d70321db820b07c10bf311428efe3950/Chapter02/light-bootstrap-dashboard/assets/img/sidebar-5.jpg -------------------------------------------------------------------------------- /Chapter02/light-bootstrap-dashboard/assets/img/tim_80x80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PythonForensics/Python-Digital-Forensics-Cookbook/18a7bec2d70321db820b07c10bf311428efe3950/Chapter02/light-bootstrap-dashboard/assets/img/tim_80x80.png -------------------------------------------------------------------------------- /Chapter02/light-bootstrap-dashboard/assets/js/light-bootstrap-dashboard.js: -------------------------------------------------------------------------------- 1 | /*! 2 | 3 | ========================================================= 4 | * Light Bootstrap Dashboard - v1.3.1.0 5 | ========================================================= 6 | 7 | * Product Page: http://www.creative-tim.com/product/light-bootstrap-dashboard 8 | * Copyright 2017 Creative Tim (http://www.creative-tim.com) 9 | * Licensed under MIT (https://github.com/creativetimofficial/light-bootstrap-dashboard/blob/master/LICENSE.md) 10 | 11 | ========================================================= 12 | 13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | 15 | */ 16 | 17 | var searchVisible = 0; 18 | var transparent = true; 19 | 20 | var transparentDemo = true; 21 | var fixedTop = false; 22 | 23 | var navbar_initialized = false; 24 | 25 | $(document).ready(function(){ 26 | window_width = $(window).width(); 27 | 28 | // check if there is an image set for the sidebar's background 29 | lbd.checkSidebarImage(); 30 | 31 | // Init navigation toggle for small screens 32 | if(window_width <= 991){ 33 | lbd.initRightMenu(); 34 | } 35 | 36 | // Activate the tooltips 37 | $('[rel="tooltip"]').tooltip(); 38 | 39 | // Activate the switches with icons 40 | if($('.switch').length != 0){ 41 | $('.switch')['bootstrapSwitch'](); 42 | } 43 | // Activate regular switches 44 | if($("[data-toggle='switch']").length != 0){ 45 | $("[data-toggle='switch']").wrap('
').parent().bootstrapSwitch(); 46 | } 47 | 48 | $('.form-control').on("focus", function(){ 49 | $(this).parent('.input-group').addClass("input-group-focus"); 50 | }).on("blur", function(){ 51 | $(this).parent(".input-group").removeClass("input-group-focus"); 52 | }); 53 | 54 | // Fixes sub-nav not working as expected on IOS 55 | $('body').on('touchstart.dropdown', '.dropdown-menu', function (e) { e.stopPropagation(); }); 56 | }); 57 | 58 | // activate collapse right menu when the windows is resized 59 | $(window).resize(function(){ 60 | if($(window).width() <= 991){ 61 | lbd.initRightMenu(); 62 | } 63 | }); 64 | 65 | lbd = { 66 | misc:{ 67 | navbar_menu_visible: 0 68 | }, 69 | 70 | checkSidebarImage: function(){ 71 | $sidebar = $('.sidebar'); 72 | image_src = $sidebar.data('image'); 73 | 74 | if(image_src !== undefined){ 75 | sidebar_container = '