-
Notifications
You must be signed in to change notification settings - Fork 0
/
Snapshot.ps1
346 lines (232 loc) · 12.4 KB
/
Snapshot.ps1
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
<##############################################################################
.SYNOPSIS
Creates a folder with files which capture the current OS state.
.DESCRIPTION
Creates a folder filled with CSV, XML and TXT files which capture
the current operational state of the computer, such as running
processes, services, user accounts, audit policies, shared folders,
networking settings, and more. These files can be used for threat
hunting, auditing, compliance, and troubleshooting purposes.
The output folder will be named after the local host and the current
date and time, e.g., .\COMPUTERNAME-Year-Month-Day-Hour-Minute.
The commands creating the files are simple and can be edited by
those without advanced scripting skills. The files produced also
can be compressed, copied, analyzed and compared without expensive
forensics or analysis tools, such as Notepad++ or WinMerge.
Script requires PowerShell 3.0, Windows 7, Server 2008, or later,
and must be run with administrative privileges.
Most commands are built into PowerShell 3.0 and later, but some
tools will need to be installed first in order to use them, such
as AUTORUNSC.EXE (http://www.microsoft.com/sysinternals/) and
SHA256DEEP.EXE (http://md5deep.sourceforge.net), which are not
required, but very useful for snapshots. Be aware, though, that
producing thousands of file hashes may require a long time.
.PARAMETER OutputParentFolder
Optional path to the parent folder under which a new subfolder will
be created to hold the snapshot files. This is not the path to
the output folder itself, which will be automatically created, but
to its parent folder. Defaults to $PWD, the present directory.
Write access permission is required to the output folder.
.PARAMETER TextFileOutput
Forces all output files to be flat TXT files instead of XML.
.PARAMETER Verbose
Show progress information as the script is running.
.NOTES
Version: 4.5
Updated: 26.Oct.2017
Author: Enclave Consulting LLC (http://www.sans.org/sec505)
Legal: 0BSD.
Requires -Version 3.0
##############################################################################>
[CmdletBinding()]
Param ([String] $OutputParentFolder = ($Pwd.Path), [Switch] $TextFileOutput)
# Verbose start time:
$StartTime = Get-Date
Write-Verbose -Message ("Started: " + (Get-Date -Format 'F'))
#.DESCRIPTION
# Helper function to write output as XML (default) or as TXT (with -TextFileOutput).
# Almost every command below pipes into this function.
function WriteOut ($FileName)
{
if ($TextFileOutput)
{
Write-Verbose -Message ("Writing to " + ($FileName + ".txt"))
$Input | Format-List * | Out-File -Encoding UTF8 -FilePath ($FileName + ".txt")
}
else
{
Write-Verbose -Message ("Writing to " + ($FileName + ".xml"))
$Input | Export-Clixml -Encoding UTF8 -Path ($FileName + ".xml")
}
}
# Confirm that the destination PARENT folder exists:
if (-not (Test-Path -Path $OutputParentFolder -PathType Container))
{
Write-Error -Message "$OutputParentFolder does not exist or is not accessible, exiting."
Exit
}
# If this script is run with File Explorer, the present working
# directory becomes C:\Windows\System32, which is not good, so
# disallow $env:SystemRoot or anything underneath it:
if ( $OutputParentFolder -like ($env:SystemRoot + '*') )
{
Write-Error -Message "Output folder cannot be under $Env:SystemRoot, and script must be run from within a command shell, exiting."
Exit
}
# Record present directory in order to switch back to it later,
# and attempt to switch into $OutputParentFolder now:
$PresentDirectory = $Pwd
cd $OutputParentFolder
if (-not $?){ Write-Error -Message "Could not switch into $OutputParentFolder, exiting." ; Exit }
# Set FOLDER variable to contain output files. The format will look
# like "COMPUTERNAME-2018-06-05-11-03" (computername-year-month-day-hour-minute).
$OutputFolder = $env:COMPUTERNAME + "-" + (Get-Date -Format 'yyyy-MM-dd-hh-mm')
Write-Verbose -Message "Creating $(Join-Path -Path $OutputParentFolder -ChildPath $OutputFolder)"
# Create the $Folder in the present working directory and switch into it:
mkdir $OutputFolder | out-null
if (-not $?){ Write-Error -Message "Could not create $OutputFolder, exiting." ; Exit }
cd $OutputFolder
if ($pwd.Path -ne (Join-Path -Path $OutputParentFolder -ChildPath $OutputFolder))
{ Write-Error -Message "Could not switch into $OutputFolder, exiting." ; Exit }
###############################################################################
#
# Create README.TXT file to identify this computer and snapshot.
# More text will be appended to the end of this file later in this script.
#
###############################################################################
$ReadmeText = @"
*SYSTEM CONFIGURATION SNAPSHOT
*Computer: $env:COMPUTERNAME
*HostName: $(hostname.exe)
*Box-Date: $(Get-Date -Format 'F')
*UTC-Date: $(Get-Date -Format 'U')
*ZuluDate: $(Get-Date -Format 'u')
*PVersion: $($PSVersionTable.PSVersion.ToString())
*UserName: $env:USERNAME
*User-Dom: $env:USERDOMAIN
"@
$ReadmeText | Out-File -Encoding UTF8 -FilePath .\README.TXT -Force
if (-not $?)
{ Write-Error -Message "Could not write to README.TXT, exiting." ; Exit }
else
{ Write-Verbose -Message "Created README.TXT" }
###############################################################################
#
# Now run whatever commands you wish to capture operational state data.
# Please add more commands and use additional tools too, always piping
# the output of any command into the WriteOut function (defined above).
#
###############################################################################
# Computer System
Get-CimInstance -ClassName Win32_ComputerSystem | WriteOut -FileName ComputerSystem
# BIOS
Get-CimInstance -ClassName Win32_BIOS | WriteOut -FileName BIOS
# Environment Variables
dir env:\ | WriteOut -FileName Environment-Variables
# Users
Get-CimInstance -ClassName Win32_UserAccount | WriteOut -FileName Users
# Groups
Get-CimInstance -ClassName Win32_Group | WriteOut -FileName Groups
# Group Members
Get-CimInstance -ClassName Win32_GroupUser | WriteOut -FileName Group-Members
# Password And Lockout Policies
net.exe accounts | Out-File -FilePath Password-And-Lockout-Policies.txt
# Local Audit Policy
auditpol.exe /get /category:* | Out-File -FilePath Audit-Policy.txt
# SECEDIT Security Policy Export
secedit.exe /export /cfg SecEdit-Security-Policy.txt | out-null
# Shared Folders
Get-SmbShare | WriteOut -FileName Shared-Folders
# Networking Configuration
Get-NetAdapter -IncludeHidden | WriteOut -FileName Network-Adapters
Get-NetIPAddress | WriteOut -FileName Network-IPaddresses
Get-NetTCPConnection -State Listen | Sort LocalPort | WriteOut -FileName Network-TCP-Listening-Ports
Get-NetUDPEndpoint | Sort LocalPort | WriteOut -FileName Network-UDP-Listening-Ports
Get-NetRoute | WriteOut -FileName Network-Route-Table
nbtstat.exe -n | Out-File -FilePath Network-NbtStat.txt
netsh.exe winsock show catalog | Out-File -FilePath Network-WinSock.txt
Get-DnsClientNrptPolicy -Effective | WriteOut -FileName Name-Resolution-Policy-Table
# Windows Firewall and IPSec
Get-NetConnectionProfile | WriteOut -FileName Network-Connection-Profiles
Get-NetFirewallProfile | WriteOut -FileName Network-Firewall-Profiles
Get-NetFirewallRule | WriteOut -FileName Network-Firewall-Rules
Get-NetIPsecRule | WriteOut -FileName Network-IPSec-Rules
netsh.exe advfirewall export Network-Firewall-Export.wfw | out-null
# Processes
Get-Process -IncludeUserName | WriteOut -FileName Processes
# Drivers
Get-CimInstance -ClassName Win32_SystemDriver | WriteOut -FileName Drivers
# DirectX Diagnostics
dxdiag.exe /whql:off /64bit /t dxdiag.txt
# Services
Get-Service | WriteOut -FileName Services
# Registry Exports (add more as you wish)
Write-Verbose -Message "Writing to registry files: *.reg"
reg.exe export hklm\system\CurrentControlSet Registry-CurrentControlSet.reg /y | out-null
reg.exe export hklm\software\microsoft\windows\currentversion Registry-WindowsCurrentVersion.reg /y | out-null
# Generate an MSINFO32.EXE report, which includes lots of misc info
Write-Verbose -Message "Writing to MSINFO32-Report.txt"
msinfo32.exe /report MSINFO32-Report.txt
# Hidden Files and Folders
dir -Path c:\ -Hidden -Recurse -ErrorAction SilentlyContinue | Select-Object FullName,Length,Mode,CreationTime,LastAccessTime,LastWriteTime | Export-Csv -Path FileSystem-Hidden-Files.csv
# Non-Hidden Files and Folders
dir -Path c:\ -Recurse -ErrorAction SilentlyContinue | Select-Object FullName,Length,Mode,CreationTime,LastAccessTime,LastWriteTime | Export-Csv -Path FileSystem-Files.csv
# NTFS Permissions And Integrity Labels
# This file can reach 100's of MB in size, so
# we'll limit this example to just System32:
icacls.exe c:\windows\system32 /t /c /q 2>$null | Out-File -FilePath FileSystem-NTFS-Permissions.txt
###############################################################################
#
# The following commands require that various tools be installed and in the
# PATH, since they are not installed by default. Uncomment the lines after
# installing the tools.
#
###############################################################################
# Sysinternals AutoRuns; not in the PATH by default even when
# installed; get from microsoft.com/sysinternals
######### autorunsc.exe -accepteula -a -c | Out-File -FilePath AutoRuns.csv
# SHA256 File Hashes
# Takes a long time! Requires lots of space!
# Add more paths as you wish of course, this is just to get started.
# sha256deep.exe is used instead of Get-FileHash because it's faster.
######### sha256deep.exe -s "c:\*" | Out-File -FilePath Hashes-C.txt
######### sha256deep.exe -s "d:\*" | Out-File -FilePath Hashes-D.txt
######### sha256deep.exe -s -r ($env:PROGRAMFILES + "\*") | Out-File -FilePath Hashes-ProgramFiles.txt
######### sha256deep.exe -s -r ($env:SYSTEMROOT + "\*") | Out-File -FilePath Hashes-SystemRoot.txt
# Save dangerous information too? How aggressive to you want to get?
# For example, https://github.com/GhostPack/Seatbelt
###############################################################################
#
# Record snapshot metadata to README.TXT and Snapshot-File-Hashes.csv:
#
###############################################################################
# Save info about the snapshot output files to README.TXT:
'*Finished: ' + $(Get-Date -Format 'u') | Out-File -Encoding UTF8 -Append -FilePath README.TXT
"-" * 50 | Out-File -Encoding UTF8 -Append -FilePath README.TXT
dir | select Name,Length,LastWriteTime | Out-File -Encoding UTF8 -Append -FilePath README.TXT
# Save hashes and full paths to the snapshot files to a CSV:
if (Get-Command -Name Get-FileHash -ErrorAction SilentlyContinue)
{
$hashes = dir -File | Get-FileHash -Algorithm SHA256 -ErrorAction SilentlyContinue
$hashes | Export-Csv -Path Snapshot-File-Hashes.csv -Force #cannot directly pipe
}
###############################################################################
#
# Perform final tasks, such as writing to an event log, cleaning up temp files,
# compressing the folder into an archive, moving the archive into a shared folder,
# etc. This can also be done in an external wrapper script run as a scheduled task.
#
###############################################################################
# Delete any leftover temp files? What about the hashes list? (del *.tmp)
# Set read-only bit on files created? (attrib.exe +R *.txt)
# Write to the event log about the snapshot process? (write-eventlog)
###############################################################################
#
# THIS COMMAND MUST BE LAST: Go back to the original working directory:
#
###############################################################################
Write-Verbose -Message "Saved files to $(Join-Path -Path $OutputParentFolder -ChildPath $OutputFolder)"
Write-Verbose -Message ("Finished: " + (Get-Date -Format 'F'))
$seconds = New-TimeSpan -Start $StartTime -End (Get-Date) | Select -ExpandProperty TotalSeconds
Write-Verbose -Message "Total run time = $seconds seconds"
cd $PresentDirectory