Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Python Digital Forensics Cookbook

You're reading from   Python Digital Forensics Cookbook Effective Python recipes for digital investigations

Arrow left icon
Product type Paperback
Published in Sep 2017
Publisher Packt
ISBN-13 9781783987467
Length 412 pages
Edition 1st Edition
Languages
Tools
Concepts
Arrow right icon
Authors (2):
Arrow left icon
Chapin Bryce Chapin Bryce
Author Profile Icon Chapin Bryce
Chapin Bryce
Preston Miller Preston Miller
Author Profile Icon Preston Miller
Preston Miller
Arrow right icon
View More author details
Toc

Table of Contents (11) Chapters Close

Preface 1. Essential Scripting and File Information Recipes FREE CHAPTER 2. Creating Artifact Report Recipes 3. A Deep Dive into Mobile Forensic Recipes 4. Extracting Embedded Metadata Recipes 5. Networking and Indicators of Compromise Recipes 6. Reading Emails and Taking Names Recipes 7. Log-Based Artifact Recipes 8. Working with Forensic Evidence Container Recipes 9. Exploring Windows Forensic Artifacts Recipes - Part I 10. Exploring Windows Forensic Artifacts Recipes - Part II

Handling arguments like an adult

Recipe Difficulty: Easy

Python Version: 2.7 or 3.5

Operating System: Any

Person A: I came here for a good argument!
Person B: Ah, no you didn't, you came here for an argument!
Person A: An argument isn't just contradiction.
Person B: Well! it can be!
Person A: No it can't! An argument is a connected series of statements
intended to establish a proposition.
Person B: No it isn't!
Person A: Yes it is! It isn't just contradiction.

Monty Python (http://www.montypython.net/scripts/argument.php) aside, arguments are an integral part of any script. Arguments allow us to provide an interface for users to specify options and configurations that change the way the code behaves. Effective use of arguments, not just contradictions, can make a tool more versatile and a favorite among examiners.

Getting started

All libraries used in this script are present in Python's standard library. While there are other argument-handling libraries available, such as optparse and ConfigParser, our scripts will leverage argparse as our de facto command-line handler. While optparse was the library to use in prior versions of Python, argparse has served as the replacement for creating argument handling code. The ConfigParser library parses arguments from a configuration file instead of the command line. This is useful for code that requires a large number of arguments or has a significant number of options. We will not cover ConfigParser in this book, though it is worth exploring if you find your argparse configuration becomes difficult to maintain.

To learn more about the argparse library, visit https://docs.python.org/3/library/argparse.html.

How to do it…

In this script, we perform the following steps:

  1. Create positional and optional arguments.
  2. Add descriptions to arguments.
  3. Configure arguments with select choices.

How it works…

To begin, we import print_function and the argparse module. By importing the print_function from the __future__ library we can write print statements as they are written in Python 3.X but still run them in Python 2.X. This allows us to make recipes compatible with both Python 2.X and 3.X. Where possible, we carry this through with most recipes in the book.

After creating a few descriptive variables about the recipe, we initialize our ArgumentParser instance. Within the constructor, we define the description and epilog keyword arguments. This data will display when the user specifies the -h argument and can give the user additional context about the script being run. The argparse library is very flexible and can scale in complexity if required for a script. Throughout this book, we cover many of the library's different features, which are detailed on its document page:

from __future__ import print_function
import argparse

__authors__ = ["Chapin Bryce", "Preston Miller"]
__date__ = 20170815
__description__ = 'A simple argparse example'

parser = argparse.ArgumentParser(
description=__description__,
epilog="Developed by {} on {}".format(
", ".join(__authors__), __date__)
)

With the parser instance created, we can now begin adding arguments to our command-line handler. There are two types of arguments: positional and optional. Positional arguments start with an alphabetic character, unlike optional arguments, which start with a dash, and are required to execute the script. Optional arguments start with a single or double dash character and are non-positional (that is, the order does not matter). These characteristics can be manually specified to overwrite the default behavior we’ve described if desired. The following code block illustrates how to create two positional arguments:

# Add Positional Arguments
parser.add_argument("INPUT_FILE", help="Path to input file")
parser.add_argument("OUTPUT_FILE", help="Path to output file")

In addition to changing whether an argument is required, we can specify help information, create default values, and other actions. The help parameter is useful in conveying what the user should provide. Other important parameters are default, type, choices, and action. The default parameter allows us to set a default value, while type converts the type of the input, which is a string by default, to the specified Python object type. The choices parameter uses a defined list, dictionary, or set to create valid options the user can select from.
The action parameter specifies the type of action that should be applied to a given argument. Some common actions include store, which is the default and stores the passed value associated with the argument; store_true, which assigns True to the argument; and version, which prints the version of the code specified by the version parameter:

# Optional Arguments
parser.add_argument("--hash", help="Hash the files", action="store_true")

parser.add_argument("--hash-algorithm",
help="Hash algorithm to use. ie md5, sha1, sha256",
choices=['md5', 'sha1', 'sha256'], default="sha256"
)

parser.add_argument("-v", "--version", "--script-version",
help="Displays script version information",
action="version", version=str(__date__)
)

parser.add_argument('-l', '--log', help="Path to log file", required=True)

With our arguments defined and configured, we can now parse them and use the provided inputs in our code. The following snippet shows how we can access the values and test whether the user specified an optional argument. Notice how we refer to arguments by the name we assign them. If we specify a short and long argument name, we must use the long name:

# Parsing and using the arguments
args = parser.parse_args()

input_file = args.INPUT_FILE
output_file = args.OUTPUT_FILE

if args.hash:
ha = args.hash_algorithm
print("File hashing enabled with {} algorithm".format(ha))
if not args.log:
print("Log file not defined. Will write to stdout")

When combined into a script and executed at the command line with the -h argument, the preceding code will provide the following output:

As seen here, the -h flag displays the script help information, automatically created by argparse, along with the valid options for the --hash-algorithm argument. We can also use the -v option to display the version information. The --script-version argument displays the version in the same manner as the -v or -version arguments as shown here:

The following screenshot shows the message printed to the console when we select one of our valid hashing algorithms:

There's more…

This script can be further improved. We have provided a couple of recommendations here:

  • Explore additional argparse functionality. For example, the argparse.FileType object can be used to accept a File object as an input.
  • We can also use the argparse.ArgumentDefaultsHelpFormatter class to show defaults we set to the user. This is helpful when combined with optional arguments to show the user what will be used if nothing is specified.
You have been reading a chapter from
Python Digital Forensics Cookbook
Published in: Sep 2017
Publisher: Packt
ISBN-13: 9781783987467
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at AU $24.99/month. Cancel anytime