Compare commits

..

38 Commits

Author SHA1 Message Date
2eecc65698 New Sliver and Metasploit EVTX files including cmd.exe writing to ADMIN$, and suspicious remote threads 2023-06-28 16:33:55 -04:00
8e510aaaef Update safelist.txt 2023-06-28 16:21:07 -04:00
50d2ca9ef9 Added Sysmon event 8 (Suspicious remote thread) 2023-06-28 16:20:32 -04:00
ac1a9991fd Added event 29, updated for new Sysmon schema 2023-06-28 14:21:01 -04:00
9e5979fca2 Update DeepBlueHash-checker.ps1 2023-06-28 13:30:16 -04:00
e9fc13a57b Update README-DeepBlueHash.md 2023-06-28 13:29:22 -04:00
7fb41280a2 Updated for Virustotal Key v3 2023-06-28 13:27:39 -04:00
41fe88f2e4 Update DeepBlueHash-collector.ps1
Updated for new Sysmon schema
2023-06-28 13:23:46 -04:00
3c8fa15e28 Update DeepBlueHash-checker.ps1
Updated for Virustotal API key v3
2023-06-28 13:23:02 -04:00
cd3e304f27 Update README-DeepBlueHash.md 2023-06-27 17:18:20 -04:00
a99c412a73 Update README-DeepBlueHash.md 2023-06-27 14:37:24 -04:00
1699dfc5cf Update README-DeepBlueHash.md 2023-06-27 14:37:10 -04:00
fc670716d6 Rename DeepWhite-collector.ps1 to DeepBlueHash-collector.ps1 2023-06-07 16:54:54 -04:00
ecbc203684 Rename DeepWhite-checker.ps1 to DeepBlueHash-checker.ps1 2023-06-07 16:54:36 -04:00
229010219a More updates, including more WMI detection 2023-06-07 16:47:34 -04:00
79dd0e6b11 Minor fix 2023-06-07 16:34:15 -04:00
f35415586d Updated for Sysmon schema 8 2023-06-07 16:17:34 -04:00
ce3c408efa Minor version update 2023-06-07 16:06:15 -04:00
e07e5aa1de Rename DeepBlueHash-checker.ps1 to DeepWhite-checker.ps1
Temp change to merge old pull request
2023-06-07 15:05:03 -04:00
9369182b49 Rename DeepBlueHash-collector.ps1 to DeepWhite-collector.ps1
Temp change to merge old pull request
2023-06-07 14:14:06 -04:00
9e51dd0579 Merge pull request #25 from netscylla/wmi-events
Wmi events
2023-06-07 13:41:55 -04:00
2fc4fd599f Merge pull request #27 from TheNiv/patch-1
Fixed windows event log check.
2023-06-07 13:36:07 -04:00
120448c50e s/White/BlueHash/g 2022-02-13 10:47:58 -05:00
115b4f30b2 Merge pull request #29 from sans-blue-team/Conrad-test
s/DeepWhite/DeepBlueHash
2022-01-05 13:51:00 -05:00
eebd75d029 Merge pull request #28 from n3tl0kr/patch-1
Small typographical error in output
2021-11-11 11:11:18 -05:00
f5b844cb1a Small typographical error in output 2021-11-11 11:10:04 -05:00
ea97820b79 Fixed windows event log check.
The output of the start/stop windows event log service was not correct. 
After checking the script on the sample file: disablestop-eventlog.evtx I have noticed that the output was not correct and found out it is actually the third parameter that should be checked instead of the second.
2021-11-06 10:11:03 +02:00
cf9411f721 Added another base64 encoding method 2021-10-29 16:37:26 -04:00
e3bf84fe51 Added some ASEPs 2021-10-29 16:25:45 -04:00
45d62cbfbe Was analyzing Sysmon event 1 image instead of CommandLine. Fixed 2021-10-29 16:17:25 -04:00
350fe3c134 Added # of unique accounts sprayed 2021-10-28 15:15:27 -04:00
d7d8d5eb80 s/Passworg/Password/g 2021-10-28 14:57:37 -04:00
5f2a62cd9c s/DeepBlueCLI/DeepWhite/g 2021-10-28 12:22:13 -04:00
46fe6b42c5 s/antivrus/antivirus/g 2021-10-28 12:20:45 -04:00
2ae82a296f Added AV caveat 2021-10-28 12:17:05 -04:00
8b15218ae3 Merge pull request #26 from sans-blue-team/Conrad-test
Inclusive language update
2021-10-28 09:07:53 -07:00
0c7338dd38 Update DeepBlue.ps1
fixed indentation
2021-09-16 13:57:35 +01:00
ddb9e3e0fa Added code to support flagging suspicious wmi filter events, also added sample log file 2021-09-16 13:55:34 +01:00
11 changed files with 170 additions and 48 deletions

View File

@ -25,7 +25,7 @@ https://github.com/sans-blue-team/DeepBlueCLI
#>
# DeepBlueCLI 2.01
# DeepBlueCLI 3.0
# Eric Conrad, Backshore Communications, LLC
# deepblue <at> backshore <dot> net
# Twitter: @eric_conrad
@ -45,7 +45,7 @@ function Main {
$logname=Check-Options $file $log
#"Processing the " + $logname + " log..."
$filter=Create-Filter $file $logname
# Passworg guessing/spraying variables:
# Password guessing/spraying variables:
$maxfailedlogons=5 # Alert after this many failed logons
$failedlogons=@{} # HashTable of failed logons per user
$totalfailedlogons=0 # Total number of failed logons (for all accounts)
@ -66,6 +66,7 @@ function Main {
$passspraytrack = @{}
$passsprayuniqusermax = 6
$passsprayloginmax = 6
$passsprayuniqaccounts = 0
# Sysmon variables:
# Check for unsigned EXEs/DLLs. This can be very chatty, so it's disabled.
# Set $checkunsigned to 1 to enable:
@ -224,7 +225,7 @@ function Main {
$totalsensprivuse+=1
# use -eq here to avoid multiple log notices
if ($totalsensprivuse -eq $maxtotalsensprivuse) {
$obj.Message = "Sensititive Privilege Use Exceeds Threshold"
$obj.Message = "Sensitive Privilege Use Exceeds Threshold"
$obj.Results = "Potentially indicative of Mimikatz, multiple sensitive privilege calls have been made.`n"
$username=$eventXML.Event.EventData.Data[1]."#text"
@ -311,11 +312,13 @@ function Main {
foreach($key in $passspraytrack.keys) {
$usernames += $key
$usernames += " "
$passsprayuniqaccounts += 1
}
$obj.Message = "Distributed Account Explicit Credential Use (Password Spray Attack)"
$obj.Results = "The use of multiple user account access attempts with explicit credentials is "
$obj.Results += "an indicator of a password spray attack.`n"
$obj.Results += "Target Usernames: $usernames`n"
$obj.results += "Unique accounts sprayed: $passsprayuniqaccounts`n"
$obj.Results += "Accessing Username: $username`n"
$obj.Results += "Accessing Host Name: $hostname`n"
Write-Output $obj
@ -388,7 +391,7 @@ function Main {
ElseIf ($event.id -eq 7040){
# The start type of the Windows Event Log service was changed from auto start to disabled.
$servicename=$eventXML.Event.EventData.Data[0]."#text"
$action = $eventXML.Event.EventData.Data[1]."#text"
$action = $eventXML.Event.EventData.Data[2]."#text"
if ($servicename -ccontains "Windows Event Log") {
$obj.Results = "Service name: $servicename`n"
$obj.Results += $text
@ -514,8 +517,14 @@ function Main {
ElseIf ($logname -eq "Sysmon"){
# Check command lines
if ($event.id -eq 1){
$creator=$eventXML.Event.EventData.Data[14]."#text"
$commandline=$eventXML.Event.EventData.Data[4]."#text"
if ($eventXML.Event.EventData.Data.Count -le 16){
$creator=$eventXML.Event.EventData.Data[14]."#text"
$commandline=$eventXML.Event.EventData.Data[10]."#text"
}
Else {
$creator=$eventXML.Event.EventData.Data[20]."#text"
$commandline=$eventXML.Event.EventData.Data[10]."#text"
}
if ($commandline){
Check-Command -EventID 1
}
@ -525,17 +534,66 @@ function Main {
# This can be very chatty, so it's disabled.
# Set $checkunsigned to 1 (global variable section) to enable:
if ($checkunsigned){
if ($eventXML.Event.EventData.Data[6]."#text" -eq "false"){
$obj.Message="Unsigned Image (DLL)"
$image=$eventXML.Event.EventData.Data[3]."#text"
$imageload=$eventXML.Event.EventData.Data[4]."#text"
# $hash=$eventXML.Event.EventData.Data[5]."#text"
$obj.Command=$imageload
$obj.Results= "Loaded by: $image"
Write-Output $obj
}
if ($event.Properties.Count -lt 14){
if ($eventXML.Event.EventData.Data[6]."#text" -eq "false"){
$obj.Message="Unsigned Image (DLL)"
$image=$eventXML.Event.EventData.Data[3]."#text"
$imageload=$eventXML.Event.EventData.Data[4]."#text"
# $hash=$eventXML.Event.EventData.Data[5]."#text"
$obj.Command=$imageload
$obj.Results= "Loaded by: $image"
Write-Output $obj
}
}
Else{
if ($eventXML.Event.EventData.Data[11]."#text" -eq "false"){
$obj.Message="Unsigned Image (DLL)"
$image=$eventXML.Event.EventData.Data[4]."#text"
$imageload=$eventXML.Event.EventData.Data[5]."#text"
# $hash=$eventXML.Event.EventData.Data[10]."#text"
$obj.Command=$imageload
$obj.Results= "Loaded by: $image"
Write-Output $obj
}
}
}
}
ElseIf ($event.id -eq 8){
#Check remote thread (lsass activity, process migration, etc)
$image=$eventXML.Event.EventData.Data[7]."#text"
$user=$eventXML.Event.EventData.Data[12]."#text"
$sourceimage=$eventXML.Event.EventData.Data[4]."#text"
If ($image -Match "lsass.exe"){
$creatortext += "Remote thread to $image`n"
$obj.Message="Suspicious remote thread"
$imageload=$eventXML.Event.EventData.Data[7]."#text"
$obj.Command=$imageload
$obj.Results= "Remote thread created to: $image from: $sourceimage by $user"
Write-Output $obj
}
ElseIf ($user -notmatch "SYSTEM"){
$creatortext += "Remote thread to $image`n"
$obj.Message="Suspicious remote thread"
$imageload=$eventXML.Event.EventData.Data[7]."#text"
$obj.Command=$imageload
$obj.Results= "Remote thread created to: $image from: $sourceimage by $user"
Write-Output $obj
}
}
}
ElseIf ($logname -eq "WMI-Activity"){
# Check commandlines for suspicious commands
if ($event.id -eq 5861){
if($event.Message -match ".*CommandLineTemplate\s=\s(.*?);"){
$command = $event.message
$obj.Message = "Suspicous WMI Event Filter"
$obj.Results += "Event Triggered Execution: WMI - T1546.003`n"
$obj.Results += $event.message
$obj.Command=$matches[0].Split("=")[1]
Write-Output $obj
}
}
}
}
# Iterate through admin logons hashtable (key is $username)
@ -618,6 +676,7 @@ function Check-Options($file, $log)
"Microsoft-Windows-AppLocker/EXE and DLL" {$logname="Applocker"}
"Microsoft-Windows-PowerShell/Operational" {$logname="Powershell"}
"Microsoft-Windows-Sysmon/Operational" {$logname="Sysmon"}
"Microsoft-Windows-WMI-Activity/Operational" {$logname="WMI-Activity"}
default {"Logic error 3, should not reach here...";Exit 1}
}
}
@ -638,7 +697,8 @@ function Create-Filter($file, $logname)
$app_events="2"
$applocker_events="8003,8004,8006,8007"
$powershell_events="4103,4104"
$sysmon_events="1,7"
$sysmon_events="1,7,8"
$wmi_events="5861"
if ($file -ne ""){
switch ($logname){
"Security" {$filter="@{path=""$file"";ID=$sec_events}"}
@ -647,6 +707,7 @@ function Create-Filter($file, $logname)
"Applocker" {$filter="@{path=""$file"";ID=$applocker_events}"}
"Powershell" {$filter="@{path=""$file"";ID=$powershell_events}"}
"Sysmon" {$filter="@{path=""$file"";ID=$sysmon_events}"}
"WMI-Activity"{$filter="@{path=""$file"";ID=$wmi_events}"}
default {"Logic error 1, should not reach here...";Exit 1}
}
}
@ -658,6 +719,7 @@ function Create-Filter($file, $logname)
"Applocker" {$filter="@{logname=""Microsoft-Windows-AppLocker/EXE and DLL"";ID=$applocker_events}"}
"Powershell" {$filter="@{logname=""Microsoft-Windows-PowerShell/Operational"";ID=$powershell_events}"}
"Sysmon" {$filter="@{logname=""Microsoft-Windows-Sysmon/Operational"";ID=$sysmon_events}"}
"WMI-Activity"{$filter="@{logname=""Microsoft-Windows-WMI-Activity/Operational"";ID=$wmi_events}"}
default {"Logic error 2, should not reach here...";Exit 1}
}
}
@ -689,6 +751,9 @@ function Check-Command(){
if ($commandline -Match "\-enc.*[A-Za-z0-9/+=]{100}"){
$base64= $commandline -Replace "^.* \-Enc(odedCommand)? ",""
}
ElseIf ($commandline -Match "\-En.*[A-Za-z0-9/+=]{100}"){
$base64= $commandline -Replace "^.* \-En",""
}
ElseIf ($commandline -Match ":FromBase64String\("){
$base64 = $commandline -Replace "^.*:FromBase64String\(\'*",""
$base64 = $base64 -Replace "\'.*$",""
@ -782,6 +847,14 @@ function Check-Creator($command,$creator){
$creatortext += "PowerShell launched via WMI: $creator`n"
}
}
ElseIf ($command -Match "cmd.exe"){
if ($creator -Match "PSEXESVC"){
$creatortext += "cmd.exe launched via PsExec: $creator`n"
}
ElseIf($creator -Match "WmiPrvSE"){
$creatortext += "cmd.exe launched via WMI: $creator`n"
}
}
}
return $creatortext
}

View File

@ -1,9 +1,14 @@
# Requires Posh-VirusTotal: https://github.com/darkoperator/Posh-VirusTotal
# Requires VirusTotalAnalyzer: https://github.com/EvotecIT/VirusTotalAnalyzer
#
# Plus a (free) VirusTotal API Key: https://www.virustotal.com/en/documentation/public-api/
#
Import-Module VirusTotalAnalyzer -Force
# API KEY can be found once you register to Virus Total service (it's free)
$VTApi = '<Your API Key>'
$hashdirectory = ".\hashes"
$safelistfile=".\file-safelist.csv"
$safelistfile=".\safelists\win10-x64.csv"
# Load the safelist into a hash table
if (Test-Path $safelistfile){
$safelist = Get-Content $safelistfile | Select-String '^[^#]' | ConvertFrom-Csv
@ -21,32 +26,30 @@ Get-ChildItem $hashdirectory | Foreach-Object{
}
Else{
try{
$VTreport = Get-VTFileReport $SHA256
$VTreport = Get-VirusReport -ApiKey $VTApi -Hash "$SHA256"
}
catch {
Write-Host "`r`nAttempted to run: Get-VTFileReport $SHA256`r`r"
Write-Host "`r`nAttempted to run: Get-Virusreport $SHA256`r`r"
Write-Host "Error: " $_.Exception.Message "`n"
Write-Host "Have you installed Posh-VirusTotal and set the VirusTotal API key?"
Write-Host "Have you installed VirusTotalAnalyzer and set the VirusTotal API key?"
Write-Host " - See: https://github.com/darkoperator/Posh-VirusTotal`r`n"
Write-Host "Once you have installed Posh-VirusTotal and have a VirusTotal API key, run the following command:`r`n"
Write-Host "Set-VTAPIKey -APIKey <API Key>`r`n"
Write-Host "Exiting...`n"
exit
}
if ($VTreport.positives -eq 0){
$positives=$VTreport.Data.attributes.last_analysis_stats.malicious
if ($positives -eq 0){
# File is clean
Rename-Item -Path "$hashdirectory\$SHA256" -NewName "$SHA256.clean"
}
ElseIf ($VTreport.positives -gt 0){
ElseIf ($positives -gt 0){
# File is flagged by Virustotal
$positives=$VTreport.positives
Write-Host " - Hash was detected by $positives Virustotal scanners"
if ($positives -eq 1){
Write-Host " - Don't Panic (yet)! There is only one positive, which may be a sign of a false positive."
Write-Host " - Check the VirusTotal report for more information."
}
Write-Host " - See $hashdirectory\$SHA256.Virustotal for the full report`r`n"
$VTreport | Set-Content "$hashdirectory\$SHA256.Virustotal"
$VTreport.Data.attributes | Set-Content "$hashdirectory\$SHA256.Virustotal"
# Rename original hash file, add the Virustotal positive count as a numbered extension
# $SHA256.$positives
Rename-Item -Path "$hashdirectory\$SHA256" -NewName "$SHA256.$positives"

View File

@ -1,20 +1,51 @@
$hashdirectory=".\hashes\"
$events = get-winevent @{logname="Microsoft-Windows-Sysmon/Operational";id=1,6,7}
$hashdirectory=".\hashes\"
$events = get-winevent @{logname="Microsoft-Windows-Sysmon/Operational";id=1,6,7,29}
ForEach ($event in $events) {
if ($event.id -eq 1){ # Process creation
$path=$event.Properties[3].Value # Full path of the file
$hash=$event.Properties[11].Value # Hashes
if ($event.Properties.Count -le 16){
$path=$event.Properties[3].Value # Full path of the file
$hash=$event.Properties[11].Value # Hashes
}
ElseIf ($event.Properties.Count -le 17){
$path=$event.Properties[4].Value # Full path of the file
$hash=$event.Properties[16].Value # Hashes
}
Else {
$path=$event.Properties[4].Value # Full path of the file
$hash=$event.Properties[17].Value # Hashes
}
}
ElseIf ($event.id -eq 29){ # FileExecutableDetected
$path=$event.Properties[6].Value # Full path of the file
$hash=$event.Properties[7].Value # Hashes
}
Else{
# Hash and path are part of the message field in Sysmon events 6 and 7. Need to parse the XML
$eventXML = [xml]$event.ToXml()
If ($event.id -eq 6){ # Driver (.sys) load
$path=$eventxml.Event.EventData.Data[1]."#text" # Full path of the file
$hash=$eventXML.Event.EventData.Data[2]."#text" # Hashes
if ($event.Properties.Count -le 6){
$path=$eventXML.Event.EventData.Data[1]."#text" # Full path of the file
$hash=$eventXML.Event.EventData.Data[2]."#text" # Hashes
$hash
}
Else{
$path=$eventXML.Event.EventData.Data[2]."#text" # Full path of the file
$hash=$eventXML.Event.EventData.Data[3]."#text" # Hashes
}
}
ElseIf ($event.id -eq 7){ # Image (.dll) load
$path=$eventxml.Event.EventData.Data[4]."#text" # Full path of the file
$hash=$eventXML.Event.EventData.Data[5]."#text" # Hashes
if ($event.Properties.Count -lt 14){
$path=$eventXML.Event.EventData.Data[4]."#text" # Full path of the file
$hash=$eventXML.Event.EventData.Data[5]."#text" # Hashes
}
Elseif ($event.Properties.Count -lt 15){
$path=$eventXML.Event.EventData.Data[5]."#text" # Full path of the file
$hash=$eventXML.Event.EventData.Data[10]."#text" # Hashes
}
Else{
$path=$eventXML.Event.EventData.Data[5]."#text" # Full path of the file
$hash=$eventXML.Event.EventData.Data[11]."#text" # Hashes
}
}
Else{
Out-Host "Logic error 1, should not reach here..."

View File

@ -10,7 +10,9 @@ Twitter: [@eric_conrad](https://twitter.com/eric_conrad)
http://ericconrad.com
Sample evtx files are in the .\evtx directory
Sample EVTX files are in the .\evtx directory
**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.
## Table of Contents
- [Usage](#usage)
@ -157,5 +159,5 @@ Install Sysmon from Sysinternals: https://docs.microsoft.com/en-us/sysinternals/
DeepBlue and DeepBlueHash currently use Sysmon events, 1, 6 and 7.
Log SHA256 hashes. Others are fine; DeepBlueCLI will use SHA256.
Log SHA256 hashes. Others are fine; DeepBlueHash will use SHA256.

View File

@ -6,20 +6,27 @@ Parses the Sysmon event logs, grabbing the SHA256 hashes from process creation (
## VirusTotal and Safelisting setup
**Note**: Virustotal has changed their free API for some users. My old account has this limitation:
- Daily quota 1 lookups / day
- Monthly quota 31 lookups / month
New accounts get this:
- Request rate 4 lookups / min
- Daily quota 500 lookups / day
- Monthly quota 15.5 K lookups / month
Not sure why that is, so FYI.
Setting up VirusTotal hash submissions and safelisting:
The hash checker requires Post-VirusTotal:
- https://github.com/darkoperator/Posh-VirusTotal
The hash checker requires VirusTotalAnalyzer: https://github.com/EvotecIT/VirusTotalAnalyzer
It also requires a VirusTotal API key:
- https://www.virustotal.com/en/documentation/public-api/
Then configure your VirusTotal API key:
```powershell
set-VTAPIKey -APIKey <API Key>
```
The script assumes a personal API key, and waits 15 seconds between submissions.
## Sysmon setup

BIN
evtx/metasploit-sysmon.evtx Normal file

Binary file not shown.

BIN
evtx/sliver-security.evtx Normal file

Binary file not shown.

BIN
evtx/sliver-sysmon.evtx Normal file

Binary file not shown.

Binary file not shown.

4
regexes.txt Normal file → Executable file
View File

@ -23,5 +23,9 @@ Type,regex,string
# Generic cvtres.exe alert, comment out if experiencing false positives
0,\\cvtres\.exe.*,Resource File To COFF Object Conversion Utility cvtres.exe
0,\\cvtres\.exe.*\\AppData\\Local\\Temp\\[A-Z0-9]{7}\.tmp,PSAttack-style command via cvtres.exe
0,Register-ScheduledTask,Command referencing Register-ScheduledTask (possible ASEP)
0,Software\\Microsoft\\Windows\\CurrentVersion\\Run,Reference to registry run key (possible ASEP)
0,reg *add,Registry addition (possible ASEP)
0,cmd.exe.*\\ADMIN\$\\,cmd.exe accessing the ADMIN$ share
1,^[a-zA-Z]{22}$,Metasploit-style service name: 22 characters, [A-Za-z]
1,^[a-zA-Z]{16}$,Metasploit-style service name: 16 characters, [A-Za-z]

2
safelist.txt Normal file → Executable file
View File

@ -7,3 +7,5 @@
regex
^"C:\\Program Files\\Google\\Chrome\\Application\\chrome\.exe"
^"C:\\Program Files\\Google\\Update\\GoogleUpdate\.exe"
^"C:\\Program Files \(x86\)\\Google\\Update\\GoogleUpdate\.exe"
"\\AppData\\Local\\Microsoft\\EdgeUpdate\\MicrosoftEdgeUpdate\.exe"