├── .gitattributes ├── .gitignore ├── DeepBlue.ps1 ├── DeepBlue.py ├── DeepBlueHash-checker.ps1 ├── DeepBlueHash-collector.ps1 ├── LICENSE ├── README.md ├── READMEs ├── README-DeepBlue.py.md ├── README-DeepBlueHash.md ├── Set-ExecutionPolicy.md └── test.md ├── evtx ├── Powershell-Invoke-Obfuscation-encoding-menu.evtx ├── Powershell-Invoke-Obfuscation-many.evtx ├── Powershell-Invoke-Obfuscation-string-menu.evtx ├── disablestop-eventlog.evtx ├── eventlog-dac.evtx ├── many-events-application.evtx ├── many-events-security.evtx ├── many-events-system.evtx ├── metasploit-psexec-native-target-security.evtx ├── metasploit-psexec-native-target-system.evtx ├── metasploit-psexec-powershell-target-security.evtx ├── metasploit-psexec-powershell-target-system.evtx ├── metasploit-psexec-pwshpayload.evtx ├── metasploit-sysmon.evtx ├── mimikatz-privesc-hashdump.evtx ├── mimikatz-privilegedebug-tokenelevate-hashdump.evtx ├── new-user-security.evtx ├── password-spray.evtx ├── powersploit-security.evtx ├── powersploit-system.evtx ├── psattack-security.evtx ├── sliver-security.evtx ├── sliver-sysmon.evtx ├── smb-password-guessing-security.evtx └── wmi-event-filter-persistance.evtx ├── hashes └── readme.md ├── regexes.txt ├── safelist.txt ├── safelists ├── readme.md └── win10-x64.csv └── t └── runall.ps1 /.gitattributes: -------------------------------------------------------------------------------- 1 | *.ps1 text 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /DeepBlue.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | 4 | A PowerShell module for hunt teaming via Windows event logs 5 | .DESCRIPTION 6 | 7 | DeepBlueCLI can automatically determine events that are typically triggered during a majority of successful breaches, including use of malicious command lines including PowerShell. 8 | .Example 9 | 10 | Process local Windows security event log: 11 | .\DeepBlue.ps1 12 | .\DeepBlue.ps1 -log security 13 | .Example 14 | Process local Windows system event log: 15 | 16 | .\DeepBlue.ps1 -log system 17 | .\DeepBlue.ps1 "" system 18 | .Example 19 | Process evtx file: 20 | 21 | .\DeepBlue.ps1 .\evtx\new-user-security.evtx 22 | .\DeepBlue.ps1 -file .\evtx\new-user-security.evtx 23 | .LINK 24 | https://github.com/sans-blue-team/DeepBlueCLI 25 | 26 | #> 27 | 28 | # DeepBlueCLI 3.0 29 | # Eric Conrad, Backshore Communications, LLC 30 | # deepblue backshore net 31 | # Twitter: @eric_conrad 32 | # http://ericconrad.com 33 | # 34 | 35 | param ([string]$file=$env:file,[string]$log=$env:log) 36 | 37 | function Main { 38 | # Set up the global variables 39 | $text="" # Temporary scratch pad variable to hold output text 40 | $minlength=1000 # Minimum length of command line to alert 41 | # Load cmd match regexes from csv file, ignore comments 42 | $regexes = Get-Content ".\regexes.txt" | Select-String '^[^#]' | ConvertFrom-Csv 43 | # Load cmd safelist regexes from csv file, ignore comments 44 | $safelist = Get-Content ".\safelist.txt" | Select-String '^[^#]' | ConvertFrom-Csv 45 | $logname=Check-Options $file $log 46 | #"Processing the " + $logname + " log..." 47 | $filter=Create-Filter $file $logname 48 | # Password guessing/spraying variables: 49 | $maxfailedlogons=5 # Alert after this many failed logons 50 | $failedlogons=@{} # HashTable of failed logons per user 51 | $totalfailedlogons=0 # Total number of failed logons (for all accounts) 52 | $totalfailedaccounts=0 # Total number of accounts with a failed logon 53 | # Track total Sensitive Privilege Use occurrences 54 | $totalsensprivuse=0 55 | $maxtotalsensprivuse=4 56 | # Admin logon variables: 57 | $totaladminlogons=0 # Total number of logons with SeDebugPrivilege 58 | $maxadminlogons=10 # Alert after this many admin logons 59 | $adminlogons=@{} # HashTable of admin logons 60 | $multipleadminlogons=@{} #Hashtable to track multiple admin logons per account 61 | $alert_all_admin=0 # Set to 1 to alert every admin logon (set to 0 disable this) 62 | # Obfuscation variables: 63 | $minpercent=.65 # minimum percentage of alphanumeric and common symbols 64 | $maxbinary=.50 # Maximum percentage of zeros and ones to detect binary encoding 65 | # Password spray variables: 66 | $passspraytrack = @{} 67 | $passsprayuniqusermax = 6 68 | $passsprayloginmax = 6 69 | $passsprayuniqaccounts = 0 70 | # Sysmon variables: 71 | # Check for unsigned EXEs/DLLs. This can be very chatty, so it's disabled. 72 | # Set $checkunsigned to 1 to enable: 73 | $checkunsigned = 0 74 | # 75 | # Get the events: 76 | try{ 77 | $events = iex "Get-WinEvent $filter -ErrorAction Stop" 78 | } 79 | catch { 80 | Write-Host "Get-WinEvent $filter -ErrorAction Stop" 81 | Write-Host "Get-WinEvent error: " $_.Exception.Message "`n" 82 | Write-Host "Exiting...`n" 83 | exit 84 | } 85 | ForEach ($event in $events) { 86 | # Custom reporting object: 87 | $obj = [PSCustomObject]@{ 88 | Date = $event.TimeCreated 89 | Log = $logname 90 | EventID = $event.id 91 | Message = $event.message 92 | Results = "" 93 | Command = "" 94 | Decoded = "" 95 | } 96 | $eventXML = [xml]$event.ToXml() 97 | $servicecmd=0 # CLIs via service creation get extra checks, this defaults to 0 (no extra checks) 98 | if ($logname -eq "Security"){ 99 | if ($event.id -eq 4688){ 100 | # A new process has been created. (Command Line Logging) 101 | $commandline=$eventXML.Event.EventData.Data[8]."#text" # Process Command Line 102 | $creator=$eventXML.Event.EventData.Data[13]."#text" # Creator Process Name 103 | if ($commandline){ 104 | Check-Command -EventID 4688 105 | } 106 | } 107 | ElseIf ($event.id -eq 4672){ 108 | # Special privileges assigned to new logon (possible admin access) 109 | $username=$eventXML.Event.EventData.Data[1]."#text" 110 | $domain=$eventXML.Event.EventData.Data[2]."#text" 111 | $securityid=$eventXML.Event.EventData.Data[3]."#text" 112 | $privileges=$eventXML.Event.EventData.Data[4]."#text" 113 | if ($privileges -Match "SeDebugPrivilege") { #Admin account with SeDebugPrivilege 114 | if ($alert_all_admin){ # Alert for every admin logon 115 | $obj.Message = "Logon with SeDebugPrivilege (admin access)" 116 | $obj.Results = "Username: $username`n" 117 | $obj.Results += "Domain: $domain`n" 118 | $obj.Results += "User SID: $securityid`n" 119 | $obj.Results += "Privileges: $privileges" 120 | Write-Output $obj 121 | } 122 | # Track User SIDs used during admin logons (can track one account logging into multiple systems) 123 | $totaladminlogons+=1 124 | if($adminlogons.ContainsKey($username)){ 125 | $string=$adminlogons.$username 126 | if (-Not ($string -Match $securityid)){ # One username with multiple admin logon SIDs 127 | $multipleadminlogons.Set_Item($username,1) 128 | $string+=" $securityid" 129 | $adminlogons.Set_Item($username,$string) 130 | } 131 | } 132 | Else{ 133 | $adminlogons.add($username,$securityid) 134 | 135 | #$adminlogons.$username=$securityid 136 | } 137 | #$adminlogons.Set_Item($username,$securitysid) 138 | #$adminlogons($username)+=($securitysid) 139 | } 140 | # This unique privilege list is used by Mimikatz 2.2.0 141 | # Disabling due to false-positive with MS Exchange. 142 | # If ($privileges -Match "SeAssignPrimaryTokenPrivilege" ` 143 | # -And $privileges -Match "SeTcbPrivilege" ` 144 | # -And $privileges -Match "SeSecurityPrivilege" ` 145 | # -And $privileges -Match "SeTakeOwnershipPrivilege" ` 146 | # -And $privileges -Match "SeLoadDriverPrivilege" ` 147 | # -And $privileges -Match "SeBackupPrivilege" ` 148 | # -And $privileges -Match "SeRestorePrivilege" ` 149 | # -And $privileges -Match "SeDebugPrivilege" ` 150 | # -And $privileges -Match "SeAuditPrivilege" ` 151 | # -And $privileges -Match "SeSystemEnvironmentPrivilege" ` 152 | # -And $privileges -Match "SeImpersonatePrivilege" ` 153 | # -And $privileges -Match "SeDelegateSessionUserImpersonatePrivilege") { 154 | # $obj.Message = "Mimikatz token::elevate Privilege Use" 155 | # $obj.Results = "Username: $username`n" 156 | # $obj.Results += "Domain: $domain`n" 157 | # $obj.Results += "User SID: $securityid`n" 158 | # $pprivileges = $privileges -replace "`n",", " -replace "\s+"," " 159 | # $obj.Results += "Privileges: $pprivileges" 160 | # Write-Output($obj) 161 | # } 162 | # This unique privilege list is used by Metasploit exploit/windows/smb/psexec (v5.0.4 tested) 163 | # # Disabling due to false-positive with MS Exchange Server 164 | # If ($privileges -Match "SeSecurityPrivilege" ` 165 | # -And $privileges -Match "SeBackupPrivilege" ` 166 | # -And $privileges -Match "SeRestorePrivilege" ` 167 | # -And $privileges -Match "SeTakeOwnershipPrivilege" ` 168 | # -And $privileges -Match "SeDebugPrivilege" ` 169 | # -And $privileges -Match "SeSystemEnvironmentPrivilege" ` 170 | # -And $privileges -Match "SeLoadDriverPrivilege" ` 171 | # -And $privileges -Match "SeImpersonatePrivilege" ` 172 | # -And $privileges -Match "SeDelegateSessionUserImpersonatePrivilege") { 173 | # $obj.Message = "Metasploit psexec Privilege Use" 174 | # $obj.Results = "Username: $username`n" 175 | # $obj.Results += "Domain: $domain`n" 176 | # $obj.Results += "User SID: $securityid`n" 177 | # $pprivileges = $privileges -replace "`n",", " -replace "\s+"," " 178 | # $obj.Results += "Privileges: $pprivileges" 179 | # Write-Output($obj) 180 | # } 181 | } 182 | ElseIf ($event.id -eq 4720){ 183 | # A user account was created. 184 | $username=$eventXML.Event.EventData.Data[0]."#text" 185 | $securityid=$eventXML.Event.EventData.Data[2]."#text" 186 | $obj.Message = "New User Created" 187 | $obj.Results = "Username: $username`n" 188 | $obj.Results += "User SID: $securityid`n" 189 | Write-Output $obj 190 | } 191 | ElseIf(($event.id -eq 4728) -or ($event.id -eq 4732) -or ($event.id -eq 4756)){ 192 | # A member was added to a security-enabled (global|local|universal) group. 193 | $groupname=$eventXML.Event.EventData.Data[2]."#text" 194 | # Check if group is Administrators, may later expand to all groups 195 | if ($groupname -eq "Administrators"){ 196 | $username=$eventXML.Event.EventData.Data[0]."#text" 197 | $securityid=$eventXML.Event.EventData.Data[1]."#text" 198 | switch ($event.id){ 199 | 4728 {$obj.Message = "User added to global $groupname group"} 200 | 4732 {$obj.Message = "User added to local $groupname group"} 201 | 4756 {$obj.Message = "User added to universal $groupname group"} 202 | } 203 | $obj.Results = "Username: $username`n" 204 | $obj.Results += "User SID: $securityid`n" 205 | Write-Output $obj 206 | } 207 | } 208 | ElseIf($event.id -eq 4625){ 209 | # An account failed to log on. 210 | # Requires auditing logon failures 211 | # https://technet.microsoft.com/en-us/library/cc976395.aspx 212 | $totalfailedlogons+=1 213 | $username=$eventXML.Event.EventData.Data[5]."#text" 214 | if($failedlogons.ContainsKey($username)){ 215 | $count=$failedlogons.Get_Item($username) 216 | $failedlogons.Set_Item($username,$count+1) 217 | } 218 | Else{ 219 | $failedlogons.Set_Item($username,1) 220 | $totalfailedaccounts+=1 221 | } 222 | } 223 | ElseIf($event.id -eq 4673){ 224 | # Sensitive Privilege Use (Mimikatz) 225 | $totalsensprivuse+=1 226 | # use -eq here to avoid multiple log notices 227 | if ($totalsensprivuse -eq $maxtotalsensprivuse) { 228 | $obj.Message = "Sensitive Privilege Use Exceeds Threshold" 229 | $obj.Results = "Potentially indicative of Mimikatz, multiple sensitive privilege calls have been made.`n" 230 | 231 | $username=$eventXML.Event.EventData.Data[1]."#text" 232 | $domainname=$eventXML.Event.EventData.Data[2]."#text" 233 | 234 | $obj.Results += "Username: $username`n" 235 | $obj.Results += "Domain Name: $domainname`n" 236 | Write-Output $obj 237 | } 238 | } 239 | ElseIf($event.id -eq 4674){ 240 | # An operation was attempted on a privileged object. 241 | if ($event.Message){ 242 | # Message is a blob of text that looks like this: 243 | ######################################################### 244 | # An operation was attempted on a privileged object. 245 | # 246 | # Subject: 247 | # Security ID: SEC504STUDENT\Sec504 248 | # Account Name: Sec504 249 | # Account Domain: SEC504STUDENT 250 | # Logon ID: 251 | # 252 | # Object: 253 | # Object Server: SC Manager 254 | # Object Type: SERVICE OBJECT 255 | # Object Name: nginx 256 | # Object Handle: 257 | # 258 | # Process Information: 259 | # Process ID: 0x21c 260 | # Process Name: C:\Windows\System32\services.exe 261 | # 262 | # Requested Operation: 263 | # Desired Access: WRITE_DAC 264 | # 265 | # Privileges: SeSecurityPrivilege 266 | $array = $event.message -split '\n' # Split each line of the message into an array 267 | $text = $array[0] 268 | $application = Remove-Spaces($array[3]) 269 | $user = Remove-Spaces(($array[4] -split ':')[1]) 270 | $service = Remove-Spaces(($array[11] -split ':')[1]) 271 | $application = Remove-Spaces(($array[16] -split ': ')[1]) 272 | $accessreq = Remove-Spaces(($array[19] -split ':')[1]) 273 | 274 | if ($application.ToUpper() -Eq "C:\WINDOWS\SYSTEM32\SERVICES.EXE" ` 275 | -And $accessreq.ToUpper() -Match "WRITE_DAC") { 276 | $obj.Message="Possible Hidden Service Attempt" 277 | $obj.Command = "" 278 | $obj.Results = "User requested to modify the Dynamic Access Control (DAC) permissions of a service, possibly to hide it from view.`n" 279 | $obj.Results += "User: $user`n" 280 | $obj.Results += "Target service: $service`n" 281 | $obj.Results += "Desired Access: $accessreq`n" 282 | Write-Output $obj 283 | } 284 | } 285 | } 286 | ElseIf($event.id -eq 4648){ 287 | # A logon was attempted using explicit credentials. 288 | $username=$eventXML.Event.EventData.Data[1]."#text" 289 | $hostname=$eventXML.Event.EventData.Data[2]."#text" 290 | $targetusername=$eventXML.Event.EventData.Data[5]."#text" 291 | $sourceip=$eventXML.Event.EventData.Data[12]."#text" 292 | 293 | # For each #4648 event, increment a counter in $passspraytrack. If that counter exceeds 294 | # $passsprayloginmax, then check for $passsprayuniqusermax also exceeding threshold and raise 295 | # a notice. 296 | if ($passspraytrack[$targetusername] -eq $null) { 297 | $passspraytrack[$targetusername] = 1 298 | } else { 299 | $passspraytrack[$targetusername] += 1 300 | } 301 | if ($passspraytrack[$targetusername] -gt $passsprayloginmax) { 302 | # This user account has exceedd the threshoold for explicit logins. Identify the total number 303 | # of accounts that also have similar explicit login patterns. 304 | $passsprayuniquser=0 305 | foreach($key in $passspraytrack.keys) { 306 | if ($passspraytrack[$key] -gt $passsprayloginmax) { 307 | $passsprayuniquser+=1 308 | } 309 | } 310 | if ($passsprayuniquser -gt $passsprayuniqusermax) { 311 | $usernames="" 312 | foreach($key in $passspraytrack.keys) { 313 | $usernames += $key 314 | $usernames += " " 315 | $passsprayuniqaccounts += 1 316 | } 317 | $obj.Message = "Distributed Account Explicit Credential Use (Password Spray Attack)" 318 | $obj.Results = "The use of multiple user account access attempts with explicit credentials is " 319 | $obj.Results += "an indicator of a password spray attack.`n" 320 | $obj.Results += "Target Usernames: $usernames`n" 321 | $obj.results += "Unique accounts sprayed: $passsprayuniqaccounts`n" 322 | $obj.Results += "Accessing Username: $username`n" 323 | $obj.Results += "Accessing Host Name: $hostname`n" 324 | Write-Output $obj 325 | $passspraytrack = @{} # Reset 326 | } 327 | } 328 | } 329 | ElseIf ($event.id -eq 1102){ 330 | # The Audit log file was cleared. 331 | if ($event.Message){ 332 | # Security 1102 Message is a blob of text that looks like this: 333 | # The audit log was cleared. 334 | # Subject: 335 | # Security ID: SEC504STUDENT\Sec504 336 | # Account Name: Sec504 337 | # Domain Name: SEC504STUDENT 338 | # Logon ID: 0x257CD 339 | $array = $event.message -split '\n' # Split each line of the message into an array 340 | $user = Remove-Spaces($array[3]) 341 | } 342 | $obj.Message = "Audit Log Clear" 343 | $obj.Results = "The Audit log was cleared.`n" 344 | $obj.Results += $user 345 | Write-Output $obj 346 | } 347 | } 348 | ElseIf ($logname -eq "System"){ 349 | if ($event.id -eq 7045){ 350 | # A service was installed in the system. 351 | $servicename=$eventXML.Event.EventData.Data[0]."#text" 352 | $commandline=$eventXML.Event.EventData.Data[1]."#text" 353 | # Check for suspicious service name 354 | $text = (Check-Regex $servicename 1) 355 | if ($text){ 356 | $obj.Message = "New Service Created" 357 | $obj.Command = $commandline 358 | $obj.Results = "Service name: $servicename`n" 359 | $obj.Results +=$text 360 | Write-Output $obj 361 | } 362 | # Check for suspicious cmd 363 | if ($commandline){ 364 | $servicecmd=1 # CLIs via service creation get extra checks 365 | Check-Command -EventID 7045 366 | } 367 | } 368 | ElseIf ($event.id -eq 7030){ 369 | # The ... service is marked as an interactive service. However, the system is configured 370 | # to not allow interactive services. This service may not function properly. 371 | $servicename=$eventXML.Event.EventData.Data."#text" 372 | $obj.Message = "Interactive service warning" 373 | $obj.Results = "Service name: $servicename`n" 374 | $obj.Results += "Malware (and some third party software) trigger this warning" 375 | # Check for suspicious service name 376 | $servicecmd=1 # CLIs via service creation get extra check 377 | $obj.Results += (Check-Regex $servicename 1) 378 | Write-Output $obj 379 | } 380 | ElseIf ($event.id -eq 7036){ 381 | # The ... service entered the stopped|running state. 382 | $servicename=$eventXML.Event.EventData.Data[0]."#text" 383 | $text = (Check-Regex $servicename 1) 384 | if ($text){ 385 | $obj.Message = "Suspicious Service Name" 386 | $obj.Results = "Service name: $servicename`n" 387 | $obj.Results += $text 388 | Write-Output $obj 389 | } 390 | } 391 | ElseIf ($event.id -eq 7040){ 392 | # The start type of the Windows Event Log service was changed from auto start to disabled. 393 | $servicename=$eventXML.Event.EventData.Data[0]."#text" 394 | $action = $eventXML.Event.EventData.Data[2]."#text" 395 | if ($servicename -ccontains "Windows Event Log") { 396 | $obj.Results = "Service name: $servicename`n" 397 | $obj.Results += $text 398 | if ($action -eq "disabled") { 399 | $obj.Message = "Event Log Service Stopped" 400 | $obj.Results += "Selective event log manipulation may follow this event." 401 | } elseIf ($action -eq "auto start") { 402 | $obj.Message = "Event Log Service Started" 403 | $obj.Results += "Selective event log manipulation may precede this event." 404 | } 405 | Write-Output $obj 406 | } 407 | } 408 | ElseIf ($event.id -eq 104){ 409 | # The System log file was cleared. 410 | $obj.Message = "System Log Clear" 411 | $obj.Results = $event.message 412 | Write-Output $obj 413 | } 414 | } 415 | ElseIf ($logname -eq "Application"){ 416 | if (($event.id -eq 2) -and ($event.Providername -eq "EMET")){ 417 | # EMET Block 418 | $obj.Message="EMET Block" 419 | if ($event.Message){ 420 | # EMET Message is a blob of text that looks like this: 421 | ######################################################### 422 | # EMET detected HeapSpray mitigation and will close the application: iexplore.exe 423 | # 424 | # HeapSpray check failed: 425 | # Application : C:\Program Files (x86)\Internet Explorer\iexplore.exe 426 | # User Name : WIN-CV6AHH1BNU9\Instructor 427 | # Session ID : 1 428 | # PID : 0xBA8 (2984) 429 | # TID : 0x9E8 (2536) 430 | # Module : mshtml.dll 431 | # Address : 0x6FBA7512, pull out relevant parts 432 | $array = $event.message -split '\n' # Split each line of the message into an array 433 | $text = $array[0] 434 | $application = Remove-Spaces($array[3]) 435 | $command= $application -Replace "^Application: ","" 436 | $username = Remove-Spaces($array[4]) 437 | $obj.Message="EMET Block" 438 | $obj.Command = "$command" 439 | $obj.Results = "$text`n" 440 | $obj.Results += "$username`n" 441 | } 442 | Else{ 443 | # If the message is blank: EMET is not installed locally. 444 | # This occurs when parsing remote event logs sent from systems with EMET installed 445 | $obj.Message="Warning: EMET Message field is blank. Install EMET locally to see full details of this alert" 446 | } 447 | Write-Output $obj 448 | } 449 | } 450 | ElseIf ($logname -eq "Applocker"){ 451 | if ($event.id -eq 8003){ 452 | # ...was allowed to run but would have been prevented from running if the AppLocker policy were enforced. 453 | $obj.Message="Applocker Warning" 454 | $command = $event.message -Replace " was .*$","" 455 | $obj.Command=$command 456 | $obj.Results = $event.message 457 | Write-Output $obj 458 | } 459 | ElseIf ($event.id -eq 8004){ 460 | $obj.Message="Applocker Block" 461 | # ...was prevented from running. 462 | $command = $event.message -Replace " was .*$","" 463 | $obj.Command=$command 464 | $obj.Results = $event.message 465 | Write-Output $obj 466 | } 467 | } 468 | ElseIf ($logname -eq "PowerShell"){ 469 | if ($event.id -eq 4103){ 470 | $commandline= $eventXML.Event.EventData.Data[2]."#text" 471 | if ($commandline -Match "Host Application"){ 472 | # Multiline replace, remove everything before "Host Application = " 473 | $commandline = $commandline -Replace "(?ms)^.*Host.Application = ","" 474 | # Remove every line after the "Host Application = " line. 475 | $commandline = $commandline -Replace "(?ms)`n.*$","" 476 | if ($commandline){ 477 | Check-Command -EventID 4103 478 | } 479 | } 480 | } 481 | ElseIf ($event.id -eq 4104){ 482 | # This section requires PowerShell command logging for event 4104 , which seems to be default with 483 | # Windows 10, but may not not the default with older Windows versions (which may log the script 484 | # block but not the command that launched it). 485 | # Caveats included because more testing of various Windows versions is needed 486 | # 487 | # If the command itself is not being logged: 488 | # Add the following to \Windows\System32\WindowsPowerShell\v1.0\profile.ps1 489 | # $LogCommandHealthEvent = $true 490 | # $LogCommandLifecycleEvent = $true 491 | # 492 | # See the following for more information: 493 | # 494 | # https://logrhythm.com/blog/powershell-command-line-logging/ 495 | # http://hackerhurricane.blogspot.com/2014/11/i-powershell-logging-what-everyone.html 496 | # 497 | # Thank you: @heinzarelli and @HackerHurricane 498 | # 499 | # The command's path is $eventxml.Event.EventData.Data[4] 500 | # 501 | # Blank path means it was run as a commandline. CLI parsing is *much* simpler than 502 | # script parsing. See Revoke-Obfuscation for parsing the script blocks: 503 | # 504 | # https://github.com/danielbohannon/Revoke-Obfuscation 505 | # 506 | # Thanks to @danielhbohannon and @Lee_Holmes 507 | # 508 | # This ignores scripts and grabs PowerShell CLIs 509 | if (-not ($eventxml.Event.EventData.Data[4]."#text")){ 510 | $commandline=$eventXML.Event.EventData.Data[2]."#text" 511 | if ($commandline){ 512 | Check-Command -EventID 4104 513 | } 514 | } 515 | } 516 | } 517 | ElseIf ($logname -eq "Sysmon"){ 518 | # Check command lines 519 | if ($event.id -eq 1){ 520 | if ($eventXML.Event.EventData.Data.Count -le 16){ 521 | $creator=$eventXML.Event.EventData.Data[14]."#text" 522 | $commandline=$eventXML.Event.EventData.Data[10]."#text" 523 | } 524 | Else { 525 | $creator=$eventXML.Event.EventData.Data[20]."#text" 526 | $commandline=$eventXML.Event.EventData.Data[10]."#text" 527 | } 528 | if ($commandline){ 529 | Check-Command -EventID 1 530 | } 531 | } 532 | ElseIf ($event.id -eq 7){ 533 | # Check for unsigned EXEs/DLLs: 534 | # This can be very chatty, so it's disabled. 535 | # Set $checkunsigned to 1 (global variable section) to enable: 536 | if ($checkunsigned){ 537 | if ($event.Properties.Count -lt 14){ 538 | if ($eventXML.Event.EventData.Data[6]."#text" -eq "false"){ 539 | $obj.Message="Unsigned Image (DLL)" 540 | $image=$eventXML.Event.EventData.Data[3]."#text" 541 | $imageload=$eventXML.Event.EventData.Data[4]."#text" 542 | # $hash=$eventXML.Event.EventData.Data[5]."#text" 543 | $obj.Command=$imageload 544 | $obj.Results= "Loaded by: $image" 545 | Write-Output $obj 546 | } 547 | } 548 | Else{ 549 | if ($eventXML.Event.EventData.Data[11]."#text" -eq "false"){ 550 | $obj.Message="Unsigned Image (DLL)" 551 | $image=$eventXML.Event.EventData.Data[4]."#text" 552 | $imageload=$eventXML.Event.EventData.Data[5]."#text" 553 | # $hash=$eventXML.Event.EventData.Data[10]."#text" 554 | $obj.Command=$imageload 555 | $obj.Results= "Loaded by: $image" 556 | Write-Output $obj 557 | } 558 | } 559 | } 560 | } 561 | ElseIf ($event.id -eq 8){ 562 | #Check remote thread (lsass activity, process migration, etc) 563 | $image=$eventXML.Event.EventData.Data[7]."#text" 564 | $user=$eventXML.Event.EventData.Data[12]."#text" 565 | $sourceimage=$eventXML.Event.EventData.Data[4]."#text" 566 | If ($image -Match "lsass.exe"){ 567 | $creatortext += "Remote thread to $image`n" 568 | $obj.Message="Suspicious remote thread" 569 | $imageload=$eventXML.Event.EventData.Data[7]."#text" 570 | $obj.Command=$imageload 571 | $obj.Results= "Remote thread created to: $image from: $sourceimage by $user" 572 | Write-Output $obj 573 | } 574 | ElseIf ($user -notmatch "SYSTEM"){ 575 | $creatortext += "Remote thread to $image`n" 576 | $obj.Message="Suspicious remote thread" 577 | $imageload=$eventXML.Event.EventData.Data[7]."#text" 578 | $obj.Command=$imageload 579 | $obj.Results= "Remote thread created to: $image from: $sourceimage by $user" 580 | Write-Output $obj 581 | } 582 | } 583 | 584 | } 585 | ElseIf ($logname -eq "WMI-Activity"){ 586 | # Check commandlines for suspicious commands 587 | if ($event.id -eq 5861){ 588 | if($event.Message -match ".*CommandLineTemplate\s=\s(.*?);"){ 589 | $command = $event.message 590 | $obj.Message = "Suspicous WMI Event Filter" 591 | $obj.Results += "Event Triggered Execution: WMI - T1546.003`n" 592 | $obj.Results += $event.message 593 | $obj.Command=$matches[0].Split("=")[1] 594 | Write-Output $obj 595 | } 596 | } 597 | } 598 | } 599 | # Iterate through admin logons hashtable (key is $username) 600 | foreach ($username in $adminlogons.Keys) { 601 | $securityid=$adminlogons.Get_Item($username) 602 | if($multipleadminlogons.$username){ 603 | $obj.Message="Multiple admin logons for one account" 604 | $obj.Results= "Username: $username`n" 605 | $obj.Results += "User SID Access Count: " + $securityid.split().Count 606 | $obj.EventId = 4672 607 | Write-Output $obj 608 | } 609 | } 610 | # Iterate through failed logons hashtable (key is $username) 611 | foreach ($username in $failedlogons.Keys) { 612 | $count=$failedlogons.Get_Item($username) 613 | if ($count -gt $maxfailedlogons){ 614 | $obj.Message="High number of logon failures for one account" 615 | $obj.Results= "Username: $username`n" 616 | $obj.Results += "Total logon failures: $count" 617 | $obj.EventId = 4625 618 | Write-Output $obj 619 | } 620 | } 621 | # Password spraying: 622 | if (($totalfailedlogons -gt $maxfailedlogons) -and ($totalfailedaccounts -gt 1)) { 623 | $obj.Message="High number of total logon failures for multiple accounts" 624 | $obj.Results= "Total accounts: $totalfailedaccounts`n" 625 | $obj.Results+= "Total logon failures: $totalfailedlogons`n" 626 | $obj.EventId = 4625 627 | Write-Output $obj 628 | } 629 | } 630 | 631 | function Check-Options($file, $log) 632 | { 633 | $log_error="Unknown and/or unsupported log type" 634 | $logname="" 635 | # Checks the command line options, return logname to parse 636 | if($file -eq ""){ # No filename provided, parse local logs 637 | if(($log -eq "") -or ($log -eq "Security")){ # Parse the security log if no log was selected 638 | $logname="Security" 639 | } 640 | ElseIf ($log -eq "System"){ 641 | $logname="System" 642 | } 643 | ElseIf ($log -eq "Application"){ 644 | $logname="Application" 645 | } 646 | ElseIf ($log -eq "Sysmon"){ 647 | $logname="Sysmon" 648 | } 649 | ElseIf ($log -eq "Powershell"){ 650 | $logname="Powershell" 651 | } 652 | Else{ 653 | write-host $log_error 654 | exit 1 655 | } 656 | } 657 | else{ # Filename provided, check if it exists: 658 | if (Test-Path $file){ # File exists. Todo: verify it is an evtx file. 659 | # Get-WinEvent will generate this error for non-evtx files: "...file does not appear to be a valid log file. 660 | # Specify only .evtx, .etl, or .evt filesas values of the Path parameter." 661 | # 662 | # Check the LogName of the first event 663 | try{ 664 | $event=Get-WinEvent -path $file -max 1 -ErrorAction Stop 665 | } 666 | catch 667 | { 668 | Write-Host "Get-WinEvent error: " $_.Exception.Message "`n" 669 | Write-Host "Exiting...`n" 670 | exit 671 | } 672 | switch ($event.LogName){ 673 | "Security" {$logname="Security"} 674 | "System" {$logname="System"} 675 | "Application" {$logname="Application"} 676 | "Microsoft-Windows-AppLocker/EXE and DLL" {$logname="Applocker"} 677 | "Microsoft-Windows-PowerShell/Operational" {$logname="Powershell"} 678 | "Microsoft-Windows-Sysmon/Operational" {$logname="Sysmon"} 679 | "Microsoft-Windows-WMI-Activity/Operational" {$logname="WMI-Activity"} 680 | default {"Logic error 3, should not reach here...";Exit 1} 681 | } 682 | } 683 | else{ # Filename does not exist, exit 684 | Write-host "Error: no such file. Exiting..." 685 | exit 1 686 | } 687 | } 688 | return $logname 689 | } 690 | 691 | function Create-Filter($file, $logname) 692 | { 693 | # Return the Get-Winevent filter 694 | # 695 | $sys_events="7030,7036,7045,7040,104" 696 | $sec_events="4688,4672,4720,4728,4732,4756,4625,4673,4674,4648,1102" 697 | $app_events="2" 698 | $applocker_events="8003,8004,8006,8007" 699 | $powershell_events="4103,4104" 700 | $sysmon_events="1,7,8" 701 | $wmi_events="5861" 702 | if ($file -ne ""){ 703 | switch ($logname){ 704 | "Security" {$filter="@{path=""$file"";ID=$sec_events}"} 705 | "System" {$filter="@{path=""$file"";ID=$sys_events}"} 706 | "Application" {$filter="@{path=""$file"";ID=$app_events}"} 707 | "Applocker" {$filter="@{path=""$file"";ID=$applocker_events}"} 708 | "Powershell" {$filter="@{path=""$file"";ID=$powershell_events}"} 709 | "Sysmon" {$filter="@{path=""$file"";ID=$sysmon_events}"} 710 | "WMI-Activity"{$filter="@{path=""$file"";ID=$wmi_events}"} 711 | default {"Logic error 1, should not reach here...";Exit 1} 712 | } 713 | } 714 | else{ 715 | switch ($logname){ 716 | "Security" {$filter="@{Logname=""Security"";ID=$sec_events}"} 717 | "System" {$filter="@{Logname=""System"";ID=$sys_events}"} 718 | "Application" {$filter="@{Logname=""Application"";ID=$app_events}"} 719 | "Applocker" {$filter="@{logname=""Microsoft-Windows-AppLocker/EXE and DLL"";ID=$applocker_events}"} 720 | "Powershell" {$filter="@{logname=""Microsoft-Windows-PowerShell/Operational"";ID=$powershell_events}"} 721 | "Sysmon" {$filter="@{logname=""Microsoft-Windows-Sysmon/Operational"";ID=$sysmon_events}"} 722 | "WMI-Activity"{$filter="@{logname=""Microsoft-Windows-WMI-Activity/Operational"";ID=$wmi_events}"} 723 | default {"Logic error 2, should not reach here...";Exit 1} 724 | } 725 | } 726 | return $filter 727 | } 728 | 729 | 730 | function Check-Command(){ 731 | 732 | Param($EventID) 733 | 734 | $text="" 735 | $base64="" 736 | # Check to see if command is safelisted 737 | foreach ($entry in $safelist) { 738 | if ($commandline -Match $entry.regex) { 739 | # Command is safelisted, return nothing 740 | return 741 | } 742 | } 743 | if ($commandline.length -gt $minlength){ 744 | $text += "Long Command Line: greater than $minlength bytes`n" 745 | } 746 | $text += (Check-Obfu $commandline) 747 | $text += (Check-Regex $commandline 0) 748 | $text += (Check-Creator $commandline $creator) 749 | # Check for base64 encoded function, decode and print if found 750 | # This section is highly use case specific, other methods of base64 encoding and/or compressing may evade these checks 751 | if ($commandline -Match "\-enc.*[A-Za-z0-9/+=]{100}"){ 752 | $base64= $commandline -Replace "^.* \-Enc(odedCommand)? ","" 753 | } 754 | ElseIf ($commandline -Match "\-En.*[A-Za-z0-9/+=]{100}"){ 755 | $base64= $commandline -Replace "^.* \-En","" 756 | } 757 | ElseIf ($commandline -Match ":FromBase64String\("){ 758 | $base64 = $commandline -Replace "^.*:FromBase64String\(\'*","" 759 | $base64 = $base64 -Replace "\'.*$","" 760 | } 761 | if ($base64){ 762 | if ($commandline -Match "Compression.GzipStream.*Decompress"){ 763 | # Metasploit-style compressed and base64-encoded function. Uncompress it. 764 | $decoded=New-Object IO.MemoryStream(,[Convert]::FromBase64String($base64)) 765 | $uncompressed=(New-Object IO.StreamReader(((New-Object IO.Compression.GzipStream($decoded,[IO.Compression.CompressionMode]::Decompress))),[Text.Encoding]::ASCII)).ReadToEnd() 766 | $obj.Decoded=$uncompressed 767 | $text += "Base64-encoded and compressed function`n" 768 | } 769 | else{ 770 | $decoded = [System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($base64)) 771 | $obj.Decoded=$decoded 772 | $text += "Base64-encoded function`n" 773 | $text += (Check-Obfu $decoded) 774 | $text += (Check-Regex $decoded 0) 775 | } 776 | } 777 | if ($text){ 778 | if ($servicecmd){ 779 | $obj.Message = "Suspicious Service Command" 780 | $obj.Results = "Service name: $servicename`n" 781 | } 782 | Else{ 783 | $obj.Message = "Suspicious Command Line" 784 | } 785 | $obj.Command = $commandline 786 | $obj.Results += $text 787 | $obj.EventID = $EventID 788 | Write-Output $obj 789 | } 790 | return 791 | } 792 | 793 | function Check-Regex($string,$type){ 794 | $regextext="" # Local variable for return output 795 | foreach ($regex in $regexes){ 796 | if ($regex.Type -eq $type) { # Type is 0 for Commands, 1 for services. Set in regexes.csv 797 | if ($string -Match $regex.regex) { 798 | $regextext += $regex.String + "`n" 799 | } 800 | } 801 | } 802 | #if ($regextext){ 803 | # $regextext = $regextext.Substring(0,$regextext.Length-1) # Remove final newline. 804 | #} 805 | return $regextext 806 | } 807 | 808 | function Check-Obfu($string){ 809 | # Check for special characters in the command. Inspired by Invoke-Obfuscation: https://twitter.com/danielhbohannon/status/778268820242825216 810 | # 811 | $obfutext="" # Local variable for return output 812 | $lowercasestring=$string.ToLower() 813 | $length=$lowercasestring.length 814 | $noalphastring = $lowercasestring -replace "[a-z0-9/\;:|.]" 815 | $nobinarystring = $lowercasestring -replace "[01]" # To catch binary encoding 816 | # Calculate the percent alphanumeric/common symbols 817 | if ($length -gt 0){ 818 | $percent=(($length-$noalphastring.length)/$length) 819 | # Adjust minpercent for very short commands, to avoid triggering short warnings 820 | if (($length/100) -lt $minpercent){ 821 | $minpercent=($length/100) 822 | } 823 | if ($percent -lt $minpercent){ 824 | $percent = "{0:P0}" -f $percent # Convert to a percent 825 | $obfutext += "Possible command obfuscation: only $percent alphanumeric and common symbols`n" 826 | } 827 | # Calculate the percent of binary characters 828 | $percent=(($nobinarystring.length-$length/$length)/$length) 829 | $binarypercent = 1-$percent 830 | if ($binarypercent -gt $maxbinary){ 831 | #$binarypercent = 1-$percent 832 | $binarypercent = "{0:P0}" -f $binarypercent # Convert to a percent 833 | $obfutext += "Possible command obfuscation: $binarypercent zeroes and ones (possible numeric or binary encoding)`n" 834 | } 835 | } 836 | return $obfutext 837 | } 838 | 839 | function Check-Creator($command,$creator){ 840 | $creatortext="" # Local variable for return output 841 | if ($creator){ 842 | if ($command -Match "powershell"){ 843 | if ($creator -Match "PSEXESVC"){ 844 | $creatortext += "PowerShell launched via PsExec: $creator`n" 845 | } 846 | ElseIf($creator -Match "WmiPrvSE"){ 847 | $creatortext += "PowerShell launched via WMI: $creator`n" 848 | } 849 | } 850 | ElseIf ($command -Match "cmd.exe"){ 851 | if ($creator -Match "PSEXESVC"){ 852 | $creatortext += "cmd.exe launched via PsExec: $creator`n" 853 | } 854 | ElseIf($creator -Match "WmiPrvSE"){ 855 | $creatortext += "cmd.exe launched via WMI: $creator`n" 856 | } 857 | } 858 | } 859 | return $creatortext 860 | } 861 | 862 | function Remove-Spaces($string){ 863 | # Changes this: Application : C:\Program Files (x86)\Internet Explorer\iexplore.exe 864 | # to this: Application: C:\Program Files (x86)\Internet Explorer\iexplore.exe 865 | $string = $string.trim() -Replace "\s+:",":" 866 | return $string 867 | } 868 | 869 | . Main 870 | 871 | -------------------------------------------------------------------------------- /DeepBlue.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # DeepBlue.py Alpha 0.12 (post-DerbyCon release) 4 | # Eric Conrad 5 | # Twitter: @eric_conrad 6 | # http://ericconrad.com 7 | # deepblue at backshore dot net 8 | 9 | # Currently alpha level functionality, supports CLI parsing only 10 | # More features to come 11 | 12 | # Requires libevtx: https://github.com/libyal/libevtx 13 | 14 | import sys 15 | import re 16 | import csv 17 | import base64 18 | import os.path 19 | import string 20 | from subprocess import Popen, PIPE 21 | 22 | def filter(str): 23 | # Used to convert base64 decoded data (unicode) to ASCII 24 | return ''.join([c for c in str if ord(c) > 31 or ord(c) == 9]) 25 | 26 | def CheckRegex(regexes,command): 27 | string="" 28 | for regex in regexes: 29 | if (regex[0] == "0"): 30 | if re.search(regex[1],command,re.IGNORECASE): 31 | string+=" - "+regex[2]+"\n" 32 | return(string) 33 | 34 | def CheckObfu(cli,minpercent,minlength): 35 | string="" 36 | noalphastring=re.sub("[A-Za-z0-9]","",cli) 37 | length1=float(len(cli)) 38 | if (length1 > minlength): 39 | length2=float(len(noalphastring)) 40 | if ((length1/150) < minpercent): 41 | minpercent=length1/150 # Shorter strings get lower minpercent, based on the string length 42 | percent =((length1-length2)/length1) 43 | if (percent < minpercent): 44 | percent=(round(percent,2))*100 45 | string += " - Potential command obfuscation: "+str(int(percent))+"% alpha characters" 46 | return(string) 47 | 48 | def CheckCommand(time, log, eventid, cli): 49 | minpercent=.65 50 | minlength=25 # Minimum CLI length to check for obfuscation 51 | string="" 52 | decoded="" 53 | noalphastring="" 54 | string=CheckRegex(regexes,cli) 55 | if re.search("\-enc.*[A-Za-z0-9/+=]{100}",cli,re.IGNORECASE): 56 | b64=re.sub("^.* \-Enc(odedCommand)? ","",cli,re.IGNORECASE) 57 | decoded=base64.b64decode(b64) 58 | decoded=str(filter(decoded)) # Convert base64 to ASCII 59 | string+=CheckRegex(regexes,decoded) 60 | string += CheckObfu(cli,minpercent,minlength) 61 | if(string): 62 | print "Date: %s\nLog: %s\nEventID: %s" % (time,log,eventid) 63 | print "Results:\n%s\n" % (string.rstrip()) 64 | print "Command: %s\n" % (cli) 65 | if(decoded): 66 | print "Decoded: %s" % (decoded) 67 | if(string): 68 | print "\n" 69 | 70 | filename="" 71 | regexfile="regexes.txt" 72 | regexes=[] 73 | if len(sys.argv)==2: 74 | if os.path.isfile(sys.argv[1]): 75 | filename=sys.argv[1] 76 | if os.path.isfile(regexfile): 77 | with open(regexfile) as csvfile: 78 | reader = csv.reader(csvfile, delimiter=',') 79 | for row in reader: 80 | if not row[0].startswith('#'): 81 | regexes.append(row) 82 | else: 83 | print "Error: cannot open "+regexfile+"\n" 84 | else: 85 | print "Error: no such file: %s\n" % (sys.argv) 86 | else: 87 | print "Error: filename required as an argument\n" 88 | 89 | if (filename and regexes): 90 | process="" 91 | try: 92 | process = Popen(['evtxexport', filename], stdout=PIPE, stderr=PIPE) 93 | except: 94 | print 'Can\'t find libevtx. Check the path and verify it is installed. See: https://github.com/libyal/libevtx' 95 | 96 | if (process): 97 | time="" 98 | log="" 99 | eventid="" 100 | cli="" 101 | path="" 102 | for line in iter(process.stdout.readline,''): 103 | if re.search("^Written time",line): 104 | #Written time : Aug 30, 2017 19:16:26.133985000 UTC 105 | time = re.sub("^.*: ","",line) 106 | time = time[:21] 107 | elif re.search("^Source name",line): 108 | log = re.sub("^.*: ","",line).rstrip() 109 | elif re.search("^Event identifier",line): 110 | # Looks like this, grab the number between the parentheses: 111 | #Event identifier : 0x00001008 (4104) 112 | #Event identifier : 0x00000001 (1) 113 | eventid = re.sub("^.*\(","",line.rstrip()) 114 | eventid = re.sub("\).*$","",eventid) 115 | elif re.search("^String: 3",line): 116 | #Source name : Microsoft-Windows-PowerShell 117 | if log=="Microsoft-Windows-PowerShell": 118 | cli = line[14:].rstrip() 119 | elif re.search("^String: 5",line): 120 | if log=="Microsoft-Windows-PowerShell": 121 | path = line[14:].rstrip() 122 | elif log=="Microsoft-Windows-Sysmon": 123 | cli = line[14:].rstrip() 124 | elif re.search("^String: 9",line): 125 | if log=="Microsoft-Windows-Security-Auditing": 126 | cli = line[14:].rstrip() 127 | elif re.search("^$",line): 128 | # 4688: CLI via System log 129 | # 4104: PowerShell CLI if path is blank (non-blank path == PowerShell script) 130 | # 1: Sysmon CLI 131 | if ((eventid=="4688")or(eventid=="1")or((eventid=="4104")and(path==""))): 132 | CheckCommand(time,log,eventid,cli) 133 | -------------------------------------------------------------------------------- /DeepBlueHash-checker.ps1: -------------------------------------------------------------------------------- 1 | # Requires VirusTotalAnalyzer: https://github.com/EvotecIT/VirusTotalAnalyzer 2 | # 3 | # Plus a (free) VirusTotal API Key: https://www.virustotal.com/en/documentation/public-api/ 4 | # 5 | Import-Module VirusTotalAnalyzer -Force 6 | 7 | # API KEY can be found once you register to Virus Total service (it's free) 8 | $VTApi = '' 9 | 10 | $hashdirectory = ".\hashes" 11 | $safelistfile=".\safelists\win10-x64.csv" 12 | # Load the safelist into a hash table 13 | if (Test-Path $safelistfile){ 14 | $safelist = Get-Content $safelistfile | Select-String '^[^#]' | ConvertFrom-Csv 15 | $hashes=@{} 16 | foreach($entry in $safelist){ 17 | $hashes[$entry.sha256]=$entry.path 18 | } 19 | } 20 | 21 | Get-ChildItem $hashdirectory | Foreach-Object{ 22 | if ($_.Name -Match '^[0-9A-F]{64}$'){ # SHA256 hashes are 64 character hex strings 23 | $SHA256=$_.Name 24 | if ($hashes.containsKey($SHA256)){ 25 | Rename-Item -Path "$hashdirectory\$SHA256" -NewName "$SHA256.safelisted" 26 | } 27 | Else{ 28 | try{ 29 | $VTreport = Get-VirusReport -ApiKey $VTApi -Hash "$SHA256" 30 | } 31 | catch { 32 | Write-Host "`r`nAttempted to run: Get-Virusreport $SHA256`r`r" 33 | Write-Host "Error: " $_.Exception.Message "`n" 34 | Write-Host "Have you installed VirusTotalAnalyzer and set the VirusTotal API key?" 35 | Write-Host " - See: https://github.com/darkoperator/Posh-VirusTotal`r`n" 36 | Write-Host "Exiting...`n" 37 | exit 38 | } 39 | $positives=$VTreport.Data.attributes.last_analysis_stats.malicious 40 | if ($positives -eq 0){ 41 | # File is clean 42 | Rename-Item -Path "$hashdirectory\$SHA256" -NewName "$SHA256.clean" 43 | } 44 | ElseIf ($positives -gt 0){ 45 | # File is flagged by Virustotal 46 | Write-Host " - Hash was detected by $positives Virustotal scanners" 47 | if ($positives -eq 1){ 48 | Write-Host " - Don't Panic (yet)! There is only one positive, which may be a sign of a false positive." 49 | Write-Host " - Check the VirusTotal report for more information." 50 | } 51 | Write-Host " - See $hashdirectory\$SHA256.Virustotal for the full report`r`n" 52 | $VTreport.Data.attributes | Set-Content "$hashdirectory\$SHA256.Virustotal" 53 | # Rename original hash file, add the Virustotal positive count as a numbered extension 54 | # $SHA256.$positives 55 | Rename-Item -Path "$hashdirectory\$SHA256" -NewName "$SHA256.$positives" 56 | } 57 | # Wait 15 seconds between submissions, for public Virustotal API keys 58 | Start-Sleep -s 15 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /DeepBlueHash-collector.ps1: -------------------------------------------------------------------------------- 1 | $hashdirectory=".\hashes\" 2 | $events = get-winevent @{logname="Microsoft-Windows-Sysmon/Operational";id=1,6,7,29} 3 | ForEach ($event in $events) { 4 | if ($event.id -eq 1){ # Process creation 5 | if ($event.Properties.Count -le 16){ 6 | $path=$event.Properties[3].Value # Full path of the file 7 | $hash=$event.Properties[11].Value # Hashes 8 | } 9 | ElseIf ($event.Properties.Count -le 17){ 10 | $path=$event.Properties[4].Value # Full path of the file 11 | $hash=$event.Properties[16].Value # Hashes 12 | } 13 | Else { 14 | $path=$event.Properties[4].Value # Full path of the file 15 | $hash=$event.Properties[17].Value # Hashes 16 | } 17 | } 18 | ElseIf ($event.id -eq 29){ # FileExecutableDetected 19 | $path=$event.Properties[6].Value # Full path of the file 20 | $hash=$event.Properties[7].Value # Hashes 21 | } 22 | Else{ 23 | # Hash and path are part of the message field in Sysmon events 6 and 7. Need to parse the XML 24 | $eventXML = [xml]$event.ToXml() 25 | If ($event.id -eq 6){ # Driver (.sys) load 26 | if ($event.Properties.Count -le 6){ 27 | $path=$eventXML.Event.EventData.Data[1]."#text" # Full path of the file 28 | $hash=$eventXML.Event.EventData.Data[2]."#text" # Hashes 29 | $hash 30 | } 31 | Else{ 32 | $path=$eventXML.Event.EventData.Data[2]."#text" # Full path of the file 33 | $hash=$eventXML.Event.EventData.Data[3]."#text" # Hashes 34 | } 35 | } 36 | ElseIf ($event.id -eq 7){ # Image (.dll) load 37 | if ($event.Properties.Count -lt 14){ 38 | $path=$eventXML.Event.EventData.Data[4]."#text" # Full path of the file 39 | $hash=$eventXML.Event.EventData.Data[5]."#text" # Hashes 40 | } 41 | Elseif ($event.Properties.Count -lt 15){ 42 | $path=$eventXML.Event.EventData.Data[5]."#text" # Full path of the file 43 | $hash=$eventXML.Event.EventData.Data[10]."#text" # Hashes 44 | } 45 | Else{ 46 | $path=$eventXML.Event.EventData.Data[5]."#text" # Full path of the file 47 | $hash=$eventXML.Event.EventData.Data[11]."#text" # Hashes 48 | } 49 | } 50 | Else{ 51 | Out-Host "Logic error 1, should not reach here..." 52 | Exit 1 53 | } 54 | } 55 | # Multiple hashes may be logged, we want SHA256. Remove everything through "SHA256=" 56 | $SHA256= $hash -Replace "^.*SHA256=","" 57 | # Split the string on commas, grab field 0 58 | $SHA256=$SHA256.Split(",")[0] 59 | if ($SHA256 -Match '^[0-9A-F]{64}$'){ # SHA256 hashes are 64 character hex strings 60 | $hashfile="$hashdirectory\$SHA256" 61 | if (-not (Test-Path "$hashfile*")){ 62 | # Hash file doesn't exist (or any variants with extensions), create it 63 | $path | Set-Content $hashfile 64 | } 65 | } 66 | Else{ 67 | Out-Host "No SHA256 hash found. Ensure Sysmon is creating SHA256 hashes" 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | {one line to give the program's name and a brief idea of what it does.} 635 | Copyright (C) {year} {name of author} 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | {project} Copyright (C) {year} {fullname} 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DeepBlueCLI 2 | 3 | DeepBlueCLI - a PowerShell Module for Threat Hunting via Windows Event Logs 4 | 5 | Eric Conrad, Backshore Communications, LLC 6 | 7 | deepblue `at` backshore `dot` net 8 | 9 | Twitter: [@eric_conrad](https://twitter.com/eric_conrad) 10 | 11 | http://ericconrad.com 12 | 13 | Sample EVTX files are in the .\evtx directory 14 | 15 | **Note** If your antivirus freaks out after downloading DeepBlueCLI: it's likely reacting to the included EVTX files in the .\evtx directory (which contain command-line logs of malicious attacks, among other artifacts). EVTX files are not harmful. You may need to configure your antivirus to ignore the DeepBlueCLI directory. 16 | 17 | ## Table of Contents 18 | - [Usage](#usage) 19 | - [Windows Event Logs processed](#windows-event-logs-processed) 20 | - [Detected events](#detected-events) 21 | - [Examples](#examples) 22 | - [Output](#output) 23 | - [Logging setup](#logging-setup) 24 | - See the [DeepBlue.py Readme](READMEs/README-DeepBlue.py.md) for information on DeepBlue.py 25 | - See the [DeepBlueHash Readme](READMEs/README-DeepBlueHash.md) for information on DeepBlueHash (detective safelisting using Sysmon event logs) 26 | 27 | ## Usage: 28 | 29 | `.\DeepBlue.ps1 ` 30 | 31 | See the [Set-ExecutionPolicy Readme](READMEs/Set-ExecutionPolicy.md) if you receive a 'running scripts is 32 | disabled on this system' error. 33 | 34 | ### Process local Windows security event log (PowerShell must be run as Administrator): 35 | 36 | `.\DeepBlue.ps1` 37 | 38 | or: 39 | 40 | `.\DeepBlue.ps1 -log security` 41 | 42 | ### Process local Windows system event log: 43 | 44 | `.\DeepBlue.ps1 -log system` 45 | 46 | ### Process evtx file: 47 | 48 | `.\DeepBlue.ps1 .\evtx\new-user-security.evtx` 49 | 50 | ## Windows Event Logs processed 51 | 52 | - Windows Security 53 | - Windows System 54 | - Windows Application 55 | - Windows PowerShell 56 | - Sysmon 57 | 58 | ### Command Line Logs processed 59 | 60 | See [Logging setup](#logging-setup) section below for how to configure these logs 61 | 62 | - Windows Security event ID 4688 63 | - Windows PowerShell event IDs 4103 and 4104 64 | - Sysmon event ID 1 65 | 66 | ## Detected events 67 | 68 | * Suspicious account behavior 69 | * User creation 70 | * User added to local/global/universal groups 71 | * Password guessing (multiple logon failures, one account) 72 | * Password spraying via failed logon (multiple logon failures, multiple accounts) 73 | * Password spraying via explicit credentials 74 | * Bloodhound (admin privileges assigned to the same account with multiple Security IDs) 75 | * Command line/Sysmon/PowerShell auditing 76 | * Long command lines 77 | * Regex searches 78 | * Obfuscated commands 79 | * PowerShell launched via WMIC or PsExec 80 | * PowerShell Net.WebClient Downloadstring 81 | * Compressed/Base64 encoded commands (with automatic decompression/decoding) 82 | * Unsigned EXEs or DLLs 83 | * Service auditing 84 | * Suspicious service creation 85 | * Service creation errors 86 | * Stopping/starting the Windows Event Log service (potential event log manipulation) 87 | * Mimikatz 88 | * `lsadump::sam` 89 | * EMET & Applocker Blocks 90 | 91 | 92 | ...and more 93 | 94 | ## Examples 95 | 96 | |Event|Command| 97 | |-----|-------| 98 | |Event log manipulation|`.\DeepBlue.ps1 .\evtx\disablestop-eventlog.evtx`| 99 | |Metasploit native target (security)|`.\DeepBlue.ps1 .\evtx\metasploit-psexec-native-target-security.evtx`| 100 | |Metasploit native target (system)|`.\DeepBlue.ps1 .\evtx\metasploit-psexec-native-target-system.evtx`| 101 | |Metasploit PowerShell target (security)|` .\DeepBlue.ps1 .\evtx\metasploit-psexec-powershell-target-security.evtx`| 102 | |Metasploit PowerShell target (system)|` .\DeepBlue.ps1 .\evtx\metasploit-psexec-powershell-target-system.evtx`| 103 | |Mimikatz `lsadump::sam`|`.\DeepBlue.ps1 .\evtx\mimikatz-privesc-hashdump.evtx`| 104 | |New user creation|`.\DeepBlue.ps1 .\evtx\new-user-security.evtx`| 105 | |Obfuscation (encoding)|`.\DeepBlue.ps1 .\evtx\Powershell-Invoke-Obfuscation-encoding-menu.evtx`| 106 | |Obfuscation (string)|`.\DeepBlue.ps1 .\evtx\Powershell-Invoke-Obfuscation-string-menu.evtx`| 107 | |Password guessing|`.\DeepBlue.ps1 .\evtx\smb-password-guessing-security.evtx`| 108 | |Password spraying|`.\DeepBlue.ps1 .\evtx\password-spray.evtx`| 109 | |PowerSploit (security)|`.\DeepBlue.ps1 .\evtx\powersploit-security.evtx`| 110 | |PowerSploit (system)|`.\DeepBlue.ps1 .\evtx\powersploit-system.evtx`| 111 | |PSAttack|`.\DeepBlue.ps1 .\evtx\psattack-security.evtx`| 112 | |User added to administrator group|`.\DeepBlue.ps1 .\evtx\new-user-security.evtx`| 113 | 114 | ## Output 115 | 116 | DeepBlueCLI outputs in PowerShell objects, allowing a variety of output methods and types, including JSON, HTML, CSV, etc. 117 | 118 | For example: 119 | 120 | |Output Type|Syntax| 121 | |-----------|------| 122 | |CSV|`.\DeepBlue.ps1 .\evtx\psattack-security.evtx \| ConvertTo-Csv`| 123 | |Format list (default)|`.\DeepBlue.ps1 .\evtx\psattack-security.evtx \| Format-List`| 124 | |Format table|`.\DeepBlue.ps1 .\evtx\psattack-security.evtx \| Format-Table`| 125 | |GridView|`.\DeepBlue.ps1 .\evtx\psattack-security.evtx \| Out-GridView`| 126 | |HTML|`.\DeepBlue.ps1 .\evtx\psattack-security.evtx \| ConvertTo-Html`| 127 | |JSON|`.\DeepBlue.ps1 .\evtx\psattack-security.evtx \| ConvertTo-Json`| 128 | |XML|`.\DeepBlue.ps1 .\evtx\psattack-security.evtx \| ConvertTo-Xml`| 129 | 130 | ## Logging setup 131 | 132 | ### Security event 4688 (Command line auditing): 133 | 134 | Enable Windows command-line auditing: https://support.microsoft.com/en-us/kb/3004375 135 | 136 | ### Security event 4625 (Failed logons): 137 | 138 | Requires auditing logon failures: https://technet.microsoft.com/en-us/library/cc976395.aspx 139 | ### PowerShell auditing (PowerShell 5.0): 140 | 141 | DeepBlueCLI uses module logging (PowerShell event 4103) and script block logging (4104). It does not use transcription. 142 | 143 | See: https://www.fireeye.com/blog/threat-research/2016/02/greater_visibilityt.html 144 | 145 | To get the PowerShell commandline (and not just script block) on Windows 7 through Windows 8.1, add the following to \Windows\System32\WindowsPowerShell\v1.0\profile.ps1 146 | ``` 147 | $LogCommandHealthEvent = $true 148 | $LogCommandLifecycleEvent = $true 149 | ``` 150 | See the following for more information: 151 | - https://logrhythm.com/blog/powershell-command-line-logging/ 152 | - http://hackerhurricane.blogspot.com/2014/11/i-powershell-logging-what-everyone.html 153 | 154 | Thank you: [@heinzarelli](https://twitter.com/heinzarelli) and [@HackerHurricane](https://twitter.com/hackerhurricane) 155 | 156 | ### Sysmon 157 | 158 | Install Sysmon from Sysinternals: https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon 159 | 160 | DeepBlue and DeepBlueHash currently use Sysmon events, 1, 6 and 7. 161 | 162 | Log SHA256 hashes. Others are fine; DeepBlueHash will use SHA256. 163 | 164 | -------------------------------------------------------------------------------- /READMEs/README-DeepBlue.py.md: -------------------------------------------------------------------------------- 1 | # DeepBlue.py 2 | 3 | DeepBlueCLI, ported to Python. Designed for parsing evtx files on Unix/Linux. 4 | 5 | Current version: alpha. It supports command line parsing for Security event log 4688, PowerShell log 4014, and Sysmon log 1. Will be porting more functionality from DeepBlueCLI after DerbyCon 7. 6 | 7 | ## libevtx 8 | 9 | Requires libevtx: https://github.com/libyal/libevtx 10 | 11 | ## Other evtx frameworks 12 | 13 | Note that I tested a few Unix/Linux/Python evtx frameworks. 14 | 15 | This is quite popular: https://github.com/williballenthin/python-evtx 16 | 17 | I ran into trouble with *some* .evtx files, where it would crash with this error: 18 | 19 | ``` 20 | UnicodeDecodeError: 'utf16' codec can't decode bytes in position 0-1: illegal UTF-16 surrogate 21 | ``` 22 | 23 | I found libevtx 'just worked', and had the added benefit of both Python and compiled options. 24 | -------------------------------------------------------------------------------- /READMEs/README-DeepBlueHash.md: -------------------------------------------------------------------------------- 1 | # DeepBlueHash 2 | 3 | Detective safelisting using Sysmon event logs. 4 | 5 | Parses the Sysmon event logs, grabbing the SHA256 hashes from process creation (event 1), driver load (event 6, sys), and image load (event 7, DLL) events. 6 | 7 | ## VirusTotal and Safelisting setup 8 | 9 | **Note**: Virustotal has changed their free API for some users. My old account has this limitation: 10 | 11 | - Daily quota 1 lookups / day 12 | - Monthly quota 31 lookups / month 13 | 14 | New accounts get this: 15 | 16 | - Request rate 4 lookups / min 17 | - Daily quota 500 lookups / day 18 | - Monthly quota 15.5 K lookups / month 19 | 20 | Not sure why that is, so FYI. 21 | 22 | Setting up VirusTotal hash submissions and safelisting: 23 | 24 | The hash checker requires VirusTotalAnalyzer: https://github.com/EvotecIT/VirusTotalAnalyzer 25 | 26 | It also requires a VirusTotal API key: 27 | 28 | - https://www.virustotal.com/en/documentation/public-api/ 29 | 30 | The script assumes a personal API key, and waits 15 seconds between submissions. 31 | 32 | ## Sysmon setup 33 | 34 | Sysmon is required: https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon 35 | 36 | Must log the SHA256 hash, DeepBlueHash will ignore the others. 37 | 38 | This minimal Sysmon 6.0 config will log the proper events/hashes. Note that image (DLL) logging may create performance issues. This config ignores DLLs signed by Microsoft (which should lighten the load), but please test! 39 | 40 | ```xml 41 | 42 | 43 | SHA256 44 | 45 | 46 | 47 | microsoft 48 | windows 49 | 50 | 51 | 52 | 53 | microsoft 54 | windows 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | ``` 63 | These are the events used by DeepBlueCLI and DeepBlueHash. 64 | 65 | You can go *much* further than this with Sysmon. The Sysinternals Sysmon page has a good basic configuration: https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon 66 | 67 | Also see @swiftonsecurity's awesome Sysmon config here: https://github.com/SwiftOnSecurity/sysmon-config 68 | 69 | ## Generating a Safelist 70 | 71 | Generate a custom safelist on Windows (note: this is optional): 72 | 73 | ``` 74 | PS C:\> Get-ChildItem c:\windows\system32 -Include '*.exe','*.dll','*.sys','*.com' -Recurse | Get-FileHash| Export-Csv -Path safelist.csv 75 | ``` 76 | Note: this will generate (harmless) 'PermissionDenied' warnings for locked files, etc. They may be ignored. 77 | -------------------------------------------------------------------------------- /READMEs/Set-ExecutionPolicy.md: -------------------------------------------------------------------------------- 1 | ## Set-ExecutionPolicy 2 | 3 | If you see this error: `.\DeepBlue.ps1 : File .\DeepBlue.ps1 cannot be loaded because running scripts is 4 | disabled on this system. For more information, see about_Execution_Policies at 5 | http://go.microsoft.com/fwlink/?LinkID=135170.` 6 | 7 | You must run Set-ExecutionPolicy as Administrator, here is an example (this will warn every time you run a ps1 script): 8 | 9 | `Set-ExecutionPolicy RemoteSigned` 10 | 11 | This command will bypass Set-Execution entirely: `Set-ExecutionPolicy Bypass` 12 | 13 | See `get-help Set-ExecutionPolicy` for more options. 14 | 15 | Please note that "Set-ExecutionPolicy is not a security control" (quoting [@Ben0xA](https://twitter.com/ben0xa)) 16 | -------------------------------------------------------------------------------- /READMEs/test.md: -------------------------------------------------------------------------------- 1 | test 2 | -------------------------------------------------------------------------------- /evtx/Powershell-Invoke-Obfuscation-encoding-menu.evtx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sans-blue-team/DeepBlueCLI/2eecc65698e8666408ece67525577c895676d579/evtx/Powershell-Invoke-Obfuscation-encoding-menu.evtx -------------------------------------------------------------------------------- /evtx/Powershell-Invoke-Obfuscation-many.evtx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sans-blue-team/DeepBlueCLI/2eecc65698e8666408ece67525577c895676d579/evtx/Powershell-Invoke-Obfuscation-many.evtx -------------------------------------------------------------------------------- /evtx/Powershell-Invoke-Obfuscation-string-menu.evtx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sans-blue-team/DeepBlueCLI/2eecc65698e8666408ece67525577c895676d579/evtx/Powershell-Invoke-Obfuscation-string-menu.evtx -------------------------------------------------------------------------------- /evtx/disablestop-eventlog.evtx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sans-blue-team/DeepBlueCLI/2eecc65698e8666408ece67525577c895676d579/evtx/disablestop-eventlog.evtx -------------------------------------------------------------------------------- /evtx/eventlog-dac.evtx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sans-blue-team/DeepBlueCLI/2eecc65698e8666408ece67525577c895676d579/evtx/eventlog-dac.evtx -------------------------------------------------------------------------------- /evtx/many-events-application.evtx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sans-blue-team/DeepBlueCLI/2eecc65698e8666408ece67525577c895676d579/evtx/many-events-application.evtx -------------------------------------------------------------------------------- /evtx/many-events-security.evtx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sans-blue-team/DeepBlueCLI/2eecc65698e8666408ece67525577c895676d579/evtx/many-events-security.evtx -------------------------------------------------------------------------------- /evtx/many-events-system.evtx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sans-blue-team/DeepBlueCLI/2eecc65698e8666408ece67525577c895676d579/evtx/many-events-system.evtx -------------------------------------------------------------------------------- /evtx/metasploit-psexec-native-target-security.evtx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sans-blue-team/DeepBlueCLI/2eecc65698e8666408ece67525577c895676d579/evtx/metasploit-psexec-native-target-security.evtx -------------------------------------------------------------------------------- /evtx/metasploit-psexec-native-target-system.evtx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sans-blue-team/DeepBlueCLI/2eecc65698e8666408ece67525577c895676d579/evtx/metasploit-psexec-native-target-system.evtx -------------------------------------------------------------------------------- /evtx/metasploit-psexec-powershell-target-security.evtx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sans-blue-team/DeepBlueCLI/2eecc65698e8666408ece67525577c895676d579/evtx/metasploit-psexec-powershell-target-security.evtx -------------------------------------------------------------------------------- /evtx/metasploit-psexec-powershell-target-system.evtx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sans-blue-team/DeepBlueCLI/2eecc65698e8666408ece67525577c895676d579/evtx/metasploit-psexec-powershell-target-system.evtx -------------------------------------------------------------------------------- /evtx/metasploit-psexec-pwshpayload.evtx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sans-blue-team/DeepBlueCLI/2eecc65698e8666408ece67525577c895676d579/evtx/metasploit-psexec-pwshpayload.evtx -------------------------------------------------------------------------------- /evtx/metasploit-sysmon.evtx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sans-blue-team/DeepBlueCLI/2eecc65698e8666408ece67525577c895676d579/evtx/metasploit-sysmon.evtx -------------------------------------------------------------------------------- /evtx/mimikatz-privesc-hashdump.evtx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sans-blue-team/DeepBlueCLI/2eecc65698e8666408ece67525577c895676d579/evtx/mimikatz-privesc-hashdump.evtx -------------------------------------------------------------------------------- /evtx/mimikatz-privilegedebug-tokenelevate-hashdump.evtx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sans-blue-team/DeepBlueCLI/2eecc65698e8666408ece67525577c895676d579/evtx/mimikatz-privilegedebug-tokenelevate-hashdump.evtx -------------------------------------------------------------------------------- /evtx/new-user-security.evtx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sans-blue-team/DeepBlueCLI/2eecc65698e8666408ece67525577c895676d579/evtx/new-user-security.evtx -------------------------------------------------------------------------------- /evtx/password-spray.evtx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sans-blue-team/DeepBlueCLI/2eecc65698e8666408ece67525577c895676d579/evtx/password-spray.evtx -------------------------------------------------------------------------------- /evtx/powersploit-security.evtx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sans-blue-team/DeepBlueCLI/2eecc65698e8666408ece67525577c895676d579/evtx/powersploit-security.evtx -------------------------------------------------------------------------------- /evtx/powersploit-system.evtx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sans-blue-team/DeepBlueCLI/2eecc65698e8666408ece67525577c895676d579/evtx/powersploit-system.evtx -------------------------------------------------------------------------------- /evtx/psattack-security.evtx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sans-blue-team/DeepBlueCLI/2eecc65698e8666408ece67525577c895676d579/evtx/psattack-security.evtx -------------------------------------------------------------------------------- /evtx/sliver-security.evtx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sans-blue-team/DeepBlueCLI/2eecc65698e8666408ece67525577c895676d579/evtx/sliver-security.evtx -------------------------------------------------------------------------------- /evtx/sliver-sysmon.evtx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sans-blue-team/DeepBlueCLI/2eecc65698e8666408ece67525577c895676d579/evtx/sliver-sysmon.evtx -------------------------------------------------------------------------------- /evtx/smb-password-guessing-security.evtx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sans-blue-team/DeepBlueCLI/2eecc65698e8666408ece67525577c895676d579/evtx/smb-password-guessing-security.evtx -------------------------------------------------------------------------------- /evtx/wmi-event-filter-persistance.evtx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sans-blue-team/DeepBlueCLI/2eecc65698e8666408ece67525577c895676d579/evtx/wmi-event-filter-persistance.evtx -------------------------------------------------------------------------------- /hashes/readme.md: -------------------------------------------------------------------------------- 1 | Placeholder for upcoming Virustotal submission script via Sysmon logs/hashes. 2 | -------------------------------------------------------------------------------- /regexes.txt: -------------------------------------------------------------------------------- 1 | # DeepBlueCLI command regex CSV file 2 | # Include only regex CSV entries or comments beginning with "#" 3 | # 4 | # Format: Match type, regex, output string 5 | # Match types: 6 | # 0: Image Path - regex 7 | # 1: Service Name - regex 8 | # 9 | Type,regex,string 10 | 0,^cmd.exe /c echo [a-z]{6} > \\\\.\\pipe\\[a-z]{6}$,Metasploit-style cmd with pipe (possible use of Meterpreter 'getsystem') 11 | 0,^%SYSTEMROOT%\\[a-zA-Z]{8}\.exe$,Metasploit-style %SYSTEMROOT% image path (possible use of Metasploit 'Native upload' exploit payload) 12 | 0,powershell.*FromBase64String.*IO.Compression.GzipStream,Metasploit-style base64 encoded/compressed PowerShell function (possible use of Metasploit PowerShell exploit payload) 13 | 0,DownloadString\(.http,Download via Net.WebClient DownloadString 14 | 0,mimikatz,Command referencing Mimikatz 15 | 0,Invoke-Mimikatz.ps,PowerSploit Invoke-Mimikatz.ps1 16 | 0,PowerSploit.*ps1,Use of PowerSploit 17 | 0,User-Agent,User-Agent set via command line 18 | 0,[a-zA-Z0-9/+=]{500},500+ consecutive Base64 characters 19 | 0,powershell.exe.*Hidden.*Enc,Base64 encoded and hidden PowerShell command 20 | # Generic csc.exe alert, comment out if experiencing false positives 21 | 0,\\csc\.exe,Use of C Sharp compiler csc.exe 22 | 0,\\csc\.exe.*\\Appdata\\Local\\Temp\\[a-z0-9]{8}\.cmdline,PSAttack-style command via csc.exe 23 | # Generic cvtres.exe alert, comment out if experiencing false positives 24 | 0,\\cvtres\.exe.*,Resource File To COFF Object Conversion Utility cvtres.exe 25 | 0,\\cvtres\.exe.*\\AppData\\Local\\Temp\\[A-Z0-9]{7}\.tmp,PSAttack-style command via cvtres.exe 26 | 0,Register-ScheduledTask,Command referencing Register-ScheduledTask (possible ASEP) 27 | 0,Software\\Microsoft\\Windows\\CurrentVersion\\Run,Reference to registry run key (possible ASEP) 28 | 0,reg *add,Registry addition (possible ASEP) 29 | 0,cmd.exe.*\\ADMIN\$\\,cmd.exe accessing the ADMIN$ share 30 | 1,^[a-zA-Z]{22}$,Metasploit-style service name: 22 characters, [A-Za-z] 31 | 1,^[a-zA-Z]{16}$,Metasploit-style service name: 16 characters, [A-Za-z] 32 | -------------------------------------------------------------------------------- /safelist.txt: -------------------------------------------------------------------------------- 1 | # DeepBlueCLI command ignore list 2 | # Currently: one entry (regex) per line 3 | # Read as a CSV file for future growth (may want to add options to each entry) 4 | # 5 | # Include only regex CSV entries, or comments beginning with "#" 6 | # 7 | regex 8 | ^"C:\\Program Files\\Google\\Chrome\\Application\\chrome\.exe" 9 | ^"C:\\Program Files\\Google\\Update\\GoogleUpdate\.exe" 10 | ^"C:\\Program Files \(x86\)\\Google\\Update\\GoogleUpdate\.exe" 11 | "\\AppData\\Local\\Microsoft\\EdgeUpdate\\MicrosoftEdgeUpdate\.exe" 12 | -------------------------------------------------------------------------------- /safelists/readme.md: -------------------------------------------------------------------------------- 1 | Placeholder for safelists directory 2 | -------------------------------------------------------------------------------- /t/runall.ps1: -------------------------------------------------------------------------------- 1 | Write-Host "Running DeepBlue.ps1 on all EVTX files to identify any syntax errors." 2 | cd .. ; gci -path . -recurse -name "*.evtx" | % {.\DeepBlue.ps1 -File $_ | Out-Null } 3 | --------------------------------------------------------------------------------