-
Notifications
You must be signed in to change notification settings - Fork 14
/
Search-ForCompromise.ps1
365 lines (233 loc) · 15.8 KB
/
Search-ForCompromise.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
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
<#
.SYNOPSIS
Search-ForCompromise is a cmdlet created to find/identify whether or not a device has been compromised.
This cmdlet was designed for system administrators. No switches need to be defined other than the computer to run this on if desired.
.DESCRIPTION
This cmdlet is meant to be used to help determine if a computer has been compromised.
It checks the following items
1.) Displays the top 20 heaviest processes. Make sure they are all legit.
2.) If the hosts file has been altered the IP Addresses are displayed. The function then requires the admin to enter the IP Addresses manually. This will close any open connections and prevent any more connections to the discovered IP Addresses.
3.) If an altered start page is configured it will be shown to the admin who will need to remove the setting.
4.) Checks local machine and current user registry for any previously unknown applications and shows the unknown apps to the admin. The admin should verify these applications are safe.
5.) Make sure no proxy settings have been configured/altered.
.NOTES
Author: Robert H. Osborne
Alias: tobor
Contact: [email protected]
.LINK
https://osbornepro.com
https://writeups.osbornepro.com
https://btpssecpack.osbornepro.com
https://github.com/tobor88
https://gitlab.com/tobor88
https://www.powershellgallery.com/profiles/tobor
https://www.linkedin.com/in/roberthosborne/
https://www.credly.com/users/roberthosborne/badges
https://www.hackthebox.eu/profile/52286
.EXAMPLE
Search-ForCompromise -ComputerName $ComputerName
.EXAMPLE
Search-ForCompromise
#>
Function Search-ForCompromise {
[CmdletBinding()]
param (
[Parameter(
Mandatory=$false,
ValueFromPipeline=$True,
ValueFromPipelineByPropertyName=$True,
HelpMessage="Enter The hostname of the remote computer you want to check."
)] # End Parameter
[string[]]$ComputerName) # End Param
BEGIN {
# ControlAPpListFile is a list of known applications and should not cause any alarm.
$ControlAppListFile = <\\NETWORKSHARE\file\AppList>
#ControlCUApplistFile is a list of the current users installed applications and is used as a reference
$ControlCUAppListFile = <\\NETWORKSHARE\file\CUAppList>
# ControlHostsFile should be a copy of C:\Windows\system32\Drivers\etc\hosts If this file is ever edited we want to know it has been changed
$ControlHostsFile = <\\NETWORKLOCATION\file\hosts>
} # End BEGIN
#======================================================================
# This part of the function is what runs if function is run locally |
#======================================================================
PROCESS {
If (!($ComputerName)) {
Write-Verbose "Finding the top 20 heaviest running processes....`n"
Get-Process | Sort-Object -Property CPU -Descending | Select-Object -First 20
Read-Host "`nAbove is a list of the top 20 heaviest processes currently running. Take note of anything unusual. Press Enter to continue"
# Check for altered hosts file. Block connections to IP Addresses added to the hosts file
Write-Verbose "`nDetermining whether or not the hosts file has been altered...."
$Diff = Get-Content -Path "C:\Windows\system32\Drivers\etc\hosts"
$Ref = Get-Content -Path $ControlHostsFile
If (Compare-Object -ReferenceObject $Ref -DifferenceObject $Diff) {
$Diff
Write-Warning 'Hosts file has been altered. Take note of any IP Addresses and break their connections by completing the next steps.'
$numberofbad = Read-Host 'How many IP Address have been added to the hosts file? Example: 2'
For ($i = 1; $i -le $numberofbad; $i++) {
Function Block-BadGuy {
[CmdletBinding()]
param(
[Parameter(
Mandatory=$true,
HelpMessage="Enter an IP Address that was added to the hosts file listed in the above output."
)] # End Parameter
[string[]]$IPaddress
) # End Param
If ($IPAddress) {
New-NetFirewallRule -Name "Deny Inbound Connections to $IPAddress" -DisplayName "Deny Inbound Connections from $IPAddress" -Enabled True -Direction Inbound -Protocol ANY -Action Block -Profile ANY -RemoteAddress $IPAddress
New-NetFirewallRule -Name "Deny Outbound Connections to $IPAddress" -DisplayName "Deny Outbound Connections from $IPAddress" -Enabled True -Direction Outbound -Protocol ANY -Action Block -Profile ANY -RemoteAddress $IPAddress
Write-Verbose 'New Firewall rules added to block inbound and outbound connections to the malicious IP Address.'
$BadGuyProcessIDs = Get-NetTCPConnection -RemoteAddress $IPAddress | Select-Object -Property OwningProcess
Foreach ($ProcessId in $BadGuyProcessIDs) {
Stop-Process -Id $ProcessId -Force -PassThru
Write-Verbose "Above are the processes that were stopped which connected to the remote address.`nFirewall rules have been added to block anymore connections to those addresses."
} # End Foreach
} # End if bad guy IP response
Else {
Write-Warning "No IP Address was entered."
} # End Else
} # End Function Block-BadGuy
Block-BadGuy -Verbose
} # End for loop
} # End if for finding an altered hosts file
Else {
Write-Verbose 'Hosts file has not been altered. Moving on to next check.....'
} # End Else
# Check for an altered start page for Internet Explorer
If (Get-Childitem -Path "HKCU:\software\Microsoft\Internet Explorer\Main\Start Page Redirect=*") {
Read-Host 'Internet Explorer start page redirect found. Make sure it is not malicious.'
} # End if for finding start page redirect
# Checks local machine registry
$LMAppRef = Import-Csv -Path $ControlAppListFile
$LMAppDiff = Get-ChildItem -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\' | Select-Object -Property PSChildName
If ($LMApplist = Compare-Object -DifferenceObject $LMAppDiff -ReferenceObject $LMAppRef -Property PsChildName | Where-Object -Property SideIndicator -like "<=" | Select-Object -ExpandProperty PSChildName ) {
$LMApplist
Write-Warning 'This is a list of previously unrecorded Application Processes. Check these results to find any possibly malicous applications.'
$LMApplist | Export-Csv -Path $ControlAppListFile -Append
} # End if AppList
Else {
Write-Verbose 'No previously unknown application services were found under Local Machine.'
} # End Else
# Checks Current User Registry
$CUAppRef = Import-Csv -Path $ControlCUAppListFile
$CUAppDiff = Get-ChildItem -Path 'HKCU:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\' | Select-Object -Property PSChildName
If ($Applist = Compare-Object -DifferenceObject $CUAppDiff -ReferenceObject $CUAppRef -Property PsChildName | Where-Object -Property SideIndicator -like "<=" | Select-Object -ExpandProperty PSChildName ) {
$CUApplist
Write-Warning 'This is a list of previously unrecorded Application Processes. Check these results to find any possibly malicous applications.'
$CUApplist | Export-Csv -Path $ControlCUAppListFile -Append
} # End if AppList
Else {
Write-Verbose 'No previously unknown application services were found under Current User.'
} # End Else
# Check the proxy settings
If (Get-ChildItem -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Proxy*') {
Write-Warning 'Proxy settings have been configured. This may mean trouble.'
} # End If
Else {
Write-Verbose 'No proxy settings detected.'
} # End Else
# Checking for ADS
Write-Verbose 'Checking for Alternate Data Streams...'
$ADSFiles = Get-ChildItem -Path 'C:\' -Recurse | ForEach-Object { Get-Item $_.FullName -Stream * } | Where-Object { ($_.Stream -ne ':$Data') -and ($_.Stream -ne 'Zone.Identifier') }
If ($ADSFiles) {
ForEach ($ADSFile in $ADSFiles) {
$ADSFilePath = $ADSFile.FileName
$ADSFileNameStream1,$ADSFileNameStream2 = ($ADSFilePath.PSChildName).Split(':')
Remove-Item –Path { $ADSFilePath } –Stream { $ADSFileNameStream2 }
} # End ForEach
} # End If
} # End If not ComputerName
#===============================================================================================
# This part of the function is used if the function needs to be executed on a remote computer |
#================================================================================================
Else {
Invoke-Command -ComputerName $ComputerName -ScriptBlock {
Write-Verbose "Finding the top 20 heaviest running processes....`n"
Get-Process | Sort-Object -Property CPU -Descending | Select-Object -First 20
Read-Host "`nAbove is a list of the top 20 heaviest processes currently running. Take note of anything unusual. Press Enter to continue"
# Check for altered hosts file. Block connections to IP Addresses added to the hosts file
Write-Verbose "`nDetermining whether or not the hosts file has been altered...."
$Diff = Get-Content -Path "C:\Windows\system32\Drivers\etc\hosts"
$Ref = Get-Content -Path $ControlHostsFile
If (Compare-Object -ReferenceObject $Ref -DifferenceObject $Diff) {
$Diff
Write-Warning 'Hosts file has been altered. Take note of any IP Addresses and break their connections by completing the next steps.'
$numberofbad = Read-Host 'How many IP Address have been added to the hosts file? Example: 2'
For ($i = 1; $i -le $numberofbad; $i++) {
Function Block-BadGuy {
[CmdletBinding()]
param(
[Parameter(
Mandatory=$true,
HelpMessage="Enter an IP Address that was added to the hosts file listed in the above output."
)] # End Parameter
[string[]]$IPaddress
) # End Param
If ($IPAddress) {
New-NetFirewallRule -Name "Deny Inbound Connections to $IPAddress" -DisplayName "Deny Inbound Connections from $IPAddress" -Enabled True -Direction Inbound -Protocol ANY -Action Block -Profile ANY -RemoteAddress $IPAddress
New-NetFirewallRule -Name "Deny Outbound Connections to $IPAddress" -DisplayName "Deny Outbound Connections from $IPAddress" -Enabled True -Direction Outbound -Protocol ANY -Action Block -Profile ANY -RemoteAddress $IPAddress
Write-Verbose 'New Firewall rules added to block inbound and outbound connections to the malicious IP Address.'
$BadGuyProcessIDs = Get-NetTCPConnection -RemoteAddress $IPAddress | Select-Object -Property OwningProcess
ForEach ($ProcessId in $BadGuyProcessIDs) {
Stop-Process -Id $ProcessId -Force -PassThru
Write-Verbose "Above are the processes that were stopped which connected to the remote address.`nFirewall rules have been added to block anymore connections to those addresses."
} # End Foreach
} # End if bad guy IP response
Else {
Write-Warning "No IP Address was entered."
} # End Else
} # End Function Block-BadGuy
Block-BadGuy -Verbose
} # End for loop
} # End if for finding an altered hosts file
Else {
Write-Verbose 'Hosts file has not been altered. Moving on to next check.....'
} # End Else
# Check for altered Internet Explorer Start Page
If (Get-Childitem -Path "HKCU:\software\Microsoft\Internet Explorer\Main\Start Page Redirect=*") {
Write-Warning 'Internet Explorer start page redirect found. Make sure it is not malicious.'
} # End if for finding start page redirect
# Checks local machine registry
$LMAppRef = Import-Csv -Path $ControlAppListFile
$LMAppDiff = Get-ChildItem -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\' | Select-Object -Property PSChildName
If ($LMApplist = Compare-Object -DifferenceObject $LMAppDiff -ReferenceObject $LMAppRef -Property PsChildName | Where-Object -Property SideIndicator -like "<=" | Select-Object -ExpandProperty PSChildName ) {
$LMApplist
Write-Warning 'This is a list of previously unrecorded Application Processes. Check these results to find any possibly malicous applications.'
$LMApplist | Export-Csv -Path $ControlAppListFile -Append
} # End if AppList
Else {
Write-Verbose 'No previously unknown application services were found under Local Machine.'
} # End Else
# Checks Current User Registry
$CUAppRef = Import-Csv -Path $ControlCUAppListFile
$CUAppDiff = Get-ChildItem -Path 'HKCU:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\' | Select-Object -Property PSChildName
If ($Applist = Compare-Object -DifferenceObject $CUAppDiff -ReferenceObject $CUAppRef -Property PsChildName | Where-Object -Property SideIndicator -like "<=" | Select-Object -ExpandProperty PSChildName ) {
$CUApplist
Write-Warning 'This is a list of previously unrecorded Application Processes. Check these results to find any possibly malicous applications.'
$CUApplist | Export-Csv -Path $ControlCUAppListFile -Append
} # End if AppList
Else {
Write-Verbose 'No previously unknown application services were found under Current User.'
} # End Else
# Check the proxy settings
If (Get-ChildItem -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Proxy*') {
Write-Warning 'Proxy settings have been configured. This may mean trouble.'
} # End If
Else {
Write-Verbose 'No proxy settings detected.'
} # End Else
$ADSFiles = Get-ChildItem -Path 'C:\' -Recurse | ForEach-Object { Get-Item $_.FullName -Stream * } | Where-Object { ($_.Stream -ne ':$Data') -and ($_.Stream -ne 'Zone.Identifier') }
If ($ADSFiles) {
ForEach ($ADSFile in $ADSFiles) {
$ADSFilePath = $ADSFile.FileName
$ADSFileNameStream1,$ADSFileNameStream2 = ($ADSFilePath.PSChildName).Split(':')
Remove-Item –Path { $ADSFilePath } –Stream { $ADSFileNameStream2 }
} # End ForEach
} # End If
} # End Invoke-Command
} # End Else
} # End PROCESS
END {
Write-Verbose "Execution of command has completed."
} # End END
} # End Function