Created
September 9, 2022 01:16
-
-
Save mattnotmax/3c305880a8c4be407bbe69b6dc145471 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function Get-ComputerDetail | |
| { | |
| <# | |
| .SYNOPSIS | |
| This script is used to get useful information from a computer. | |
| Function: Get-ComputerDetail | |
| Author: Joe Bialek, Twitter: @JosephBialek | |
| Required Dependencies: None | |
| Optional Dependencies: None | |
| .DESCRIPTION | |
| This script is used to get useful information from a computer. Currently, the script gets the following information: | |
| -Explicit Credential Logons (Event ID 4648) | |
| -Logon events (Event ID 4624) | |
| -AppLocker logs to find what processes are created | |
| -PowerShell logs to find PowerShell scripts which have been executed | |
| -RDP Client Saved Servers, which indicates what servers the user typically RDP's in to | |
| .PARAMETER ToString | |
| Switch: Outputs the data as text instead of objects, good if you are using this script through a backdoor. | |
| .EXAMPLE | |
| Get-ComputerDetail | |
| Gets information about the computer and outputs it as PowerShell objects. | |
| Get-ComputerDetail -ToString | |
| Gets information about the computer and outputs it as raw text. | |
| .NOTES | |
| This script is useful for fingerprinting a server to see who connects to this server (from where), and where users on this server connect to. | |
| You can also use it to find Powershell scripts and executables which are typically run, and then use this to backdoor those files. | |
| .LINK | |
| Blog: http://clymb3r.wordpress.com/ | |
| Github repo: https://github.com/clymb3r/PowerShell | |
| #> | |
| [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] | |
| Param( | |
| [Parameter(Position=0)] | |
| [Switch] | |
| $ToString | |
| ) | |
| Set-StrictMode -Version 2 | |
| $SecurityLog = Get-EventLog -LogName Security | |
| $Filtered4624 = Find-4624Logon $SecurityLog | |
| $Filtered4648 = Find-4648Logon $SecurityLog | |
| $AppLockerLogs = Find-AppLockerLog | |
| $PSLogs = Find-PSScriptsInPSAppLog | |
| $RdpClientData = Find-RDPClientConnection | |
| if ($ToString) | |
| { | |
| Write-Output "Event ID 4624 (Logon):" | |
| Write-Output $Filtered4624.Values | Format-List | |
| Write-Output "Event ID 4648 (Explicit Credential Logon):" | |
| Write-Output $Filtered4648.Values | Format-List | |
| Write-Output "AppLocker Process Starts:" | |
| Write-Output $AppLockerLogs.Values | Format-List | |
| Write-Output "PowerShell Script Executions:" | |
| Write-Output $PSLogs.Values | Format-List | |
| Write-Output "RDP Client Data:" | |
| Write-Output $RdpClientData.Values | Format-List | |
| } | |
| else | |
| { | |
| $Properties = @{ | |
| LogonEvent4624 = $Filtered4624.Values | |
| LogonEvent4648 = $Filtered4648.Values | |
| AppLockerProcessStart = $AppLockerLogs.Values | |
| PowerShellScriptStart = $PSLogs.Values | |
| RdpClientData = $RdpClientData.Values | |
| } | |
| $ReturnObj = New-Object PSObject -Property $Properties | |
| return $ReturnObj | |
| } | |
| } | |
| function Find-4648Logon | |
| { | |
| <# | |
| .SYNOPSIS | |
| Retrieve the unique 4648 logon events. This will often find cases where a user is using remote desktop to connect to another computer. It will give the | |
| the account that RDP was launched with and the account name of the account being used to connect to the remote computer. This is useful | |
| for identifying normal authenticaiton patterns. Other actions that will trigger this include any runas action. | |
| Function: Find-4648Logon | |
| Author: Joe Bialek, Twitter: @JosephBialek | |
| Required Dependencies: None | |
| Optional Dependencies: None | |
| .DESCRIPTION | |
| Retrieve the unique 4648 logon events. This will often find cases where a user is using remote desktop to connect to another computer. It will give the | |
| the account that RDP was launched with and the account name of the account being used to connect to the remote computer. This is useful | |
| for identifying normal authenticaiton patterns. Other actions that will trigger this include any runas action. | |
| .EXAMPLE | |
| Find-4648Logon | |
| Gets the unique 4648 logon events. | |
| .NOTES | |
| .LINK | |
| Blog: http://clymb3r.wordpress.com/ | |
| Github repo: https://github.com/clymb3r/PowerShell | |
| #> | |
| Param( | |
| $SecurityLog | |
| ) | |
| $ExplicitLogons = $SecurityLog | Where-Object {$_.InstanceID -eq 4648} | |
| $ReturnInfo = @{} | |
| foreach ($ExplicitLogon in $ExplicitLogons) | |
| { | |
| $Subject = $false | |
| $AccountWhosCredsUsed = $false | |
| $TargetServer = $false | |
| $SourceAccountName = "" | |
| $SourceAccountDomain = "" | |
| $TargetAccountName = "" | |
| $TargetAccountDomain = "" | |
| $TargetServer = "" | |
| foreach ($line in $ExplicitLogon.Message -split "\r\n") | |
| { | |
| if ($line -cmatch "^Subject:$") | |
| { | |
| $Subject = $true | |
| } | |
| elseif ($line -cmatch "^Account\sWhose\sCredentials\sWere\sUsed:$") | |
| { | |
| $Subject = $false | |
| $AccountWhosCredsUsed = $true | |
| } | |
| elseif ($line -cmatch "^Target\sServer:") | |
| { | |
| $AccountWhosCredsUsed = $false | |
| $TargetServer = $true | |
| } | |
| elseif ($Subject -eq $true) | |
| { | |
| if ($line -cmatch "\s+Account\sName:\s+(\S.*)") | |
| { | |
| $SourceAccountName = $Matches[1] | |
| } | |
| elseif ($line -cmatch "\s+Account\sDomain:\s+(\S.*)") | |
| { | |
| $SourceAccountDomain = $Matches[1] | |
| } | |
| } | |
| elseif ($AccountWhosCredsUsed -eq $true) | |
| { | |
| if ($line -cmatch "\s+Account\sName:\s+(\S.*)") | |
| { | |
| $TargetAccountName = $Matches[1] | |
| } | |
| elseif ($line -cmatch "\s+Account\sDomain:\s+(\S.*)") | |
| { | |
| $TargetAccountDomain = $Matches[1] | |
| } | |
| } | |
| elseif ($TargetServer -eq $true) | |
| { | |
| if ($line -cmatch "\s+Target\sServer\sName:\s+(\S.*)") | |
| { | |
| $TargetServer = $Matches[1] | |
| } | |
| } | |
| } | |
| #Filter out logins that don't matter | |
| if (-not ($TargetAccountName -cmatch "^DWM-.*" -and $TargetAccountDomain -cmatch "^Window\sManager$")) | |
| { | |
| $Key = $SourceAccountName + $SourceAccountDomain + $TargetAccountName + $TargetAccountDomain + $TargetServer | |
| if (-not $ReturnInfo.ContainsKey($Key)) | |
| { | |
| $Properties = @{ | |
| LogType = 4648 | |
| LogSource = "Security" | |
| SourceAccountName = $SourceAccountName | |
| SourceDomainName = $SourceAccountDomain | |
| TargetAccountName = $TargetAccountName | |
| TargetDomainName = $TargetAccountDomain | |
| TargetServer = $TargetServer | |
| Count = 1 | |
| Times = @($ExplicitLogon.TimeGenerated) | |
| } | |
| $ResultObj = New-Object PSObject -Property $Properties | |
| $ReturnInfo.Add($Key, $ResultObj) | |
| } | |
| else | |
| { | |
| $ReturnInfo[$Key].Count++ | |
| $ReturnInfo[$Key].Times += ,$ExplicitLogon.TimeGenerated | |
| } | |
| } | |
| } | |
| return $ReturnInfo | |
| } | |
| function Find-4624Logon | |
| { | |
| <# | |
| .SYNOPSIS | |
| Find all unique 4624 Logon events to the server. This will tell you who is logging in and how. You can use this to figure out what accounts do | |
| network logons in to the server, what accounts RDP in, what accounts log in locally, etc... | |
| Function: Find-4624Logon | |
| Author: Joe Bialek, Twitter: @JosephBialek | |
| Required Dependencies: None | |
| Optional Dependencies: None | |
| .DESCRIPTION | |
| Find all unique 4624 Logon events to the server. This will tell you who is logging in and how. You can use this to figure out what accounts do | |
| network logons in to the server, what accounts RDP in, what accounts log in locally, etc... | |
| .EXAMPLE | |
| Find-4624Logon | |
| Find unique 4624 logon events. | |
| .NOTES | |
| .LINK | |
| Blog: http://clymb3r.wordpress.com/ | |
| Github repo: https://github.com/clymb3r/PowerShell | |
| #> | |
| Param ( | |
| $SecurityLog | |
| ) | |
| $Logons = $SecurityLog | Where-Object {$_.InstanceID -eq 4624} | |
| $ReturnInfo = @{} | |
| foreach ($Logon in $Logons) | |
| { | |
| $SubjectSection = $false | |
| $NewLogonSection = $false | |
| $NetworkInformationSection = $false | |
| $AccountName = "" | |
| $AccountDomain = "" | |
| $LogonType = "" | |
| $NewLogonAccountName = "" | |
| $NewLogonAccountDomain = "" | |
| $WorkstationName = "" | |
| $SourceNetworkAddress = "" | |
| $SourcePort = "" | |
| foreach ($line in $Logon.Message -Split "\r\n") | |
| { | |
| if ($line -cmatch "^Subject:$") | |
| { | |
| $SubjectSection = $true | |
| } | |
| elseif ($line -cmatch "^Logon\sType:\s+(\S.*)") | |
| { | |
| $LogonType = $Matches[1] | |
| } | |
| elseif ($line -cmatch "^New\sLogon:$") | |
| { | |
| $SubjectSection = $false | |
| $NewLogonSection = $true | |
| } | |
| elseif ($line -cmatch "^Network\sInformation:$") | |
| { | |
| $NewLogonSection = $false | |
| $NetworkInformationSection = $true | |
| } | |
| elseif ($SubjectSection) | |
| { | |
| if ($line -cmatch "^\s+Account\sName:\s+(\S.*)") | |
| { | |
| $AccountName = $Matches[1] | |
| } | |
| elseif ($line -cmatch "^\s+Account\sDomain:\s+(\S.*)") | |
| { | |
| $AccountDomain = $Matches[1] | |
| } | |
| } | |
| elseif ($NewLogonSection) | |
| { | |
| if ($line -cmatch "^\s+Account\sName:\s+(\S.*)") | |
| { | |
| $NewLogonAccountName = $Matches[1] | |
| } | |
| elseif ($line -cmatch "^\s+Account\sDomain:\s+(\S.*)") | |
| { | |
| $NewLogonAccountDomain = $Matches[1] | |
| } | |
| } | |
| elseif ($NetworkInformationSection) | |
| { | |
| if ($line -cmatch "^\s+Workstation\sName:\s+(\S.*)") | |
| { | |
| $WorkstationName = $Matches[1] | |
| } | |
| elseif ($line -cmatch "^\s+Source\sNetwork\sAddress:\s+(\S.*)") | |
| { | |
| $SourceNetworkAddress = $Matches[1] | |
| } | |
| elseif ($line -cmatch "^\s+Source\sPort:\s+(\S.*)") | |
| { | |
| $SourcePort = $Matches[1] | |
| } | |
| } | |
| } | |
| #Filter out logins that don't matter | |
| if (-not ($NewLogonAccountDomain -cmatch "NT\sAUTHORITY" -or $NewLogonAccountDomain -cmatch "Window\sManager")) | |
| { | |
| $Key = $AccountName + $AccountDomain + $NewLogonAccountName + $NewLogonAccountDomain + $LogonType + $WorkstationName + $SourceNetworkAddress + $SourcePort | |
| if (-not $ReturnInfo.ContainsKey($Key)) | |
| { | |
| $Properties = @{ | |
| LogType = 4624 | |
| LogSource = "Security" | |
| SourceAccountName = $AccountName | |
| SourceDomainName = $AccountDomain | |
| NewLogonAccountName = $NewLogonAccountName | |
| NewLogonAccountDomain = $NewLogonAccountDomain | |
| LogonType = $LogonType | |
| WorkstationName = $WorkstationName | |
| SourceNetworkAddress = $SourceNetworkAddress | |
| SourcePort = $SourcePort | |
| Count = 1 | |
| Times = @($Logon.TimeGenerated) | |
| } | |
| $ResultObj = New-Object PSObject -Property $Properties | |
| $ReturnInfo.Add($Key, $ResultObj) | |
| } | |
| else | |
| { | |
| $ReturnInfo[$Key].Count++ | |
| $ReturnInfo[$Key].Times += ,$Logon.TimeGenerated | |
| } | |
| } | |
| } | |
| return $ReturnInfo | |
| } | |
| function Find-AppLockerLog | |
| { | |
| <# | |
| .SYNOPSIS | |
| Look through the AppLocker logs to find processes that get run on the server. You can then backdoor these exe's (or figure out what they normally run). | |
| Function: Find-AppLockerLog | |
| Author: Joe Bialek, Twitter: @JosephBialek | |
| Required Dependencies: None | |
| Optional Dependencies: None | |
| .DESCRIPTION | |
| Look through the AppLocker logs to find processes that get run on the server. You can then backdoor these exe's (or figure out what they normally run). | |
| .EXAMPLE | |
| Find-AppLockerLog | |
| Find process creations from AppLocker logs. | |
| .NOTES | |
| .LINK | |
| Blog: http://clymb3r.wordpress.com/ | |
| Github repo: https://github.com/clymb3r/PowerShell | |
| #> | |
| $ReturnInfo = @{} | |
| $AppLockerLogs = Get-WinEvent -LogName "Microsoft-Windows-AppLocker/EXE and DLL" -ErrorAction SilentlyContinue | Where-Object {$_.Id -eq 8002} | |
| foreach ($Log in $AppLockerLogs) | |
| { | |
| $SID = New-Object System.Security.Principal.SecurityIdentifier($Log.Properties[7].Value) | |
| $UserName = $SID.Translate( [System.Security.Principal.NTAccount]) | |
| $ExeName = $Log.Properties[10].Value | |
| $Key = $UserName.ToString() + "::::" + $ExeName | |
| if (!$ReturnInfo.ContainsKey($Key)) | |
| { | |
| $Properties = @{ | |
| Exe = $ExeName | |
| User = $UserName.Value | |
| Count = 1 | |
| Times = @($Log.TimeCreated) | |
| } | |
| $Item = New-Object PSObject -Property $Properties | |
| $ReturnInfo.Add($Key, $Item) | |
| } | |
| else | |
| { | |
| $ReturnInfo[$Key].Count++ | |
| $ReturnInfo[$Key].Times += ,$Log.TimeCreated | |
| } | |
| } | |
| return $ReturnInfo | |
| } | |
| Function Find-PSScriptsInPSAppLog | |
| { | |
| <# | |
| .SYNOPSIS | |
| Go through the PowerShell operational log to find scripts that run (by looking for ExecutionPipeline logs eventID 4100 in PowerShell app log). | |
| You can then backdoor these scripts or do other malicious things. | |
| Function: Find-AppLockerLog | |
| Author: Joe Bialek, Twitter: @JosephBialek | |
| Required Dependencies: None | |
| Optional Dependencies: None | |
| .DESCRIPTION | |
| Go through the PowerShell operational log to find scripts that run (by looking for ExecutionPipeline logs eventID 4100 in PowerShell app log). | |
| You can then backdoor these scripts or do other malicious things. | |
| .EXAMPLE | |
| Find-PSScriptsInPSAppLog | |
| Find unique PowerShell scripts being executed from the PowerShell operational log. | |
| .NOTES | |
| .LINK | |
| Blog: http://clymb3r.wordpress.com/ | |
| Github repo: https://github.com/clymb3r/PowerShell | |
| #> | |
| $ReturnInfo = @{} | |
| $Logs = Get-WinEvent -LogName "Microsoft-Windows-PowerShell/Operational" -ErrorAction SilentlyContinue | Where-Object {$_.Id -eq 4100} | |
| foreach ($Log in $Logs) | |
| { | |
| $LogDetails = $Log.Message -split "`r`n" | |
| $FoundScriptName = $false | |
| foreach($Line in $LogDetails) | |
| { | |
| if ($Line -imatch "^\s*Script\sName\s=\s(.+)") | |
| { | |
| $ScriptName = $Matches[1] | |
| $FoundScriptName = $true | |
| } | |
| elseif ($Line -imatch "^\s*User\s=\s(.*)") | |
| { | |
| $User = $Matches[1] | |
| } | |
| } | |
| if ($FoundScriptName) | |
| { | |
| $Key = $ScriptName + "::::" + $User | |
| if (!$ReturnInfo.ContainsKey($Key)) | |
| { | |
| $Properties = @{ | |
| ScriptName = $ScriptName | |
| UserName = $User | |
| Count = 1 | |
| Times = @($Log.TimeCreated) | |
| } | |
| $Item = New-Object PSObject -Property $Properties | |
| $ReturnInfo.Add($Key, $Item) | |
| } | |
| else | |
| { | |
| $ReturnInfo[$Key].Count++ | |
| $ReturnInfo[$Key].Times += ,$Log.TimeCreated | |
| } | |
| } | |
| } | |
| return $ReturnInfo | |
| } | |
| Function Find-RDPClientConnection | |
| { | |
| <# | |
| .SYNOPSIS | |
| Search the registry to find saved RDP client connections. This shows you what connections an RDP client has remembered, indicating what servers the user | |
| usually RDP's to. | |
| Function: Find-RDPClientConnection | |
| Author: Joe Bialek, Twitter: @JosephBialek | |
| Required Dependencies: None | |
| Optional Dependencies: None | |
| .DESCRIPTION | |
| Search the registry to find saved RDP client connections. This shows you what connections an RDP client has remembered, indicating what servers the user usually RDP's to. | |
| .EXAMPLE | |
| Find-RDPClientConnection | |
| Find unique saved RDP client connections. | |
| .NOTES | |
| .LINK | |
| Blog: http://clymb3r.wordpress.com/ | |
| Github repo: https://github.com/clymb3r/PowerShell | |
| #> | |
| $ReturnInfo = @{} | |
| New-PSDrive -Name HKU -PSProvider Registry -Root Registry::HKEY_USERS | Out-Null | |
| #Attempt to enumerate the servers for all users | |
| $Users = Get-ChildItem -Path "HKU:\" | |
| foreach ($UserSid in $Users.PSChildName) | |
| { | |
| $Servers = Get-ChildItem "HKU:\$($UserSid)\Software\Microsoft\Terminal Server Client\Servers" -ErrorAction SilentlyContinue | |
| foreach ($Server in $Servers) | |
| { | |
| $Server = $Server.PSChildName | |
| $UsernameHint = (Get-ItemProperty -Path "HKU:\$($UserSid)\Software\Microsoft\Terminal Server Client\Servers\$($Server)").UsernameHint | |
| $Key = $UserSid + "::::" + $Server + "::::" + $UsernameHint | |
| if (!$ReturnInfo.ContainsKey($Key)) | |
| { | |
| $SIDObj = New-Object System.Security.Principal.SecurityIdentifier($UserSid) | |
| $User = ($SIDObj.Translate([System.Security.Principal.NTAccount])).Value | |
| $Properties = @{ | |
| CurrentUser = $User | |
| Server = $Server | |
| UsernameHint = $UsernameHint | |
| } | |
| $Item = New-Object PSObject -Property $Properties | |
| $ReturnInfo.Add($Key, $Item) | |
| } | |
| } | |
| } | |
| return $ReturnInfo | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment