Adding Get-ComputerDetails recon script

Get-ComputerDetails is a recon script which pulls a variety of useful
information off a computer which might later be useful by an attacker.
This includes:
Logons
AppLocker process start logs
PowerShell logs to find scripts run
RDP Client saved servers
This commit is contained in:
clymb3r 2014-02-20 17:47:27 -08:00
parent b684da050a
commit 308042f493
2 changed files with 439 additions and 1 deletions

View File

@ -0,0 +1,438 @@
function Get-ComputerDetails
{
<#
.SYNOPSIS
This script is used to get useful information from a computer.
Function: Get-ComputerDetails
Author: Joe Bialek, Twitter: @JosephBialek
Required Dependencies: None
Optional Dependencies: None
Version: 1.0
.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-ComputerDetails
Gets information about the computer and outputs it as PowerShell objects.
Get-ComputerDetails -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
#>
Param(
[Parameter(Position=0)]
[Switch]
$ToString
)
Set-StrictMode -Version 2
#Retrieve the 4648 logon event. 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-ExplicitLogons
{
Param(
$SecurityLog
)
$ExplicitLogons = $SecurityLog | Where {$_.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
}
#Find all 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...
# This is event 4624.
function Find-AllLogons
{
Param (
$SecurityLog
)
$Logons = $SecurityLog | Where {$_.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
}
#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-AppLockerLogs
{
$ReturnInfo = @{}
$AppLockerLogs = Get-WinEvent -LogName "Microsoft-Windows-AppLocker/EXE and DLL" -ErrorAction SilentlyContinue | Where {$_.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
}
#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-PSScriptsInPSAppLog
{
$ReturnInfo = @{}
$Logs = Get-WinEvent -LogName "Microsoft-Windows-PowerShell/Operational" -ErrorAction SilentlyContinue | Where {$_.Id -eq 4100}
foreach ($Log in $Logs)
{
$ContainsScriptName = $false
$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
}
#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-RDPClientConnections
{
$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 ($User in $Users.PSChildName)
{
$Servers = Get-ChildItem "HKU:\$($User)\Software\Microsoft\Terminal Server Client\Servers" -ErrorAction SilentlyContinue
foreach ($Server in $Servers)
{
$Server = $Server.PSChildName
$UsernameHint = (Get-ItemProperty -Path "HKU:\$($User)\Software\Microsoft\Terminal Server Client\Servers\$($Server)").UsernameHint
$Key = $User + "::::" + $Server + "::::" + $UsernameHint
if (!$ReturnInfo.ContainsKey($Key))
{
$Properties = @{
CurrentUser = $User
Server = $Server
UsernameHint = $UsernameHint
}
$Item = New-Object PSObject -Property $Properties
$ReturnInfo.Add($Key, $Item)
}
}
}
return $ReturnInfo
}
$SecurityLog = Get-EventLog -LogName Security
$Filtered4624 = Find-AllLogons $SecurityLog
$Filtered4648 = Find-ExplicitLogons $SecurityLog
$AppLockerLogs = Find-AppLockerLogs
$PSLogs = Find-PSScriptsInPSAppLog
$RdpClientData = Find-RDPClientConnections
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
}
}

View File

@ -74,7 +74,7 @@ ModuleList = @(@{ModuleName = 'Recon'; ModuleVersion = '1.0.0.0'; GUID = '7e775a
# List of all files packaged with this module
FileList = 'Recon.psm1', 'Recon.psd1', 'Get-HttpStatus.ps1', 'Invoke-ReverseDnsLookup.ps1',
'Invoke-Portscan.ps1', 'Usage.md'
'Invoke-Portscan.ps1', 'Get-ComputerDetails', 'Usage.md'
# Private data to pass to the module specified in RootModule/ModuleToProcess
# PrivateData = ''