System Root


After performing some basic enumeration, I found an interesting note at the system root

*evil-winrm* ps c:\> dir
 
 
    directory: C:\
 
 
Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----        5/29/2020   5:13 PM                Departments
d-----        5/29/2020   5:23 PM                HP Universal Print Driver
d-----        5/29/2020   4:36 PM                inetpub
d-----        5/26/2020   6:08 PM                PerfLogs
d-r---        6/11/2020   1:57 AM                Program Files
d-----        5/29/2020   4:54 PM                Program Files (x86)
d-----         6/1/2020   4:24 AM                test
d-r---        5/31/2020   5:08 PM                Users
d-----        10/9/2020   8:16 AM                Windows
-ar---        6/10/2020   6:22 PM            334 readme.txt

It’s the readme.txt file

readme.txt


*Evil-WinRM* PS C:\> cat readme.txt
// MFT printing format issue
 
note to HP engineer:
 
The "test" directory has been created. For repeated tests while diagnosing this issue, the same folder should be used.
 
This is a production environment and the "solution" should be developed and confirmed working in your testbed
 
All changes will be reverted every 2 mins.

The note seems to be addressing an issue regarding the printer and mentions that there is a “test” directory for development only and all the changes will be reverted every 2 minutes.

This may answer why there’s been a password reset every 2 minutes to those 3 users earlier.

test


i can also see the “test” directory at the c:\test

*evil-winrm* ps c:\> dir -force test
*evil-winrm* ps c:\> icacls test
test nt authority\system:(I)(OI)(CI)(F)
     builtin\administrators:(I)(OI)(CI)(F)
     builtin\users:(I)(OI)(CI)(RX)
     builtin\users:(I)(CI)(AD)
     builtin\users:(I)(CI)(WD)
     creator owner:(I)(OI)(CI)(IO)(F)
 
Successfully processed 1 files; Failed processing 0 files

The “test” directory is empty, but the current user is have a complete control over the directory based on the ACLs enumerated

Looking a bit further, I found something else

ProgramData


*Evil-WinRM* PS C:\ProgramData\Microsoft> dir
 
 
    Directory: C:\ProgramData\Microsoft
 
 
Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----        5/29/2020   4:40 PM                Crypto
d-----        7/16/2016   6:18 AM                Device Stage
d---s-         2/2/2023   8:31 AM                Diagnosis
d-----        7/16/2016   6:18 AM                DRM
d-----        7/16/2016   6:18 AM                Event Viewer
d-----        7/16/2016   6:18 AM                NetFramework
d-----        7/16/2016   6:18 AM                Network
d-----        7/16/2016   6:18 AM                servermanager
d-----        7/16/2016   6:18 AM                Vault
d-----        7/16/2016   6:18 AM                WDF
d-----       11/20/2016   6:43 PM                Windows
d-----         6/1/2020   1:38 AM                Windows Defender
d-----        7/16/2016   6:18 AM                WinMSIPC
-a----         6/1/2020   3:38 AM            488 revert.ps1
-a----         6/1/2020   3:00 AM           6714 Set-LHSTokenPrivilege.ps1
-a----         6/1/2020   2:59 AM         120320 unload_driver.exe

At the Microsoft installation directory of ProgramData, I see two unique PowerShell scripts I recall that one of them were picked up by PEAS earlier.

revert.ps1


*evil-winrm* ps c:\ProgramData\Microsoft> cat revert.ps1
$password = ConvertTo-SecureString -String '$fab@s3Rv1ce$1' -AsPlainText -Force
$credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList ("FABRICORP\svc-print", $password);
start-process c:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -Argument "Import-Module C:\ProgramData\Microsoft\Set-LHSTokenPrivilege.ps1; C:\ProgramData\Microsoft\unload_driver.exe; Remove-Item -Path HKCU:\System\CurrentControlSet\* -Recurse" -Credential $credential

This script basically starts a new process that

  • imports the other PowerShell script; Set-LHSTokenPrivilege.ps1
  • execute the unload_driver.exe program
  • recursively deletes everything under hkcu:\System\CurrentControlSet\*

The unload_driver.exe program seems to be pretty much self-explanatory.

I assume that this was set for Driver Exploitation, and there must be a scheduled task running in the background executing this.

Set-LHSTokenPrivilege.ps1


*Evil-WinRM* PS C:\ProgramData\Microsoft> cat Set-LHSTokenPrivilege.ps1
function Set-LHSTokenPrivilege
{
<#
.SYNOPSIS
    Enables or disables privileges in a specified access token.
 
.DESCRIPTION
    Enables or disables privileges in a specified access token.
 
.PARAMETER Privilege
    The privilege to adjust. This set is taken from
    http://msdn.microsoft.com/en-us/library/bb530716(VS.85).aspx
 
.PARAMETER $ProcessId
    The process on which to adjust the privilege. Defaults to the current process.
 
.PARAMETER Disable
    Switch to disable the privilege, rather than enable it.
 
.EXAMPLE
    Set-LHSTokenPrivilege -Privilege SeRestorePrivilege
 
    To set the 'Restore Privilege' for the current Powershell Process.
 
.EXAMPLE
    Set-LHSTokenPrivilege -Privilege SeRestorePrivilege -Disable
 
    To disable 'Restore Privilege' for the current Powershell Process.
 
.EXAMPLE
    Set-LHSTokenPrivilege -Privilege SeShutdownPrivilege -ProcessId 4711
 
    To set the 'Shutdown Privilege' for the Process with Process ID 4711
 
.INPUTS
    None to the pipeline
 
.OUTPUTS
    System.Boolean, True if the privilege could be enabled
 
.NOTES
    to check privileges use whoami
    PS:\> whoami /priv
 
    PRIVILEGES INFORMATION
    ----------------------
 
    Privilege Name                Description                          State
    ============================= ==================================== ========
    SeShutdownPrivilege           Shut down the system                 Disabled
    SeChangeNotifyPrivilege       Bypass traverse checking             Enabled
    SeUndockPrivilege             Remove computer from docking station Disabled
    SeIncreaseWorkingSetPrivilege Increase a process working set       Disabled
 
 
    AUTHOR: Pasquale Lantella
    LASTEDIT:
    KEYWORDS: Token Privilege
 
.LINK
    http://www.leeholmes.com/blog/2010/09/24/adjusting-token-privileges-in-powershell/
 
    The privilege to adjust. This set is taken from
    http://msdn.microsoft.com/en-us/library/bb530716(VS.85).aspx
 
    pinvoke AdjustTokenPrivileges (advapi32)
    http://www.pinvoke.net/default.aspx/advapi32.AdjustTokenPrivileges
 
#Requires -Version 2.0
#>
 
[cmdletbinding(
    ConfirmImpact = 'low',
    SupportsShouldProcess = $false
)]
 
[OutputType('System.Boolean')]
 
Param(
 
    [Parameter(Position=0,Mandatory=$True,ValueFromPipeline=$False,HelpMessage='An Token Privilege.')]
    [ValidateSet(
        "SeAssignPrimaryTokenPrivilege", "SeAuditPrivilege", "SeBackupPrivilege",
        "SeChangeNotifyPrivilege", "SeCreateGlobalPrivilege", "SeCreatePagefilePrivilege",
        "SeCreatePermanentPrivilege", "SeCreateSymbolicLinkPrivilege", "SeCreateTokenPrivilege",
        "SeDebugPrivilege", "SeEnableDelegationPrivilege", "SeImpersonatePrivilege", "SeIncreaseBasePriorityPrivilege",
        "SeIncreaseQuotaPrivilege", "SeIncreaseWorkingSetPrivilege", "SeLoadDriverPrivilege",
        "SeLockMemoryPrivilege", "SeMachineAccountPrivilege", "SeManageVolumePrivilege",
        "SeProfileSingleProcessPrivilege", "SeRelabelPrivilege", "SeRemoteShutdownPrivilege",
        "SeRestorePrivilege", "SeSecurityPrivilege", "SeShutdownPrivilege", "SeSyncAgentPrivilege",
        "SeSystemEnvironmentPrivilege", "SeSystemProfilePrivilege", "SeSystemtimePrivilege",
        "SeTakeOwnershipPrivilege", "SeTcbPrivilege", "SeTimeZonePrivilege", "SeTrustedCredManAccessPrivilege",
        "SeUndockPrivilege", "SeUnsolicitedInputPrivilege")]
    [String]$Privilege,
 
    [Parameter(Position=1)]
    $ProcessId = $pid,
 
    [Switch]$Disable
   )
 
BEGIN {
 
    Set-StrictMode -Version Latest
    ${CmdletName} = $Pscmdlet.MyInvocation.MyCommand.Name
 
## Taken from P/Invoke.NET with minor adjustments.
 
$definition = @'
 using System;
 using System.Runtime.InteropServices;
 
 public class AdjPriv
 {
  [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
  internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);
 
  [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
  internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);
 
  [DllImport("advapi32.dll", SetLastError = true)]
  internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);
 
  [StructLayout(LayoutKind.Sequential, Pack = 1)]
  internal struct TokPriv1Luid
  {
   public int Count;
   public long Luid;
   public int Attr;
  }
 
  internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
  internal const int SE_PRIVILEGE_DISABLED = 0x00000000;
  internal const int TOKEN_QUERY = 0x00000008;
  internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
 
  public static bool EnablePrivilege(long processHandle, string privilege, bool disable)
  {
   bool retVal;
   TokPriv1Luid tp;
   IntPtr hproc = new IntPtr(processHandle);
   IntPtr htok = IntPtr.Zero;
   retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
   tp.Count = 1;
   tp.Luid = 0;
   if(disable)
   {
    tp.Attr = SE_PRIVILEGE_DISABLED;
   }
   else
   {
    tp.Attr = SE_PRIVILEGE_ENABLED;
   }
   retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid);
   retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
   return retVal;
  }
 }
'@
 
 
 
} # end BEGIN
 
PROCESS {
 
    $processHandle = (Get-Process -id $ProcessId).Handle
 
    $type = Add-Type $definition -PassThru
    $type[0]::EnablePrivilege($processHandle, $Privilege, $Disable)
 
} # end PROCESS
 
END { Write-Verbose "Function ${CmdletName} finished." }
 
} # end Function Set-LHSTokenPrivilege
 
$Privs =  "SeAssignPrimaryTokenPrivilege", "SeAuditPrivilege", "SeBackupPrivilege",
 
        "SeChangeNotifyPrivilege", "SeCreateGlobalPrivilege", "SeCreatePagefilePrivilege",
 
        "SeCreatePermanentPrivilege", "SeCreateSymbolicLinkPrivilege", "SeCreateTokenPrivilege",
 
        "SeDebugPrivilege", "SeEnableDelegationPrivilege", "SeImpersonatePrivilege", "SeIncreaseBasePriorityPrivilege",
 
        "SeIncreaseQuotaPrivilege", "SeIncreaseWorkingSetPrivilege", "SeLoadDriverPrivilege",
 
        "SeLockMemoryPrivilege", "SeMachineAccountPrivilege", "SeManageVolumePrivilege",
 
        "SeProfileSingleProcessPrivilege", "SeRelabelPrivilege", "SeRemoteShutdownPrivilege",
 
        "SeRestorePrivilege", "SeSecurityPrivilege", "SeShutdownPrivilege", "SeSyncAgentPrivilege",
 
        "SeSystemEnvironmentPrivilege", "SeSystemProfilePrivilege", "SeSystemtimePrivilege",
 
        "SeTakeOwnershipPrivilege", "SeTcbPrivilege", "SeTimeZonePrivilege", "SeTrustedCredManAccessPrivilege",
 
        "SeUndockPrivilege", "SeUnsolicitedInputPrivilege"
 
        foreach ($i in $Privs){
         Set-LHSTokenPrivilege -Privilege $i
        }

This script contains a function that allows users to enable or disable a specific privilege for a given process. The function takes in two parameters, the privilege to modify and the process ID, and an optional switch to disable the privilege.

Calling this script surely would alter the user’s privileges.

I looked up further and the Set-LHSTokenPrivilege.ps1 script is mostly used for red-teaming