Mastering Python Forensics - Sample Chapter
Mastering Python Forensics - Sample Chapter
ee
P U B L I S H I N G
C o m m u n i t y
$ 39.99 US
25.99 UK
pl
Mastering Python
Forensics
Sa
m
E x p e r i e n c e
Mastering Python
Forensics
Master the art of digital forensics and analysis with Python
D i s t i l l e d
Dr. Johann Uhrmann holds a degree in computer science from the University of
Applied Sciences Landshut and a doctor of engineering from the University of the
German Federal Armed Forces. He has more than ten years of experience in software
development, which includes working for start-ups, institutional research, and
corporate environment. Johann has several years of experience in incident handling
and IT governance, focusing on Linux and Cloud environments.
Preface
Today, information technology is a part of almost everything that surrounds us.
These are the systems that we wear and that support us in building and running
cities, companies, our personal online shopping tours, and our friendships. These
systems are attractive to useand abuse. Consequently, all criminal fields such
as theft, fraud, blackmailing, and so on expanded to the IT. Nowadays, this is a
multi-billion, criminal, global shadow industry.
Can a single person spot traces of criminal or suspicious activity conducted by
a multi-billion, criminal, global shadow industry? Well, sometimes you can.
To analyze the modern crime, you do not need magnifying glasses and lifting
fingerprints off wine bottles. Instead, we will see how to apply your Python skills
to get a close look at the most promising spots on a file system and take digital
fingerprints from the traces left behind by hackers.
As authors, we believe in the strength of examples over dusty theory. This is why
we provide samples for forensic tooling and scripts, which are short enough to be
understood by the average Python programmer, yet usable tools and building blocks
for real-world IT forensics.
Are you ready to turn suspicion into hard facts?
Preface
Chapter 2, Forensic Algorithms, provides you with the digital equivalent of taking
fingerprints. Just like in the case of classic fingerprints, we will show you how to
compare the digital fingerprints with a huge registry of the known good and bad
samples. This will support you in focusing your analysis and providing a proof of
forensical soundness.
Chapter 3, Using Python for Windows and Linux Forensics, is the first step on your
journey to understanding digital evidence. We will provide examples to detect signs
of compromise on Windows and Linux systems. We will conclude the chapter with
an example on how to use machine learning algorithms in the forensic analysis.
Chapter 4, Using Python for Network Forensics, is all about capturing and analyzing
network traffic. With the provided tools, you can search and analyze the network
traffic for signs of exfiltration or signature of malware communication.
Chapter 5, Using Python for Virtualization Forensics, explains how modern virtualization
concepts can be used by the attacker and forensic analyst. Consequently, we will
show how to find traces of malicious behavior on the hypervisor level and utilize the
virtualization layer as a reliable source of forensic data.
Chapter 6, Using Python for Mobile Forensics, will give you an insight on how to
retrieve and analyze forensic data from mobile devices. The examples will include
analyzing Android devices as well as Apple iOS devices.
Chapter 7, Using Python for Memory Forensics, demonstrates how to retrieve memory
snapshots and analyze these RAM images forensically with Linux and Android.
With the help of tools such as LiME and Volatility, we will demonstrate how to
extract information from the system memory.
[ 111 ]
The preservation of data from hard disks is, in most cases, a simple and well-known
procedure. An investigator removes the hard disk from the computer or notebook,
connects it to his workstation with the help of a write blocker (for example, Tableau
TK35) and starts analyzing it with well-known and certified software solutions.
When comparing this to the smartphone world, it becomes clear that there is no such
procedure. Nearly every smartphone has its own way to build its storage in and
ongoing with this, for each smartphone, the investigator needs their own way to get
the dump of the storage. While it is very hard to get the data from a smartphone,
one can get much more data with reference to the diversity of the data. Smartphones
store, besides the usual data (for example, pictures and documents), the data such as
GPS coordinates and the position of a mobile cell that the smartphone was connected
to before it was switched off.
Considering the resulting opportunities, it turns out that it is worth the extra expense
for an investigator.
In this chapter, we will cover the following topics:
Incident Alerts or Accusation: The accusation is the start signal for the
whole process. In this phase, the sources are evaluated and detailed
inquiries are requested.
[ 112 ]
Chapter 6
Preservation: When securing the evidence, it has to be ensured that these are
not modified. This is why all the evidence is documented, photographed,
sealed, and afterwards locked away. In the case of digital evidence, this
means that copies of evidence are created first; further investigation is
done only on the copies. To prove the authenticity of copies of evidence,
cryptographic hash functions are used. Most often, this is the hardest part
in mobile phone forensics due to the fact that creating one-to-one copies is
not possible for some type of phones. We will show, in the following section,
how to create backups that can be used during the investigation.
[ 113 ]
Recovery: Eoghan Casey describes the retrieval as throwing out a large net. In
particular, this phase includes the retrieval of evidence that has been deleted,
hidden, masked, or made inaccessible in any other way. It is recommended
that you make use of synergies with other evidence. For example, it is
reasonable to test whether a note with passwords has been found at the crime
scene in case the encrypted data needs to be read.
Analysis: This phase includes the detailed analysis regarding the file content.
Among others, connections between data and persons have to be drawn
in order to determine the responsible person. Moreover, the evaluation
of the content and context is made according to the means, motivation,
and opportunity. In this step, experiments are helpful to determine
undocumented behavior and develop new methods. All results need to be
tested and should be testable with scientific methodology.
Reporting: The report is not only to present results but also demonstrate
how one has arrived to the stated results. For this, all considered rules and
standards should be documented. In addition, all drawn conclusions need to
be justified and alternative explanation models need to be discussed.
[ 114 ]
Chapter 6
By looking at the previously described process, one can see only little changes
when dealing with smartphones unlike other types of evidence. However, it is very
important for an investigator to understand at what steps he has to take special care.
Android
The first mobile operating system that we will examine with the help of Python is
Android. In the first subsection, we will demonstrate how to manually examine the
smartphone, followed by an automatic approach using ADEL. Last but not least, we
will demonstrate how to merge data from the analysis to create movement profiles.
Manual Examination
The first step is getting root access to the smartphone. This is required to circumvent
internal system protections and get access to all data. Getting root access is different
for most of the phones and strongly dependent on the OS version. The best way
is creating your own recovery image and booting the phone through the built-in
recovery mode.
After getting the root access, the next step is trying to get the screen lock in plain text
as this secret is often used for different protections (for example, the screen lock can
be used as an application password for an app on the phone). Breaking the screen
lock for a PIN or password can be done with the following script:
import os, sys, subprocess, binascii, struct
import sqlite3 as lite
def get_sha1hash(backup_dir):
# dumping the password/pin from the device
print "Dumping PIN/Password hash ..."
password = subprocess.Popen(['adb', 'pull', '/data/system/
password.key', backup_dir],
stdout=subprocess.PIPE, stdin=subprocess.PIPE,
stderr=subprocess.PIPE)
password.wait()
# cutting the HASH within password.key
[ 115 ]
Chapter 6
hash_salt = sha1hash + ':' + salt
crack.write(hash_salt)
crack.close()
if __name__ == '__main__':
# check if device is connected and adb is running as root
if subprocess.Popen(['adb', 'get-state'], stdout=subprocess.PIPE).
communicate(0)[0].split("\n")[0] == "unknown":
print "no device connected - exiting..."
sys.exit(2)
# starting to create the output directory and the crack file used
for hashcat
backup_dir = sys.argv[1]
try:
os.stat(backup_dir)
except:
os.mkdir(backup_dir)
sha1hash = get_sha1hash(backup_dir)
salt = get_salt(backup_dir)
write_crack(salt, sha1hash, backup_dir)
This script generates a file called crack.hash that can be used to feed hashcat to
brute force the screen lock. If the smartphone owner has used a 4-digit PIN, the
command to execute hashcat is as follows:
user@lab:~$ ./hashcat -a 3 -m 110 out/crack.hash -1 ?d ?1?1?1?1
Initializing hashcat v0.50 with 4 threads and 32mb segment-size...
c87226fed37977772be870d722c449f915844922:256c05b54b73308b:0420
By looking at the marked line in the output, you can see the sha256 hash followed by
the salt and the brute forced PIN that is used to unlock the screen.
If the smartphone user has used a gesture to unlock the smartphone, you can use a
pre-generated rainbow table and the following script:
import hashlib, sqlite3, array, datetime
from binascii import hexlify
SQLITE_DB = "GestureRainbowTable.db"
def crack(backup_dir):
# dumping the system file containing the hash
print "Dumping gesture.key ..."
saltdb = subprocess.Popen(['adb', 'pull', '/data/system/gesture.
key', backup_dir],
stdout=subprocess.PIPE, stdin=subprocess.PIPE,
stderr=subprocess.PIPE)
gesturehash = open(backup_dir + "/gesture.key", "rb").readline()
lookuphash = hexlify(gesturehash).decode()
print "HASH: \033[0;32m" + lookuphash + "\033[m"
conn = sqlite3.connect(SQLITE_DB)
cur = conn.cursor()
cur.execute("SELECT pattern FROM RainbowTable WHERE hash = ?",
(lookuphash,))
gesture = cur.fetchone()[0]
return gesture
if __name__ == '__main__':
# check if device is connected and adb is running as root
[ 118 ]
Chapter 6
if subprocess.Popen(['adb', 'get-state'], stdout=subprocess.PIPE).
communicate(0)[0].split("\n")[0] == "unknown":
print "no device connected - exiting..."
sys.exit(2)
# starting to create the output directory and the crack file used
for hashcat
backup_dir = sys.argv[1]
try:
os.stat(backup_dir)
except:
os.mkdir(backup_dir)
gesture = crack(backup_dir)
print "screenlock gesture: \033[0;32m" + gesture + "\033[m""
The next thing that could be very important when looking for potentially infected
devices is a list of installed apps and their hashes to check them against AndroTotal
or Mobile-Sandbox. This can be done with the following script:
import os, sys, subprocess, hashlib
def get_apps():
# dumping the list of installed apps from the device
print "Dumping apps meta data ..."
meta = subprocess.Popen(['adb', 'shell', 'ls', '-l', '/data/app'],
stdout=subprocess.PIPE, stdin=subprocess.PIPE,
stderr=subprocess.PIPE)
meta.wait()
apps = []
while True:
line = meta.stdout.readline()
if line != '':
name = line.split(' ')[-1].rstrip()
date = line.split(' ')[-3]
time = line.split(' ')[-2]
if name.split('.')[-1] == 'apk':
app = [name, date, time]
else:
[ 119 ]
if __name__ == '__main__':
# check if device is connected and adb is running as root
if subprocess.Popen(['adb', 'get-state'], stdout=subprocess.PIPE).
communicate(0)[0].split("\n")[0] == "unknown":
print "no device connected - exiting..."
sys.exit(2)
# starting to create the output directory
[ 120 ]
Chapter 6
backup_dir = sys.argv[1]
try:
os.stat(backup_dir)
except:
os.mkdir(backup_dir)
apps = get_apps()
dump_apps(apps, backup_dir)
meta = get_hashes(apps, backup_dir)
# printing the list of installed apps
print 'Installed apps:'
for app in meta:
print "\033[0;32m" + ' '.join(app) + "\033[m"
After executing the preceding printed script, you get the following output including
important metadata:
user@lab:~$ ./get_installed_apps.py out
Installed apps:
com.android.SSLTrustKiller-1.apk 2015-05-18 17:11
52b4d6a1888a6514b62f6607cebf8c2c2aa4e4857319ec67b24be601db5243fb
com.android.chrome-2.apk 2015-06-16 20:50
191cd720626df38eaedf3301826e72330493cdeb8c45da4e309939cfe5633d61
com.android.vending-1.apk 2015-07-25 12:05
7be9f8f99e8c1a6c3be1edb01d84aba14619e3c67c14856755523413ba8e2d98
com.google.android.GoogleCamera-2.apk 2015-06-16 20:49
6936f3c17948c767550c206ff0ae0f44f1f4da0fcb85125da722e0c709787894
com.google.android.apps.authenticator2-1.apk 2015-06-05 10:14
11bcfcf1c853b1eb567c9453507c3413b09a1d70fd3085013f4a091719560ab6
...
[ 121 ]
With the help of this information, you can check the apps against online services
to know whether they are safe to use or potentially malicious. If you don't want to
submit them, then you can use the apk_analyzer.py script in combination with
Androguard to perform a quick analysis that often can reveal important information.
After getting a list of all installed apps and checking them for malicious behavior, it
can also be really helpful to get information about all partitions and mount points of
the device. This can be achieved with the following script:
import sys, subprocess
def get_partition_info():
# dumping the list of installed apps from the device
print "Dumping partition information ..."
partitions = subprocess.Popen(['adb', 'shell', 'mount'],
stdout=subprocess.PIPE, stdin=subprocess.PIPE,
stderr=subprocess.PIPE)
partitions.wait()
while True:
line = partitions.stdout.readline().rstrip()
if line != '':
print "\033[0;32m" + line + "\033[m"
else:
break
if __name__ == '__main__':
# check if device is connected and adb is running as root
if subprocess.Popen(['adb', 'get-state'], stdout=subprocess.PIPE).
communicate(0)[0].split("\n")[0] == "unknown":
print "no device connected - exiting..."
sys.exit(2)
get_partition_info()
[ 122 ]
Chapter 6
[ 123 ]
At the end of this section, we will show you how to gather more details about the
usage of the android-based smartphone. In the following example, we will use the
contacts database that also stores the phone call history. This example can easily be
adopted to get calendar entries or content from any other database of an app that is
installed on the device:
import os, sys, subprocess
import sqlite3 as lite
from prettytable import from_db_cursor
def dump_database(backup_dir):
# dumping the password/pin from the device
print "Dumping contacts database ..."
contactsDB = subprocess.Popen(['adb', 'pull', '/data/data/com.
android.providers.contacts/databases/contacts2.db',
backup_dir], stdout=subprocess.PIPE, stdin=subprocess.PIPE,
stderr=subprocess.PIPE)
contactsDB.wait()
def get_content(backup_dir):
# getting the content from the contacts database
con = lite.connect(backup_dir + '/contacts2.db')
cur = con.cursor()
cur.execute("SELECT contacts._id AS _id,contacts.custom_ringtone
AS custom_ringtone, name_raw_contact.display_name_source AS display_
name_source, name_raw_contact.display_name AS display_name, name_
raw_contact.display_name_alt AS display_name_alt, name_raw_contact.
phonetic_name AS phonetic_name, name_raw_contact.phonetic_name_style
AS phonetic_name_style, name_raw_contact.sort_key AS sort_key, name_
raw_contact.phonebook_label AS phonebook_label, name_raw_contact.
phonebook_bucket AS phonebook_bucket, name_raw_contact.sort_key_alt
AS sort_key_alt, name_raw_contact.phonebook_label_alt AS phonebook_
label_alt, name_raw_contact.phonebook_bucket_alt AS phonebook_
bucket_alt, has_phone_number, name_raw_contact_id, lookup, photo_id,
photo_file_id, CAST(EXISTS (SELECT _id FROM visible_contacts WHERE
contacts._id=visible_contacts._id) AS INTEGER) AS in_visible_group,
status_update_id, contacts.contact_last_updated_timestamp, contacts.
last_time_contacted AS last_time_contacted, contacts.send_to_voicemail
AS send_to_voicemail, contacts.starred AS starred, contacts.pinned
AS pinned, contacts.times_contacted AS times_contacted, (CASE WHEN
photo_file_id IS NULL THEN (CASE WHEN photo_id IS NULL OR photo_id=0
THEN NULL ELSE 'content://com.android.contacts/contacts/'||contacts._
[ 124 ]
Chapter 6
id|| '/photo' END) ELSE 'content://com.android.contacts/display_
photo/'||photo_file_id END) AS photo_uri, (CASE WHEN photo_id IS
NULL OR photo_id=0 THEN NULL ELSE 'content://com.android.contacts/
contacts/'||contacts._id|| '/photo' END) AS photo_thumb_uri, 0 AS
is_user_profile FROM contacts JOIN raw_contacts AS name_raw_contact
ON(name_raw_contact_id=name_raw_contact._id)")
pt = from_db_cursor(cur)
con.close()
print pt
if __name__ == '__main__':
# check if device is connected and adb is running as root
if subprocess.Popen(['adb', 'get-state'], stdout=subprocess.PIPE).
communicate(0)[0].split("\n")[0] == "unknown":
print "no device connected - exiting..."
sys.exit(2)
# starting to create the output directory
backup_dir = sys.argv[1]
try:
os.stat(backup_dir)
except:
os.mkdir(backup_dir)
dump_database(backup_dir)
get_content(backup_dir)
[ 125 ]
Extendibility: ADEL has been modularly built and contains two separate
modules: the analysis and the report module. Predefined interfaces exist
between these modules and both of them can be easily amended with the
help of additional functions. The modular structure allows you to dump and
analyse further databases of smartphones without great effort and facilitates
updates of the system in the future.
[ 126 ]
Chapter 6
ADEL makes use of Android Software Development Kit (Android SDK) to dump
database files in the investigator's machine. To extract contents that are contained
in a SQLite database file, ADEL parses the low-level data structures. After having
opened the database file that is to be parsed in the read-only mode, ADEL reads the
database header (the first 100 bytes of the file) and extracts the values for each of the
header fields. Not all, but some of the values in header fields are necessary in order
to parse the rest of the database file. An important value is the size of the pages in
the database file, which is required for parsing the B-tree structures (pagewise).
After having read the database header fields, ADEL parses the B-tree that contains
the sqlite_master table for which the first page of the database is always the
root page. The SQL CREATE statement and the page number of the B-tree root
page are extracted for each of the database tables. Additionally, the SQL CREATE
statement is further analyzed to extract the name and data type of each column of the
corresponding table.
[ 127 ]
Finally, the complete B-tree structure is parsed for each table, beginning at the B-tree
root page, which was extracted from the sqlite_master table. By following the
pointers of all of the interior pages, you can identify every leaf page of the B-tree.
Finally the row contents of each table are extracted from the cells that are found in
any leaf page that belongs to the same table B-tree.
In the following sections, we will address the report module and its functionalities.
In the current development state, the following databases are forensically treated
and parsed:
Calendar entries
SMS messages
Google-Maps
Data retrieved in this way is written to an XML file by the report module in order
to ease the further use and depiction of the data. Similar to the analysis module,
it can be easily updated regarding possible changes in future Android versions or
in underlying database schemes. Therefore, we have created different tuplefor
example, [table, row, column]to define the data that is exchanged between both
modules. If the database design changes in the future, only the tuple has to be
adapted. The report module automatically creates XML files for each data type that
is previously listed. In addition, a report is created that contains all the data extracted
from analyzed databases. With the help of an XSL file the report will be graphically
refurbished. All files created by ADEL are stored in a subfolder of the current project.
To get access to the necessary databases and system folders on the smartphone,
ADEL needs root access on the device.
[ 128 ]
Chapter 6
All you need to do is check whether the device in question is already included in
the configuration profile of ADEL that is located in /xml/phone_config.xml. If the
device is missing, there are two options on how to proceed:
1. Choose a different device with the same Android version (this will generate a
warning but it works in most of the cases).
2. Generate a new device configuration that matches the device type and
Android version of the device in question.
If you choose the second option, you can copy the configuration of an already
working device and adopt the numbers in the XML file. These numbers represent
the tables and columns of the noted database. To be a bit more precise, if you try
to adopt the SMS database, you have to check the numbers for the following tables
and columns:
<sms>
<db_name>mmssms.db</db_name>
<table_num>10</table_num>
<sms_entry_positions>
<id>0</id>
<thread_id>1</thread_id>
<address>2</address>
<person>3</person>
<date>4</date>
<read>7</read>
<type>9</type>
<subject>11</subject>
<body>12</body>
</sms_entry_positions>
</sms>
The number for the table_num tag has to be set to the number that corresponds to
the table called sms. The following numbers have to be adopted corresponding to the
columns in the sms table that are named identically. The preceding printed example
works with a Nexus 5 and Android 4.4.4. The same has to be done for all other
databases too.
[ 129 ]
Running ADEL against a rooted Nexus 5 with Android 4.4.4filled with test data
generates the following output:
user@lab:~$./adel.py -d nexus5 -l 4
_____
/
/
/
________
___________.____
\ \______ \ \_
_____/|
|
|
/_\
\ |
\ |
__)_ |
\|
\|
\|
/_______
/|_______ \
\____|__
/_______
\/
\/
|___
\/
\/
ADEL MAIN:
ADEL MAIN:
dumpDBs:
dumpDBs:
6a117 created
ADEL MAIN:
----> log file 2015-07-20__22-53-22__031c6277f0a6a117/log/
adel.log created
ADEL MAIN:
dumpDBs:
dumpDBs:
dumpDBs:
dumpDBs:
dumpDBs:
dumpDBs:
dumpDBs:
dumpDBs:
dumpDBs:
dumpDBs:
dumpDBs:
dumpDBs:
dumpDBs:
Screenlock:
----> Screenlock Hash:
6a062b9b3452e366407181a1bf92ea73e9ed4c48
[ 130 ]
Chapter 6
Screenlock:
parseDBs:
parseDBs:
parseDBs:
parseDBs:
parseDBs:
analyzeDBs:
createReport:
ADEL MAIN:
----> report 2015-07-20__22-53-22__031c6277f0a6a117/xml/
report.xml created
compareHash:
ADEL MAIN:
In this output, you can see the name of the folder where all the data is dumped
and where the generated report can be found. Additionally, you can also see the
gesture of the screen lock that was automatically extracted and compared with
a pre-generated rainbow table, as follows:
[ 131 ]
Movement profiles
In addition to data about individual communications, the EU directive from 2006
also requires certain location data to be retained by network operators. Specially,
the directive requires that the following data is retained for at least six months:
Identity and exact GPS coordinates of the radio cell where the user started a
phone call
Identity and coordinates of the radio cell that was active at the beginning of a
GPRS data transmission
[ 132 ]
Chapter 6
For performance and other reasons, mobile devices persistently store location data in
the local memory. In April 2011, it was reported that Android and iOS store sensitive
geographical data. This data, which is maintained in system cache files, is regularly
sent to platform developers. However, generating geographical data is not restricted
to the operating systemmany apps that provide location-based services also create
and store such data. For example, Benford has shown that pictures taken by an iPhone
contain the GPS coordinates of the location where the pictures were taken. Such data
is sensitive because it can be used to create movement profiles as seen in the following
figure. Unlike the location data that is retained by network operators, location data
stored on smartphones can be accessed by law enforcement via an open seizure.
Apple iOS
After we have seen how to examine an Android-based smartphone, we now want
to show you how to perform similar investigations on iOS-based devices. In the first
section, we are using a Secure Shell (SSH) connection to the device and will show
you how to get stored data from the keychain of a jailbroken iOS device.
[ 133 ]
In the second part of this section, we will use libimobiledevice. This library is a
cross-platform library that uses the protocols to support iOS-based devices and
allows you to easily access the device's filesystem, retrieve information about the
device and it's internals, backup/restore the device, manage installed applications,
retrieve PIM data as well as bookmarks, and so on. The most important fact is that
the iOS-based device does not have to be jailbroken in order to be used when
dealing with libimobiledevice.
def push_kcd(ip):
# dumping the keychain
print "Pushing the Keychain Dumper to the device ..."
kcd = subprocess.Popen(['scp', 'keychain_dumper' 'root@' + ip +
':~/'],
stdout=subprocess.PIPE, stdin=subprocess.PIPE,
stderr=subprocess.PIPE)
kcd.communicate()
Chapter 6
# pretty print keychain
kcc = subprocess.Popen(['ssh', 'root@' + ip, './keychain_dumper'],
stdout=subprocess.PIPE, stdin=subprocess.PIPE,
stderr=subprocess.PIPE)
kcc.communicate()
kcc.stdout
if __name__ == '__main__':
# starting to create the output directory
backup_dir = sys.argv[1]
try:
os.stat(backup_dir)
except:
os.mkdir(backup_dir)
# get the IP of the iDevice from user input
ip = sys.argv[2]
get_kc(ip, backup_dir)
push_kcd(ip)
exec_kcd(ip, backup_dir)
In the output of the preceding script, you can also find the password of the Apple
account that the device is registered to:
Generic Password
---------------Service: com.apple.account.AppleAccount.password
Account: 437C2D8F-****-****-****-************
Entitlement Group: apple
Label: (null)
Generic Field: (null)
Keychain Data: *************************
[ 135 ]
def get_device_info():
# getting the udid of the connected device
udid = subprocess.Popen(['idevice_id', '-l'], stdout=subprocess.
PIPE).stdout.readline().rstrip()
print "connected device: \033[0;32m" + udid + "\033[m"
return udid
def create_backup(backup_dir):
# creating a backup of the connected device
print "creating backup (this can take some time) ..."
backup = subprocess.Popen(['idevicebackup2', 'backup', backup_
dir], stdout=subprocess.PIPE)
backup.communicate()
print "backup successfully created in ./" + backup_dir + "/"
[ 136 ]
Chapter 6
backup.communicate()
print "backup successfully unpacked and ready for analysis"
def get_content(backup_dir):
# printing content of the created backup
content = subprocess.Popen(['tree', backup_dir + '/_unback_/'],
stdout=subprocess.PIPE).stdout.read()
f = open(backup_dir + '/filelist.txt', 'a+')
f.write(content)
f.close
print "list of all files and folders of the backup are stored in
./" + backup_dir + "/filelist.txt"
if __name__ == '__main__':
# check if device is connected
if subprocess.Popen(['idevice_id', '-l'], stdout=subprocess.PIPE).
communicate(0)[0].split("\n")[0] == "":
print "no device connected - exiting..."
sys.exit(2)
# starting to create the output directory
backup_dir = sys.argv[1]
try:
os.stat(backup_dir)
except:
os.mkdir(backup_dir)
udid = get_device_info()
create_backup(backup_dir)
unback_backup(udid, backup_dir)
get_content(backup_dir)
[ 137 ]
The final output of this script will look like the following extract:
user@lab:~$ ./create_ios_backup.py out
With the help of the list of files and folders, you can start the analysis of the backup
with common tools such as a plist file viewer or a SQLite browser. Searching
for Cydia App Store in this generated file can also help to identify whether the
smartphone has been jailbroken by the user or an attacker.
Summary
In this chapter, we covered the investigative process model from Eoghan Casey
and adopted it to the case of smartphones. Later, we performed an analysis of
Android smartphones in manual as well as automated ways with the help of
Python scripts and the ADEL framework. In the last section, we covered the
analysis of iOS-based smartphones.
After handling the forensic investigation of smartphones, we finished the physical
and virtual acquisition and analysis and will shift the investigation to the volatile
area of the devices in the next chapter.
[ 138 ]
www.PacktPub.com
Stay Connected: