├── README.md
├── log-monkey.png
├── sysdiagnose-appconduit.py
├── sysdiagnose-appupdates.py
├── sysdiagnose-mobileactivation.py
├── sysdiagnose-mobilebackup.py
├── sysdiagnose-mobilecontainermanager.py
├── sysdiagnose-net-ext-cache.py
├── sysdiagnose-networkinterfaces.py
├── sysdiagnose-networkprefs.py
├── sysdiagnose-sys.py
├── sysdiagnose-uuid2path.py
├── sysdiagnose-wifi-icloud.py
├── sysdiagnose-wifi-kml.py
├── sysdiagnose-wifi-net.py
└── sysdiagnose-wifi-plist.py
/README.md:
--------------------------------------------------------------------------------
1 | # iOS_sysdiagnose_forensic_scripts
2 |
3 |
4 |
18 |
19 | It is strongly suggested that interested forensic monkeys first read the document BEFORE attempting to use these scripts.
20 | The document details the various iOS logs available, methods of generating and collecting those logs and how to use these scripts to extract forensically interesting information from them.
21 |
22 | These scripts were written for Python3 (tested under Ubuntu 16.04 and macOS X Mojave) using test data from various iOS12 devices. They do not require any third party Python libaries.
23 |
24 |
25 | Here is a usage summary of the available scripts:
26 |
27 | Name | Description | Output | Usage Example |
28 | sysdiagnose-sys.py | Extracts OS info from logs/SystemVersion/SystemVersion.plist | Command line | python3 sysdiagnose-sys.py -i SystemVersion.plist |
29 |
30 | sysdiagnose-networkprefs.py | Extracts hostnames from logs/Networking/preferences.plist | Command line | python3 sysdiagnose-networkprefs.py -i preferences.plist |
31 |
32 | sysdiagnose-networkinterfaces.py | Extracts network config info from logs/Networking/NetworkInterfaces.plist | Command line | python3 sysdiagnose-networkinterfaces.py -i NetworkInterfaces.plist |
33 |
34 | sysdiagnose-mobilecontainermanager.py | Extracts uninstall info from logs/MobileContainerManager/containermanagerd.log.0 | Command line | python3 sysdiagnose-mobilecontainermanager.py -i containermanagerd.log.0 |
35 |
36 | sysdiagnose-mobilebackup.py | Extracts backup info from logs/MobileBackup/com.apple.MobileBackup.plist | Command line | python3 sysdiagnose-mobilebackup.py -i com.apple.MobileBackup.plist |
37 |
38 | sysdiagnose-mobileactivation.py | Mobile Activation Startup and Upgrade info from logs/MobileActivation/mobileactivationd.log.* | Command line | python3 sysdiagnose-mobileactivation.py -i mobileactivation.log |
39 |
40 | sysdiagnose-wifi-plist.py | Extracts Wi-Fi network values from WiFi/com.apple.wifi.plist Use -t option for TSV output file
41 | | Command line and TSV | python3 sysdiagnose-wifi-plist.py -i com.apple.wifi.plist -t |
42 |
43 | sysdiagnose-wifi-icloud.py | Extracts Wi-Fi network values from WiFi/ICLOUD.apple.wifid.plist Use -t option for TSV output file | Command line and TSV | python3 sysdiagnose-wifi-icloud.py -i ICLOUD.apple.wifid.plist -t |
44 |
45 | sysdiagnose-wifi-net.py | Extracts Wi-Fi network names to categorized TSV files from WiFi/wifi *.log | TSV files | python3 sysdiagnose-wifi-net.py -i wifi-buf.log |
46 |
47 | sysdiagnose-wifi-kml.py | Extracts Wi-Fi geolocation values and creates a KML from wifi*.log | KML | python3 sysdiagnose-wifi-kml.py -i wifi-buf.log |
48 |
49 | sysdiagnose-uuid2path.py | Extracts GUID and path info from logs/tailspindb/UUIDToBinaryLocations | Command line (comma separated) | python3 sysdiagnose-uuid2path.py -i UUIDToBinaryLocations |
50 |
51 | sysdiagnose-net-ext-cache.py | Extracts app name & GUID info from logs/Networking/com.apple.networkextension.cache.plist Use -v option to print GUID info | Command line | python3 sysdiagnose-net-ext-cache.py -i com.apple.networkextension.cache.plist -v |
52 |
53 | sysdiagnose-appconduit.py | Extracts connection info from logs/AppConduit/AppConduit.log.* | Command line | python3 sysdiagnose-appconduit.py -i AppConduit.log |
54 |
55 | sysdiagnose-appupdates.py | Extracts update info from logs/appinstallation/AppUpdates.sqlite.db.* | Command line | python3 sysdiagnose-appupdates.py -i AppUpdates.sqlitedb |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/log-monkey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cheeky4n6monkey/iOS_sysdiagnose_forensic_scripts/21df9a41e026a61768561df2fb229506c92a1413/log-monkey.png
--------------------------------------------------------------------------------
/sysdiagnose-appconduit.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 |
3 | # For Python3
4 | # Script to print connection info from logs/AppConduit/AppConduit.log.*
5 | # Author: cheeky4n6monkey@gmail.com
6 |
7 | import sys
8 | from optparse import OptionParser
9 |
10 | version_string = "sysdiagnose-appconduit.py v2019-05-10 Version 1.0"
11 |
12 | if sys.version_info[0] < 3:
13 | print("Must be using Python 3! Exiting ...")
14 | exit(-1)
15 |
16 | print("Running " + version_string + "\n")
17 |
18 | usage = "\n%prog -i inputfile\n"
19 |
20 | parser = OptionParser(usage=usage)
21 | parser.add_option("-i", dest="inputfile",
22 | action="store", type="string",
23 | help="logs/AppConduit/AppConduit.log.* To Be Searched")
24 | (options, args) = parser.parse_args()
25 |
26 | #no arguments given by user, print help and exit
27 | if len(sys.argv) == 1:
28 | parser.print_help()
29 | exit(-1)
30 |
31 | linecount = 0
32 | connectedcount = 0
33 | resumecount = 0
34 | reunioncount = 0
35 | disconnectedcount = 0
36 | suspendcount = 0
37 |
38 | with open(options.inputfile, 'r') as fp:
39 | data = fp.readlines()
40 |
41 | for line in data:
42 | linecount += 1
43 |
44 | if '[ACXCompanionSyncConnectionManager devicesAreNowConnected:]: Device' in line:
45 | connectedcount += 1
46 | #print("\n" + line)
47 | txts = line.split()
48 | #print(txts, linecount)
49 | #print(len(txts))
50 | if(len(txts) > 10):
51 | dayofweek = txts[0]
52 | month = txts[1]
53 | day = txts[2]
54 | time = txts[3]
55 | year = txts[4]
56 | device = txts[11]
57 | print(day + " " + month + " " + year + " " + time + " - " + device + " Now Connected [line " + str(linecount) + "]")
58 | else:
59 | #malformed message ... ignore
60 | print("\nMalformed devicesAreNowConnected entry at line "+str(linecount)+"\n")
61 |
62 |
63 | if '[ACXInstallQueue reachabilityChangedForDevice:]_block_invoke: Resuming because' in line:
64 | resumecount += 1
65 | #print("\n" + line)
66 | txts = line.split()
67 | #print(txts, linecount)
68 | #print(len(txts))
69 | if(len(txts) > 11):
70 | dayofweek = txts[0]
71 | month = txts[1]
72 | day = txts[2]
73 | time = txts[3]
74 | year = txts[4]
75 | device = txts[12]
76 | print(day + " " + month + " " + year + " " + time + " - " + device + " Resuming [line " + str(linecount) + "]")
77 | else:
78 | #malformed message ... ignore
79 | print("\nMalformed Resuming entry at line "+str(linecount)+"\n")
80 |
81 |
82 | if '[ACXCompanionSyncConnection performReunionSyncWithReason:]_block_invoke: Starting reunion sync because ' in line:
83 | reunioncount += 1
84 | #print("\n" + line)
85 | txts = line.split()
86 | #print(txts, linecount)
87 | #print(len(txts))
88 | if(len(txts) > 14):
89 | dayofweek = txts[0]
90 | month = txts[1]
91 | day = txts[2]
92 | time = txts[3]
93 | year = txts[4]
94 | device = txts[15]
95 | print(day + " " + month + " " + year + " " + time + " - " + device + " Starting Reunion Sync [line " + str(linecount) + "]")
96 | else:
97 | #malformed message ... ignore
98 | print("\nMalformed Sync entry at line "+str(linecount)+"\n")
99 |
100 |
101 | if '[ACXCompanionSyncConnectionManager devicesAreNoLongerConnected:]: Device' in line:
102 | disconnectedcount += 1
103 | #print("\n" + line)
104 | txts = line.split()
105 | #print(txts, linecount)
106 | #print(len(txts))
107 | if(len(txts) > 10):
108 | dayofweek = txts[0]
109 | month = txts[1]
110 | day = txts[2]
111 | time = txts[3]
112 | year = txts[4]
113 | device = txts[11]
114 | print(day + " " + month + " " + year + " " + time + " - " + device + " Disconnected [line " + str(linecount) + "]")
115 | else:
116 | #malformed message ... ignore
117 | print("\nMalformed devicesAreNoLongerConnected entry at line "+str(linecount)+"\n")
118 |
119 | if '[ACXInstallQueue reachabilityChangedForDevice:]_block_invoke: Suspending because' in line:
120 | suspendcount += 1
121 | #print("\n" + line)
122 | txts = line.split()
123 | #print(txts, linecount)
124 | #print(len(txts))
125 | if(len(txts) > 11):
126 | dayofweek = txts[0]
127 | month = txts[1]
128 | day = txts[2]
129 | time = txts[3]
130 | year = txts[4]
131 | device = txts[12]
132 | print(day + " " + month + " " + year + " " + time + " - " + device + " Suspending [line " + str(linecount) + "]")
133 | else:
134 | #malformed message ... ignore
135 | print("\nMalformed Suspending entry at line "+str(linecount)+"\n")
136 |
137 |
138 | print("\nFound " + str(connectedcount) + " Now Connected entries")
139 | print("Found " + str(resumecount) + " Resuming entries")
140 | print("Found " + str(reunioncount) + " Starting Reunion Sync entries")
141 | print("Found " + str(disconnectedcount) + " Disconnected entries")
142 | print("Found " + str(suspendcount) + " Suspending entries\n")
143 |
144 |
145 |
146 |
--------------------------------------------------------------------------------
/sysdiagnose-appupdates.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 |
3 | # For Python3
4 | # Script to print connection info from logs/appinstallation/AppUpdates.sqlite.db
5 | # Author: david@autopsit.org
6 |
7 | import sys
8 | from optparse import OptionParser
9 | import time
10 | import datetime
11 | import sqlite3
12 |
13 | version_string = "sysdiagnose-appupdates.py v2019-10-02 Version 1.0"
14 |
15 | if sys.version_info[0] < 3:
16 | print("Must be using Python 3! Exiting ...")
17 | exit(-1)
18 |
19 | print("Running " + version_string + "\n")
20 |
21 | usage = "\n%prog -i inputfile\n"
22 |
23 | parser = OptionParser(usage=usage)
24 | parser.add_option("-i", dest="inputfile",
25 | action="store", type="string",
26 | help="logs/appinstallation/AppUpdates.sqlite.db to be parsed")
27 | (options, args) = parser.parse_args()
28 |
29 | #no arguments given by user, print help and exit
30 | if len(sys.argv) == 1:
31 | parser.print_help()
32 | exit(-1)
33 |
34 | try:
35 | appinstalldb = sqlite3.connect(options.inputfile)
36 | cursor = appinstalldb.cursor()
37 | print("pid\tbundle_id\tinstall_date(UTC)\ttimestamp(UTC)")
38 | for row in cursor.execute("SELECT pid, bundle_id, install_date, timestamp FROM app_updates"):
39 | [pid, bundle_id, install_date, timestamp] = row
40 | if (install_date is not None):
41 | # convert "install_date" from Cocoa EPOCH -> UTC
42 | epoch = install_date + 978307200 # difference between COCOA and UNIX epoch is 978307200 seconds
43 | utctime = datetime.datetime.utcfromtimestamp(epoch)
44 | else:
45 | utctime = "NULL"
46 | if (timestamp is not None):
47 | # convert "timestamp" from Unix EPOCH -> UTC
48 | utctimestamp = datetime.datetime.utcfromtimestamp(timestamp)
49 | else:
50 | utctimestamp = "NULL"
51 |
52 | print("%s\t%s\t%s\t%s" % (pid, bundle_id, utctime, utctimestamp))
53 | except:
54 | print("AN UNHANDLED ERROR OCCURRED AND THE DB WAS NOT PARSED")
55 |
56 |
57 |
58 | # That's all folks ;)
59 |
60 |
--------------------------------------------------------------------------------
/sysdiagnose-mobileactivation.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 |
3 | # For Python3
4 | # Script to print Mobile Activation Startup and Upgrade info from logs/MobileActivation/mobileactivationd.log.*
5 | # Author: cheeky4n6monkey@gmail.com
6 |
7 | import sys
8 | from optparse import OptionParser
9 |
10 | version_string = "sysdiagnose-mobileactivation.py v2019-05-10 Version 1.0"
11 |
12 | if sys.version_info[0] < 3:
13 | print("Must be using Python 3! Exiting ...")
14 | exit(-1)
15 |
16 | print("Running " + version_string + "\n")
17 |
18 | usage = "\n%prog -i inputfile\n"
19 |
20 | parser = OptionParser(usage=usage)
21 | parser.add_option("-i", dest="inputfile",
22 | action="store", type="string",
23 | help="logs/MobileActivation/mobileactivationd.log.* To Be Searched")
24 | (options, args) = parser.parse_args()
25 |
26 | #no arguments given by user, print help and exit
27 | if len(sys.argv) == 1:
28 | parser.print_help()
29 | exit(-1)
30 |
31 | linecount = 0
32 | hitcount = 0
33 | activationcount = 0
34 | with open(options.inputfile, 'r') as fp:
35 | data = fp.readlines()
36 |
37 | for line in data:
38 | linecount += 1
39 |
40 | if 'perform_data_migration' in line:
41 | hitcount += 1
42 | #print("\n" + line)
43 | txts = line.split()
44 | #print(txts, linecount)
45 | #print(len(txts))
46 | dayofweek = txts[0]
47 | month = txts[1]
48 | day = txts[2]
49 | time = txts[3]
50 | year = txts[4]
51 | frombuild = txts[12]
52 | tobuild = txts[14]
53 | print("\n" + day + " " + month + " " + year + " " + time + " Upgraded from " + frombuild + " to " + tobuild + " [line " + str(linecount) + "]")
54 |
55 |
56 | if 'MA: main: ____________________ Mobile Activation Startup _____________________' in line:
57 | activationcount += 1
58 | #print("\n" + line)
59 | txts = line.split()
60 | #print(txts, linecount)
61 | #print(len(txts))
62 | dayofweek = txts[0]
63 | month = txts[1]
64 | day = txts[2]
65 | time = txts[3]
66 | year = txts[4]
67 | print("\n" + day + " " + month + " " + year + " " + time + " Mobile Activation Startup " + " [line " + str(linecount) + "]")
68 |
69 | if 'MA: main: build_version:' in line:
70 | #print("\n" + line)
71 | txts = line.split()
72 | #print(txts, linecount)
73 | #print(len(txts))
74 | dayofweek = txts[0]
75 | month = txts[1]
76 | day = txts[2]
77 | time = txts[3]
78 | year = txts[4]
79 | buildver = txts[11]
80 | print(day + " " + month + " " + year + " " + time + " Mobile Activation Build Version = " + buildver)
81 |
82 | if 'MA: main: hardware_model:' in line:
83 | #print("\n" + line)
84 | txts = line.split()
85 | #print(txts, linecount)
86 | #print(len(txts))
87 | dayofweek = txts[0]
88 | month = txts[1]
89 | day = txts[2]
90 | time = txts[3]
91 | year = txts[4]
92 | hwmodel = txts[11]
93 | print(day + " " + month + " " + year + " " + time + " Mobile Activation Hardware Model = " + hwmodel)
94 |
95 | if 'MA: main: product_type:' in line:
96 | #print("\n" + line)
97 | txts = line.split()
98 | #print(txts, linecount)
99 | #print(len(txts))
100 | dayofweek = txts[0]
101 | month = txts[1]
102 | day = txts[2]
103 | time = txts[3]
104 | year = txts[4]
105 | prod = txts[11]
106 | print(day + " " + month + " " + year + " " + time + " Mobile Activation Product Type = " + prod)
107 |
108 | if 'MA: main: device_class:' in line:
109 | #print("\n" + line)
110 | txts = line.split()
111 | #print(txts, linecount)
112 | #print(len(txts))
113 | dayofweek = txts[0]
114 | month = txts[1]
115 | day = txts[2]
116 | time = txts[3]
117 | year = txts[4]
118 | devclass = txts[11]
119 | print(day + " " + month + " " + year + " " + time + " Mobile Activation Device Class = " + devclass)
120 |
121 | print("\nFound " + str(hitcount) + " Upgrade entries")
122 |
123 | print("Found " + str(activationcount) + " Mobile Activation Startup entries\n")
124 |
125 |
--------------------------------------------------------------------------------
/sysdiagnose-mobilebackup.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 |
3 | # For Python3
4 | # Script to print the values from logs/MobileBackup/com.apple.MobileBackup.plist
5 | # Author: cheeky4n6monkey@gmail.com
6 |
7 | import sys
8 | from optparse import OptionParser
9 | import plistlib
10 |
11 | #import pprint
12 |
13 | version_string = "sysdiagnose-mobilebackup.py v2019-05-10 Version 1.0"
14 |
15 | if sys.version_info[0] < 3:
16 | print("Must be using Python 3! Exiting ...")
17 | exit(-1)
18 |
19 |
20 | usage = "\n%prog -i inputfile\n"
21 |
22 | parser = OptionParser(usage=usage)
23 | parser.add_option("-i", dest="inputfile",
24 | action="store", type="string",
25 | help="logs/MobileBackup/com.apple.MobileBackup.plist To Be Searched")
26 | (options, args) = parser.parse_args()
27 |
28 | #no arguments given by user, print help and exit
29 | if len(sys.argv) == 1:
30 | parser.print_help()
31 | exit(-1)
32 |
33 | print("Running " + version_string + "\n")
34 |
35 | with open(options.inputfile, 'rb') as fp:
36 | pl = plistlib.load(fp)
37 | #pprint.pprint(pl)
38 | #print(pl.keys())
39 |
40 | if 'BackupStateInfo' in pl.keys():
41 | for key, val in pl["BackupStateInfo"].items():
42 | #print("key = " + str(key) + ", val = " + str(val))
43 | if key == 'date':
44 | print("BackupStateInfo Date = " + str(val))
45 | if key == 'isCloud':
46 | print("BackupStateInfo isCloud = " + str(val))
47 |
48 | if 'RestoreInfo' in pl.keys():
49 | for key, val in pl["RestoreInfo"].items():
50 | if key == 'RestoreDate':
51 | print("RestoreInfo Date = " + str(val))
52 | if key == 'BackupBuildVersion':
53 | print("RestoreInfo BackupBuildVersion = " + str(val))
54 | if key == 'DeviceBuildVersion':
55 | print("RestoreInfo DeviceBuildVersion = " + str(val))
56 | if key == 'WasCloudRestore':
57 | print("RestoreInfo WasCloudRestore = " + str(val))
58 |
59 |
60 |
--------------------------------------------------------------------------------
/sysdiagnose-mobilecontainermanager.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 |
3 | # For Python3
4 | # Script to print uninstall infor from logs/MobileContainerManager/containermanagerd.log.0
5 | # Author: cheeky4n6monkey@gmail.com
6 |
7 | import sys
8 | from optparse import OptionParser
9 |
10 | version_string = "sysdiagnose-mobilecontainermanager.py v2019-05-10 Version 1.0"
11 |
12 | if sys.version_info[0] < 3:
13 | print("Must be using Python 3! Exiting ...")
14 | exit(-1)
15 |
16 | print("Running " + version_string + "\n")
17 |
18 | usage = "\n%prog -i inputfile\n"
19 |
20 | parser = OptionParser(usage=usage)
21 | parser.add_option("-i", dest="inputfile",
22 | action="store", type="string",
23 | help="logs/MobileContainerManager/containermanagerd.log.0 To Be Searched")
24 | (options, args) = parser.parse_args()
25 |
26 | #no arguments given by user, print help and exit
27 | if len(sys.argv) == 1:
28 | parser.print_help()
29 | exit(-1)
30 |
31 | linecount = 0
32 | hitcount = 0
33 | with open(options.inputfile, 'r') as fp:
34 | data = fp.readlines()
35 |
36 | for line in data:
37 | linecount += 1
38 |
39 | if '[MCMGroupManager _removeGroupContainersIfNeededforUser:groupContainerClass:identifiers:referenceCounts:]: Last reference to group container' in line:
40 | hitcount += 1
41 | #print("\n" + line)
42 | txts = line.split()
43 | #print(txts, linecount)
44 | #print(len(txts))
45 | dayofweek = txts[0]
46 | month = txts[1]
47 | day = txts[2]
48 | time = txts[3]
49 | year = txts[4]
50 | group = txts[15]
51 | print(day + " " + month + " " + year + " " + time + " Removed " + group + " [line " + str(linecount) + "]")
52 |
53 | print("\nFound " + str(hitcount) + " group removal entries\n")
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/sysdiagnose-net-ext-cache.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 |
3 | # For Python3
4 | # Script to print the values from logs/Networking/com.apple.networkextension.cache.plist
5 | # Author: cheeky4n6monkey@gmail.com
6 |
7 | import sys
8 | from optparse import OptionParser
9 | import plistlib
10 |
11 | #import pprint
12 |
13 | version_string = "sysdiagnose-net-ext-cache.py v2019-05-10 Version 1.0"
14 |
15 | if sys.version_info[0] < 3:
16 | print("Must be using Python 3! Exiting ...")
17 | exit(-1)
18 |
19 |
20 | usage = "\n%prog -i inputfile\n"
21 |
22 | parser = OptionParser(usage=usage)
23 | parser.add_option("-i", dest="inputfile",
24 | action="store", type="string",
25 | help="logs/Networking/com.apple.networkextension.cache.plist To Be Searched")
26 | parser.add_option("-v", dest="verbose",
27 | action="store_true", default=False,
28 | help="Print GUIDs as well as app names")
29 | (options, args) = parser.parse_args()
30 |
31 | #no arguments given by user, print help and exit
32 | if len(sys.argv) == 1:
33 | parser.print_help()
34 | exit(-1)
35 |
36 | print("Running " + version_string + "\n")
37 |
38 | count = 0
39 | with open(options.inputfile, 'rb') as fp:
40 | pl = plistlib.load(fp)
41 | #pprint.pprint(pl)
42 | #print(pl.keys())
43 |
44 | if 'app-rules' in pl.keys():
45 | for key, list1 in pl["app-rules"].items():
46 | count += 1
47 | if (options.verbose):
48 | print(str(key) + " = " + ', '.join(list1)) # verbose with GUIDs
49 | else:
50 | print(str(key)) # just app names
51 |
52 | print("\n" + str(count) + " cache entries retrieved\n")
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/sysdiagnose-networkinterfaces.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 |
3 | # For Python3
4 | # Script to print the values from logs/Networking/NetworkInterfaces.plist
5 | # Author: cheeky4n6monkey@gmail.com
6 |
7 | import sys
8 | from optparse import OptionParser
9 | import plistlib
10 |
11 | version_string = "sysdiagnose-networkinterfaces.py v2019-11-08 Version 1.0"
12 |
13 | if sys.version_info[0] < 3:
14 | print("Must be using Python 3! Exiting ...")
15 | exit(-1)
16 |
17 | print("Running " + version_string + "\n")
18 |
19 | usage = "\n%prog -i inputfile\n"
20 |
21 | parser = OptionParser(usage=usage)
22 | parser.add_option("-i", dest="inputfile",
23 | action="store", type="string",
24 | help="logs/Networking/NetworkInterfaces.plist To Be Searched")
25 | (options, args) = parser.parse_args()
26 |
27 | with open(options.inputfile, 'rb') as fp:
28 | pl = plistlib.load(fp)
29 | if 'Interfaces' in pl.keys():
30 | #print(pl["Interfaces"])
31 | #print(type(pl["Interfaces"])) = dict
32 |
33 | for dictn in pl['Interfaces']:
34 | print("==================================")
35 | print("BSD Name = " + dictn['BSD Name'])
36 | if 'Active' in dictn.keys():
37 | print("Active = " + str(dictn['Active']))
38 | if 'IOMACAddress' in dictn.keys():
39 | #print("IOMACAddress = " + str(dictn['IOMACAddress'])) # dictn['IOMACAddress'] = bytes type
40 | print("IOMACAddress = " + dictn['IOMACAddress'].hex()) # string type
41 | if 'IOPathMatch' in dictn.keys():
42 | print("IOPathMatch = " + dictn['IOPathMatch'])
43 |
44 | for key, val in dictn['SCNetworkInterfaceInfo'].items():
45 | if key == 'UserDefinedName':
46 | print("UserDefinedName = " + val)
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/sysdiagnose-networkprefs.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 |
3 | # For Python3
4 | # Script to print the values from /logs/Networking/preferences.plist
5 | # Author: cheeky4n6monkey@gmail.com
6 |
7 | import sys
8 | from optparse import OptionParser
9 | import plistlib
10 |
11 | version_string = "sysdiagnose-networkprefs.py v2019-05-10 Version 1.0"
12 |
13 | if sys.version_info[0] < 3:
14 | print("Must be using Python 3! Exiting ...")
15 | exit(-1)
16 |
17 | print("Running " + version_string + "\n")
18 |
19 | usage = "\n%prog -i inputfile\n"
20 |
21 | parser = OptionParser(usage=usage)
22 | parser.add_option("-i", dest="inputfile",
23 | action="store", type="string",
24 | help="/logs/Networking/preferences.plist To Be Searched")
25 | (options, args) = parser.parse_args()
26 |
27 | with open(options.inputfile, 'rb') as fp:
28 | pl = plistlib.load(fp)
29 | #print(pl.keys()) # dict_keys(['CurrentSet', 'System', 'Sets', 'NetworkServices'])
30 |
31 | if 'System' in pl.keys():
32 | #print(pl["System"])
33 | #print(type(pl["System"])) = dict
34 | if 'System' in pl["System"].keys():
35 | for key, val in pl["System"].items():
36 | if key == 'System':
37 | print("System ComputerName = " + val["ComputerName"]) # System/System/ComputerName
38 | print("System HostName = " + val["HostName"]) # System/System/HostName
39 | if key == 'Network':
40 | for key2, val2 in val["HostNames"].items():
41 | print("Network LocalHostName = " + val2) # for each System/Network/HostNames/LocalHostName
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/sysdiagnose-sys.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 |
3 | # For Python3
4 | # Script to print the values from /logs/SystemVersion/SystemVersion.plist
5 | # Author: cheeky4n6monkey@gmail.com
6 |
7 | import sys
8 | from optparse import OptionParser
9 | import plistlib
10 |
11 | version_string = "sysdiagnose-sys.py v2019-05-10 Version 1.0"
12 |
13 | if sys.version_info[0] < 3:
14 | print("Must be using Python 3! Exiting ...")
15 | exit(-1)
16 |
17 | print("Running " + version_string + "\n")
18 |
19 | usage = "\n%prog -i inputfile\n"
20 |
21 | parser = OptionParser(usage=usage)
22 | parser.add_option("-i", dest="inputfile",
23 | action="store", type="string",
24 | help="/logs/SystemVersion/SystemVersion.plist To Be Searched")
25 | (options, args) = parser.parse_args()
26 |
27 | with open(options.inputfile, 'rb') as fp:
28 | pl = plistlib.load(fp)
29 | print("ProductName = " + pl["ProductName"])
30 | print("ProductVersion = " + pl["ProductVersion"])
31 | print("ProductBuildVersion = " + pl["ProductBuildVersion"])
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/sysdiagnose-uuid2path.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 |
3 | # For Python3
4 | # Script to print the values from logs/tailspindb/UUIDToBinaryLocations (XML plist)
5 | # Uses Python3's plistlib
6 | # Author: cheeky4n6monkey@gmail.com
7 |
8 | import sys
9 | from optparse import OptionParser
10 | import plistlib
11 | import pprint
12 |
13 | version_string = "sysdiagnose-uuid2path.py v2019-05-10 Version 1.0"
14 |
15 | if sys.version_info[0] < 3:
16 | print("Must be using Python 3! Exiting ...")
17 | exit(-1)
18 |
19 | usage = "\n%prog -i inputfile\n"
20 |
21 | parser = OptionParser(usage=usage)
22 | parser.add_option("-i", dest="inputfile",
23 | action="store", type="string",
24 | help="logs/tailspindb/UUIDToBinaryLocations plist To Be Printed")
25 | (options, args) = parser.parse_args()
26 |
27 | #no arguments given by user, print help and exit
28 | if len(sys.argv) == 1:
29 | parser.print_help()
30 | exit(-1)
31 |
32 | print("Running " + version_string + "\n")
33 |
34 | with open(options.inputfile, 'rb') as fp:
35 | pl = plistlib.load(fp)
36 | for key, val in pl.items():
37 | print(str(key) + ", " + str(val))
38 |
39 | print("\n" + str(len(pl.keys())) + " GUIDs found\n")
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/sysdiagnose-wifi-icloud.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 |
3 | # For Python3
4 | # Script to print the values from WiFi/ICLOUD_com.apple.wifid.plist
5 | # Author: cheeky4n6monkey@gmail.com
6 |
7 | import sys
8 | from optparse import OptionParser
9 | import plistlib
10 |
11 | version_string = "sysdiagnose-wifi-icloud.py v2019-05-10 Version 1.0"
12 |
13 | if sys.version_info[0] < 3:
14 | print("Must be using Python 3! Exiting ...")
15 | exit(-1)
16 |
17 | print("Running " + version_string + "\n")
18 |
19 | usage = "\n%prog -i inputfile\n"
20 |
21 | parser = OptionParser(usage=usage)
22 | parser.add_option("-i", dest="inputfile",
23 | action="store", type="string",
24 | help="WiFi/ICLOUD_com.apple.wifid.plist To Be Searched")
25 | parser.add_option("-t", dest="outputtsv",
26 | action="store_true", default=False,
27 | help="Write TSV output file called sysdiagnose-wifi-icloud-output.TSV")
28 | (options, args) = parser.parse_args()
29 |
30 | netlist = []
31 |
32 | with open(options.inputfile, 'rb') as fp:
33 | pl = plistlib.load(fp)
34 | if 'values' in pl.keys():
35 | name = ""
36 | timestamp =""
37 | bssid = ""
38 | ssid = ""
39 | addedat = ""
40 | addedby = ""
41 | enabled = ""
42 | for key, val in pl['values'].items(): # values contains an entry for each wifi net
43 | print("==================================")
44 | print("Name = " + key)
45 | name = key
46 |
47 | if type(val) == dict:
48 | for key2, val2 in val.items():
49 | if key2 == 'timestamp':
50 | print("timestamp = " + str(val2))
51 | timestamp = str(val2)
52 |
53 | if key2 == 'value':
54 | if type(val2) == dict:
55 | for key3, val3 in val2.items():
56 | if key3 == 'BSSID':
57 | print("BSSID = " + str(val3))
58 | bssid = str(val3)
59 | if key3 == 'SSID_STR':
60 | print("SSID_STR = " + str(val3))
61 | ssid = str(val3)
62 | if key3 == 'added_at':
63 | print("added_at = " + str(val3))
64 | addedat = str(val3)
65 | if key3 == 'added_by':
66 | print("added_by = " + str(val3))
67 | addedby = str(val3)
68 | if key3 == 'enabled':
69 | print("enabled = " + str(val3))
70 | enabled = str(val3)
71 |
72 | netlist.append((name, timestamp, bssid, ssid, addedat, addedby, enabled))
73 |
74 | print("\nRetrieved " + str(len(pl['values'].keys())) + " wifi entries\n")
75 |
76 |
77 | if (options.outputtsv):
78 | with open("sysdiagnose-wifi-icloud-output.TSV", 'w') as wp:
79 | wp.write("NAME\tTIMESTAMP\tBSSID\tSSID\tADDEDAT\tADDEDBY\tENABLED\n") # header
80 | for name, timestamp, bssid, ssid, addedat, addedby, enabled in netlist:
81 | wp.write(name+"\t"+timestamp+"\t"+bssid+"\t"+ssid+"\t"+addedat+"\t"+addedby+"\t"+enabled+"\n")
82 |
83 | print("Also outputted to sysdiagnose-wifi-icloud-output.TSV\n")
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/sysdiagnose-wifi-kml.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 |
3 | # For Python3
4 | # Script to print the geolocation values from WiFi/wifi*.log
5 | # and log locations to output KML
6 | # Author: cheeky4n6monkey@gmail.com
7 |
8 | #import os
9 | import sys
10 | from optparse import OptionParser
11 | import tarfile
12 |
13 | version_string = "sysdiagnose-wifi-kml.py v2019-05-10 Version 1.0"
14 |
15 | if sys.version_info[0] < 3:
16 | print("Must be using Python 3! Exiting ...")
17 | exit(-1)
18 |
19 | print("Running " + version_string + "\n")
20 |
21 | usage = "\n%prog -i inputfile\n"
22 |
23 | parser = OptionParser(usage=usage)
24 | parser.add_option("-i", dest="inputfile",
25 | action="store", type="string",
26 | help="WiFi/wifi*.log To Be Searched")
27 | (options, args) = parser.parse_args()
28 |
29 | #no arguments given by user, print help and exit
30 | if len(sys.argv) == 1:
31 | parser.print_help()
32 | exit(-1)
33 |
34 | linecount = 0
35 | ignorecount = 0
36 | updatecount = 0
37 | geotagcount = 0
38 | callbackcount = 0
39 | localecallbackcount = 0
40 | checklocalecount = 0
41 | networktranscount = 0
42 | wifimanagercount = 0
43 | wificurrentlocation = 0
44 |
45 | locations = []
46 | scanlocations = []
47 | geolocations = []
48 | callbacklocations = []
49 | localecallbacklocations = []
50 | checklocalelocations = []
51 | networktranslocations = []
52 | copylocations = []
53 |
54 | #print(options.inputfile[0:-4]) # = wifi-buf-04-26-2019__16:00:52.768.log
55 |
56 | if options.inputfile.endswith('.tgz'): # eg wifi-buf-04-26-2019__16:00:52.768.log.tgz
57 | # untar file first to current directory
58 | # tarfile.open currently Throws InvalidHeader error!
59 | with tarfile.open(options.inputfile, 'r:gz') as t:
60 | t.extractall('./')
61 |
62 | # does not get here due to exception ... todo
63 |
64 | # readfile = ass-ume extracted name is same as input name minus the .tgz
65 | with open(options.inputfile[0:-4], 'r') as fp:
66 | data = fp.readlines()
67 | # TODO: Implement processing when given zip file
68 | '''
69 | for line in data:
70 | if 'didUpdateLocations:' in line:
71 | count += 1
72 | print(line)
73 | '''
74 | else: # ass-ume input file has been untarred already and is plaintext
75 | with open(options.inputfile, 'r') as fp:
76 | data = fp.readlines()
77 |
78 | for line in data:
79 | linecount += 1
80 |
81 | if 'didUpdateLocations: latitude' in line:
82 | #print("\n" + line)
83 | txts = line.split()
84 | #print(txts, linecount)
85 | #print(len(txts))
86 |
87 | if '