575 lines
17 KiB
PowerShell
575 lines
17 KiB
PowerShell
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
|
|
}
|