forked from ydkhatri/mac_apt
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsudo_lastrun.py
118 lines (100 loc) · 4.76 KB
/
sudo_lastrun.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
'''
Copyright (c) 2020 Yogesh Khatri
This file is part of mac_apt (macOS Artifact Parsing Tool).
Usage or distribution of this software/code is subject to the
terms of the MIT License.
sudo_ts.py
---------------
This gets the last time(s) sudo was used by each user.
'''
import os
from plugins.helpers.macinfo import *
from plugins.helpers.writer import *
import logging
import struct
__Plugin_Name = "SUDOLASTRUN" # Cannot have spaces, and must be all caps!
__Plugin_Friendly_Name = "sudo lastrun timestamps"
__Plugin_Version = "1.0"
__Plugin_Description = "Gets last time sudo was used and a few other times earlier (if available)"
__Plugin_Author = "Yogesh Khatri"
__Plugin_Author_Email = "yogesh@swiftforensics.com"
__Plugin_Modes = "MACOS,ARTIFACTONLY" # Valid values are 'MACOS', 'IOS, 'ARTIFACTONLY'
__Plugin_ArtifactOnly_Usage = 'Provide files under /var/db/sudo/ts/ to read this info'
log = logging.getLogger('MAIN.' + __Plugin_Name) # Do not rename or remove this ! This is the logger object
#---- Do not change the variable names in above section ----#
def PrintAll(sudo_logs, output_params, source_path):
sudo_info = [ ('Uid',DataType.TEXT),('Run Date',DataType.TEXT),
('User', DataType.TEXT),('Source',DataType.TEXT)
]
log.info("Found {} sudo last run timestamp(s)".format(len(sudo_logs)))
WriteList("sudo last run timestamp", "SudoLastRun", sudo_logs, sudo_info, output_params, source_path)
def ProcessTsFile(f, name, file_path, file_size, sudo_logs):
while f.tell() < file_size:
header = f.read(8)
if len(header) == 8:
version, size, typ, flags = struct.unpack('<HHHH', header)
if typ == 2:
data = f.read(size - 8)
if len(data) == size - 8:
if size == 0x28:
uid, _, _, date_1, _ = struct.unpack('<HHIQQ', data[0:24])
date_1 = CommonFunctions.ReadUnixTime(date_1)
if date_1:
sudo_logs.append( [uid, date_1, name, file_path] )
elif size == 0x38:
uid, _, _, date_1, _, date_2, _ = struct.unpack('<HHIQQQQ', data[0:40])
date_1 = CommonFunctions.ReadUnixTime(date_1)
date_2 = CommonFunctions.ReadUnixTime(date_2)
if date_1:
sudo_logs.append( [uid, date_1, name, file_path] )
if date_2:
sudo_logs.append( [uid, date_2, name, file_path] )
else:
log.error(f'Got unknown size for sudo_timestamp struct , size={size}')
break
else:
break
else:
f.seek(size - 8, 1)
else:
break
def Plugin_Start(mac_info):
'''Main Entry point function for plugin'''
sudo_logs = []
source_path = '/private/var/db/sudo/ts'
if mac_info.IsValidFolderPath(source_path):
files_list = mac_info.ListItemsInFolder(source_path, EntryType.FILES, include_dates=False)
for file_entry in files_list:
if file_entry['size'] > 0:
file_path = source_path + '/' + file_entry['name']
mac_info.ExportFile(file_path, __Plugin_Name, '', False)
f = mac_info.Open(file_path)
if f:
ProcessTsFile(f, file_entry['name'], file_path, file_entry['size'], sudo_logs)
f.close()
if len(sudo_logs) > 0:
PrintAll(sudo_logs, mac_info.output_params, '')
else:
log.info('No sudo timestamp files were found!')
else:
log.info(f'{source_path} does not exist.')
def Plugin_Start_Standalone(input_files_list, output_params):
'''Main entry point function when used on single artifacts (mac_apt_singleplugin), not on a full disk image'''
log.info("Module Started as standalone")
sudo_logs = []
for input_path in input_files_list:
log.debug("Input file passed was: " + input_path)
## Process the input file here ##
f = open(file_path)
if f:
ProcessTsFile(f, os.path.basename(input_path), input_path, os.path.getsize(input_path), sudo_logs)
f.close()
if len(sudo_logs) > 0:
PrintAll(sudo_logs, output_params, '')
else:
log.info('No sudo timestamp files were found!')
def Plugin_Start_Ios(ios_info):
'''Entry point for ios_apt plugin'''
pass
if __name__ == '__main__':
print ("This plugin is a part of a framework and does not run independently on its own!")