From 6a6ec93fb61fd662f09eb5a51aaa07894563bead Mon Sep 17 00:00:00 2001 From: Aconite33 Date: Thu, 31 May 2018 11:37:00 -0400 Subject: [PATCH] Forklifted functions from Empire's Invoke-Kerberoast functions into Recon/PowerView.ps1. --- Recon/PowerView.ps1 | 278 +++++++++++--------------------------------- 1 file changed, 69 insertions(+), 209 deletions(-) diff --git a/Recon/PowerView.ps1 b/Recon/PowerView.ps1 index 6be2241..82d8046 100755 --- a/Recon/PowerView.ps1 +++ b/Recon/PowerView.ps1 @@ -2607,6 +2607,14 @@ Defaults to 'John'. A [Management.Automation.PSCredential] object of alternate credentials for connection to the remote domain using Invoke-UserImpersonation. +.PARAMETER Delay + +Specifies the delay in seconds between ticket requests. + +.PARAMETER Jitter + +Specifies the jitter (0-1.0) to apply to any specified -Delay, defaults to +/- 0.3 + .EXAMPLE Get-DomainSPNTicket -SPN "HTTP/web.testlab.local" @@ -2663,6 +2671,14 @@ Outputs a custom object containing the SamAccountName, ServicePrincipalName, and [String] $OutputFormat = 'John', + [ValidateRange(0,10000)] + [Int] + $Delay = 0, + + [ValidateRange(0.0, 1.0)] + [Double] + $Jitter = .3, + [Management.Automation.PSCredential] [Management.Automation.CredentialAttribute()] $Credential = [Management.Automation.PSCredential]::Empty @@ -2683,8 +2699,11 @@ Outputs a custom object containing the SamAccountName, ServicePrincipalName, and else { $TargetObject = $SPN } + + $RandNo = New-Object System.Random ForEach ($Object in $TargetObject) { + if ($PSBoundParameters['User']) { $UserSPN = $Object.ServicePrincipalName $SamAccountName = $Object.SamAccountName @@ -2761,6 +2780,8 @@ Outputs a custom object containing the SamAccountName, ServicePrincipalName, and $Out.PSObject.TypeNames.Insert(0, 'PowerView.SPNTicket') Write-Output $Out } + # sleep for our semi-randomized interval + Start-Sleep -Seconds $RandNo.Next((1-$Jitter)*$Delay, (1+$Jitter)*$Delay) } } @@ -2775,87 +2796,59 @@ Outputs a custom object containing the SamAccountName, ServicePrincipalName, and function Invoke-Kerberoast { <# .SYNOPSIS - Requests service tickets for kerberoast-able accounts and returns extracted ticket hashes. - Author: Will Schroeder (@harmj0y), @machosec License: BSD 3-Clause Required Dependencies: Invoke-UserImpersonation, Invoke-RevertToSelf, Get-DomainUser, Get-DomainSPNTicket - .DESCRIPTION - Uses Get-DomainUser to query for user accounts with non-null service principle names (SPNs) and uses Get-SPNTicket to request/extract the crackable ticket information. - +The ticket format can be specified with -OutputFormat . .PARAMETER Identity - A SamAccountName (e.g. harmj0y), DistinguishedName (e.g. CN=harmj0y,CN=Users,DC=testlab,DC=local), SID (e.g. S-1-5-21-890171859-3433809279-3366196753-1108), or GUID (e.g. 4c435dd7-dc58-4b14-9a5e-1fdb0e80d201). Wildcards accepted. - .PARAMETER Domain - Specifies the domain to use for the query, defaults to the current domain. - .PARAMETER LDAPFilter - Specifies an LDAP query string that is used to filter Active Directory objects. - .PARAMETER SearchBase - The LDAP source to search through, e.g. "LDAP://OU=secret,DC=testlab,DC=local" Useful for OU queries. - .PARAMETER Server - Specifies an Active Directory server (domain controller) to bind to. - .PARAMETER SearchScope - Specifies the scope to search under, Base/OneLevel/Subtree (default of Subtree). - .PARAMETER ResultPageSize - Specifies the PageSize to set for the LDAP searcher object. - .PARAMETER ServerTimeLimit - Specifies the maximum amount of time the server spends searching. Default of 120 seconds. - .PARAMETER Tombstone - Switch. Specifies that the searcher should also return deleted/tombstoned objects. - +.PARAMETER OutputFormat +Either 'John' for John the Ripper style hash formatting, or 'Hashcat' for Hashcat format. +Defaults to 'John'. .PARAMETER Credential - A [Management.Automation.PSCredential] object of alternate credentials for connection to the target domain. - +.PARAMETER Delay +Specifies the delay in seconds between ticket requests. +.PARAMETER Jitter +Specifies the jitter (0-1.0) to apply to any specified -Delay, defaults to +/- 0.3 .EXAMPLE - Invoke-Kerberoast | fl - Kerberoasts all found SPNs for the current domain. - .EXAMPLE - -Invoke-Kerberoast -Domain dev.testlab.local | fl - +Invoke-Kerberoast -Domain dev.testlab.local -OutputFormat HashCat | fl Kerberoasts all found SPNs for the testlab.local domain, outputting to HashCat format instead of John (the default). - .EXAMPLE - $SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -orce $Cred = New-Object System.Management.Automation.PSCredential('TESTLB\dfm.a', $SecPassword) Invoke-Kerberoast -Credential $Cred -Verbose -Domain testlab.local | fl - Kerberoasts all found SPNs for the testlab.local domain using alternate credentials. - .OUTPUTS - PowerView.SPNTicket - Outputs a custom object containing the SamAccountName, ServicePrincipalName, and encrypted ticket section. #> @@ -2902,6 +2895,19 @@ Outputs a custom object containing the SamAccountName, ServicePrincipalName, and [Switch] $Tombstone, + [ValidateRange(0,10000)] + [Int] + $Delay = 0, + + [ValidateRange(0.0, 1.0)] + [Double] + $Jitter = .3, + + [ValidateSet('John', 'Hashcat')] + [Alias('Format')] + [String] + $OutputFormat = 'John', + [Management.Automation.PSCredential] [Management.Automation.CredentialAttribute()] $Credential = [Management.Automation.PSCredential]::Empty @@ -2929,7 +2935,7 @@ Outputs a custom object containing the SamAccountName, ServicePrincipalName, and PROCESS { if ($PSBoundParameters['Identity']) { $UserSearcherArguments['Identity'] = $Identity } - Get-DomainUser @UserSearcherArguments | Where-Object {$_.samaccountname -ne 'krbtgt'} | Get-DomainSPNTicket + Get-DomainUser @UserSearcherArguments | Where-Object {$_.samaccountname -ne 'krbtgt'} | Get-DomainSPNTicket -Delay $Delay -OutputFormat $OutputFormat -Jitter $Jitter } END { @@ -3119,27 +3125,18 @@ https://support.microsoft.com/en-us/kb/305144 function Convert-LDAPProperty { <# .SYNOPSIS - Helper that converts specific LDAP property result fields and outputs a custom psobject. - Author: Will Schroeder (@harmj0y) License: BSD 3-Clause Required Dependencies: None - .DESCRIPTION - Converts a set of raw LDAP properties results from ADSI/LDAP searches into a proper PSObject. Used by several of the Get-Domain* function. - .PARAMETER Properties - Properties object to extract out LDAP fields for display. - .OUTPUTS - System.Management.Automation.PSCustomObject - A custom PSObject with LDAP hashtable properties translated. #> @@ -3251,94 +3248,53 @@ A custom PSObject with LDAP hashtable properties translated. function Get-DomainSearcher { <# .SYNOPSIS - Helper used by various functions that builds a custom AD searcher object. - Author: Will Schroeder (@harmj0y) License: BSD 3-Clause Required Dependencies: Get-Domain - .DESCRIPTION - Takes a given domain and a number of customizations and returns a System.DirectoryServices.DirectorySearcher object. This function is used heavily by other LDAP/ADSI searcher functions (Verb-Domain*). - .PARAMETER Domain - Specifies the domain to use for the query, defaults to the current domain. - .PARAMETER LDAPFilter - Specifies an LDAP query string that is used to filter Active Directory objects. - .PARAMETER Properties - Specifies the properties of the output object to retrieve from the server. - .PARAMETER SearchBase - The LDAP source to search through, e.g. "LDAP://OU=secret,DC=testlab,DC=local" Useful for OU queries. - .PARAMETER SearchBasePrefix - Specifies a prefix for the LDAP search string (i.e. "CN=Sites,CN=Configuration"). - .PARAMETER Server - Specifies an Active Directory server (domain controller) to bind to for the search. - .PARAMETER SearchScope - Specifies the scope to search under, Base/OneLevel/Subtree (default of Subtree). - .PARAMETER ResultPageSize - Specifies the PageSize to set for the LDAP searcher object. - .PARAMETER ResultPageSize - Specifies the PageSize to set for the LDAP searcher object. - .PARAMETER ServerTimeLimit - Specifies the maximum amount of time the server spends searching. Default of 120 seconds. - .PARAMETER SecurityMasks - Specifies an option for examining security information of a directory object. One of 'Dacl', 'Group', 'None', 'Owner', 'Sacl'. - .PARAMETER Tombstone - Switch. Specifies that the searcher should also return deleted/tombstoned objects. - .PARAMETER Credential - A [Management.Automation.PSCredential] object of alternate credentials for connection to the target domain. - .EXAMPLE - Get-DomainSearcher -Domain testlab.local - Return a searcher for all objects in testlab.local. - .EXAMPLE - Get-DomainSearcher -Domain testlab.local -LDAPFilter '(samAccountType=805306368)' -Properties 'SamAccountName,lastlogon' - Return a searcher for user objects in testlab.local and only return the SamAccountName and LastLogon properties. - .EXAMPLE - Get-DomainSearcher -SearchBase "LDAP://OU=secret,DC=testlab,DC=local" - Return a searcher that searches through the specific ADS/LDAP search base (i.e. OU). - .OUTPUTS - System.DirectoryServices.DirectorySearcher #> @@ -3401,38 +3357,36 @@ System.DirectoryServices.DirectorySearcher PROCESS { if ($PSBoundParameters['Domain']) { $TargetDomain = $Domain - - if ($ENV:USERDNSDOMAIN -and ($ENV:USERDNSDOMAIN.Trim() -ne '')) { - # see if we can grab the user DNS logon domain from environment variables - $UserDomain = $ENV:USERDNSDOMAIN - if ($ENV:LOGONSERVER -and ($ENV:LOGONSERVER.Trim() -ne '') -and $UserDomain) { - $BindServer = "$($ENV:LOGONSERVER -replace '\\','').$UserDomain" - } - } } - elseif ($PSBoundParameters['Credential']) { - # if not -Domain is specified, but -Credential is, try to retrieve the current domain name with Get-Domain - $DomainObject = Get-Domain -Credential $Credential - $BindServer = ($DomainObject.PdcRoleOwner).Name + else { + # if not -Domain is specified, retrieve the current domain name + if ($PSBoundParameters['Credential']) { + $DomainObject = Get-Domain -Credential $Credential + } + else { + $DomainObject = Get-Domain + } $TargetDomain = $DomainObject.Name } - elseif ($ENV:USERDNSDOMAIN -and ($ENV:USERDNSDOMAIN.Trim() -ne '')) { - # see if we can grab the user DNS logon domain from environment variables - $TargetDomain = $ENV:USERDNSDOMAIN - if ($ENV:LOGONSERVER -and ($ENV:LOGONSERVER.Trim() -ne '') -and $TargetDomain) { - $BindServer = "$($ENV:LOGONSERVER -replace '\\','').$TargetDomain" + + if (-not $PSBoundParameters['Server']) { + # if there's not a specified server to bind to, try to pull the current domain PDC + try { + if ($DomainObject) { + $BindServer = $DomainObject.PdcRoleOwner.Name + } + elseif ($PSBoundParameters['Credential']) { + $BindServer = ((Get-Domain -Credential $Credential).PdcRoleOwner).Name + } + else { + $BindServer = ((Get-Domain).PdcRoleOwner).Name + } + } + catch { + throw "[Get-DomainSearcher] Error in retrieving PDC for current domain: $_" } } else { - # otherwise, resort to Get-Domain to retrieve the current domain object - write-verbose "get-domain" - $DomainObject = Get-Domain - $BindServer = ($DomainObject.PdcRoleOwner).Name - $TargetDomain = $DomainObject.Name - } - - if ($PSBoundParameters['Server']) { - # if there's not a specified server to bind to, try to pull a logon server from ENV variables $BindServer = $Server } @@ -3478,7 +3432,7 @@ System.DirectoryServices.DirectorySearcher } $SearchString += $DN - Write-Verbose "[Get-DomainSearcher] search base: $SearchString" + Write-Verbose "[Get-DomainSearcher] search string: $SearchString" if ($Credential -ne [Management.Automation.PSCredential]::Empty) { Write-Verbose "[Get-DomainSearcher] Using alternate credentials for LDAP connection" @@ -4024,45 +3978,28 @@ Outputs custom PSObjects with detailed information about the DNS record entry. function Get-Domain { <# .SYNOPSIS - Returns the domain object for the current (or specified) domain. - Author: Will Schroeder (@harmj0y) License: BSD 3-Clause Required Dependencies: None - .DESCRIPTION - Returns a System.DirectoryServices.ActiveDirectory.Domain object for the current domain or the domain specified with -Domain X. - .PARAMETER Domain - Specifies the domain name to query for, defaults to the current domain. - .PARAMETER Credential - A [Management.Automation.PSCredential] object of alternate credentials for connection to the target domain. - .EXAMPLE - Get-Domain -Domain testlab.local - .EXAMPLE - $SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force $Cred = New-Object System.Management.Automation.PSCredential('TESTLAB\dfm.a', $SecPassword) Get-Domain -Credential $Cred - .OUTPUTS - System.DirectoryServices.ActiveDirectory.Domain - A complex .NET domain object. - .LINK - http://social.technet.microsoft.com/Forums/scriptcenter/en-US/0c5b3f83-e528-4d49-92a4-dee31f4b481c/finding-the-dn-of-the-the-domain-without-admodule-in-powershell?forum=ITCG #> @@ -4848,184 +4785,107 @@ Custom PSObject with translated object property outliers. function Get-DomainUser { <# .SYNOPSIS - Return all users or specific user objects in AD. - Author: Will Schroeder (@harmj0y) License: BSD 3-Clause Required Dependencies: Get-DomainSearcher, Convert-ADName, Convert-LDAPProperty - .DESCRIPTION - Builds a directory searcher object using Get-DomainSearcher, builds a custom LDAP filter based on targeting/filter parameters, and searches for all objects matching the criteria. To only return specific properties, use "-Properties samaccountname,usnchanged,...". By default, all user objects for the current domain are returned. - .PARAMETER Identity - A SamAccountName (e.g. harmj0y), DistinguishedName (e.g. CN=harmj0y,CN=Users,DC=testlab,DC=local), SID (e.g. S-1-5-21-890171859-3433809279-3366196753-1108), or GUID (e.g. 4c435dd7-dc58-4b14-9a5e-1fdb0e80d201). Wildcards accepted. Also accepts DOMAIN\user format. - .PARAMETER SPN - Switch. Only return user objects with non-null service principal names. - .PARAMETER UACFilter - Dynamic parameter that accepts one or more values from $UACEnum, including "NOT_X" negation forms. To see all possible values, run '0|ConvertFrom-UACValue -ShowAll'. - .PARAMETER AdminCount - Switch. Return users with '(adminCount=1)' (meaning are/were privileged). - .PARAMETER AllowDelegation - Switch. Return user accounts that are not marked as 'sensitive and not allowed for delegation' - .PARAMETER DisallowDelegation - Switch. Return user accounts that are marked as 'sensitive and not allowed for delegation' - .PARAMETER TrustedToAuth - Switch. Return computer objects that are trusted to authenticate for other principals. - .PARAMETER PreauthNotRequired - Switch. Return user accounts with "Do not require Kerberos preauthentication" set. - .PARAMETER Domain - Specifies the domain to use for the query, defaults to the current domain. - .PARAMETER LDAPFilter - Specifies an LDAP query string that is used to filter Active Directory objects. - .PARAMETER Properties - Specifies the properties of the output object to retrieve from the server. - .PARAMETER SearchBase - The LDAP source to search through, e.g. "LDAP://OU=secret,DC=testlab,DC=local" Useful for OU queries. - .PARAMETER Server - Specifies an Active Directory server (domain controller) to bind to. - .PARAMETER SearchScope - Specifies the scope to search under, Base/OneLevel/Subtree (default of Subtree). - .PARAMETER ResultPageSize - Specifies the PageSize to set for the LDAP searcher object. - .PARAMETER ServerTimeLimit - Specifies the maximum amount of time the server spends searching. Default of 120 seconds. - .PARAMETER SecurityMasks - Specifies an option for examining security information of a directory object. One of 'Dacl', 'Group', 'None', 'Owner', 'Sacl'. - .PARAMETER Tombstone - Switch. Specifies that the searcher should also return deleted/tombstoned objects. - .PARAMETER FindOne - Only return one result object. - .PARAMETER Credential - A [Management.Automation.PSCredential] object of alternate credentials for connection to the target domain. - .PARAMETER Raw - Switch. Return raw results instead of translating the fields into a custom PSObject. - .EXAMPLE - Get-DomainUser -Domain testlab.local - Return all users for the testlab.local domain - .EXAMPLE - Get-DomainUser "S-1-5-21-890171859-3433809279-3366196753-1108","administrator" - Return the user with the given SID, as well as Administrator. - .EXAMPLE - 'S-1-5-21-890171859-3433809279-3366196753-1114', 'CN=dfm,CN=Users,DC=testlab,DC=local','4c435dd7-dc58-4b14-9a5e-1fdb0e80d201','administrator' | Get-DomainUser -Properties samaccountname,lastlogoff - lastlogoff samaccountname ---------- -------------- 12/31/1600 4:00:00 PM dfm.a 12/31/1600 4:00:00 PM dfm 12/31/1600 4:00:00 PM harmj0y 12/31/1600 4:00:00 PM Administrator - .EXAMPLE - Get-DomainUser -SearchBase "LDAP://OU=secret,DC=testlab,DC=local" -AdminCount -AllowDelegation - Search the specified OU for privileged user (AdminCount = 1) that allow delegation - .EXAMPLE - Get-DomainUser -LDAPFilter '(!primarygroupid=513)' -Properties samaccountname,lastlogon - Search for users with a primary group ID other than 513 ('domain users') and only return samaccountname and lastlogon - .EXAMPLE - Get-DomainUser -UACFilter DONT_REQ_PREAUTH,NOT_PASSWORD_EXPIRED - Find users who doesn't require Kerberos preauthentication and DON'T have an expired password. - .EXAMPLE - $SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force $Cred = New-Object System.Management.Automation.PSCredential('TESTLAB\dfm.a', $SecPassword) Get-DomainUser -Credential $Cred - .EXAMPLE - Get-Domain | Select-Object -Expand name testlab.local - Get-DomainUser dev\user1 -Verbose -Properties distinguishedname VERBOSE: [Get-DomainSearcher] search string: LDAP://PRIMARY.testlab.local/DC=testlab,DC=local VERBOSE: [Get-DomainSearcher] search string: LDAP://PRIMARY.testlab.local/DC=dev,DC=testlab,DC=local VERBOSE: [Get-DomainUser] filter string: (&(samAccountType=805306368)(|(samAccountName=user1))) - distinguishedname ----------------- CN=user1,CN=Users,DC=dev,DC=testlab,DC=local - .INPUTS - String - .OUTPUTS - PowerView.User - Custom PSObject with translated user property fields. - PowerView.User.Raw - The raw DirectoryServices.SearchResult object, if -Raw is enabled. #>