Arbitrary File Deletion & Local PrivEsc with Symlinks
Symlinks zijn uiteraard handig als een verwijzing naar een een bestand op een andere locatie. Maar in Windows kunnen we meer met symlinks waardoor ze ook interessant kunnen zijn voor local privilege escalation. In Windows bestaan meerdere manieren om bestanden en paden aan elkaar te koppelen. Dat kan via symlinks, hardlinks, speciale registerkoppelingen en object manager symlinks. Dit klinkt technisch, maar het idee is simpel: je zorgt dat een proces dat met hoge rechten draait per ongeluk een bestand van jou gaat aanmaken of overschrijven. Zo kun je SYSTEM-rechten krijgen. In deze blog leg ik je uit hoe dit werkt en waarom dit type aanval lastig te voorkomen is.
Wat is een symlink?
Een symlink is een soort “snelkoppeling”. Een symlink is een verwijzing naar een ander pad. Let op, een symlink is geen “snelkoppeling”. Een snelkoppeling is een bestand met de extensie .lnk dat dient als een verwijzing naar een ander bestand, map of programma. Het is een door Windows beheerd mechanisme om snel toegang te krijgen tot een doel. Een snelkoppeling is geen directe link op bestandssysteemniveau. Het is een apart bestand dat metadata bevat, zoals het pad naar het doelbestand, pictogram en andere eigenschappen (bijv. sneltoetsen of venstergrootte). Een symlink daarintegen is een geavanceerde link op bestandssysteemniveau (NTFS) welke een bestand of map “spiegelt” naar een andere locatie. Symlinks worden ondersteund door het NTFS-bestandssystemen en werken transparant voor de meeste toepassingen. Een symlink gedraagt zich alsof het het originele bestand of de originele map is. Wanneer een programma een symlink opent, wordt het automatisch doorgestuurd naar het doelbestand of de doellocatie.
Windows kent meerdere vormen symlinks:
NTFS symlink
Dit is een bestand dat verwijst naar een ander bestand of een andere map. Je maakt hem met “mklink”.
mklink C:\Users\Public\fake.txt C:\Windows\System32\drivers\etc\hosts |
Hardlink
Een hardlink koppelt twee bestandsnamen direct aan dezelfde data op schijf. Als je de ene naam wist, blijft de andere bestaan. Hardlinks werken alleen binnen één volume. Je maakt een hardlink op de volgende manier:
fsutil hardlink create C:\Users\Public\hard.txt C:\Windows\System32\license.rtf |
Registry Symbolic Link
Het Windows-register ondersteunt ook links. Zo kun je registersleutels aan elkaar koppelen:
reg.exe add HKLM\Software\Classes\CLSID\{GUID}\SymbolicLinkValue /v SymbolicLink /t REG_LINK /d \Registry\Machine\OtherKey |
Object Manager Symlink
Windows gebruikt een interne “Object Manager Namespace”. Je kunt daarin een symlink maken naar apparaten, pipes of andere objecten. Deze symlinks worden vaak misbruikt voor kwetsbaarheden. Een “Object Manager Symlink” koppel je aan een pad als \GLOBAL??\C:\…. Zo leid je processen om naar andere objecten.
DefineDosDevice /d /r /s C: \??\C:\Windows\System32 |
Waarom zijn symlinks gevaarlijk?
Veel services draaien als SYSTEM. Stel dat zo’n service een logbestand schrijft in een map die voor iedereen toegankelijk is, zoals “C:\ProgramData\log.txt”. Als we dit logbestand vervangen door een symlink naar bijvoorbeeld “C:\Windows\System32\drivers\etc\hosts” dan zal de service dus zijn logs wegschrijven in dit “hosts” bestand.
Door deze toegankelijk bestanden te manipuleren kunnen we dus systeemgedrag beïnvloeden.
Hoe ontdek je of een service kwetsbaar is?
1. Het eerste wat we moeten monitoren is toegang tot bestanden. Met tools zoals ProcMon kun je filteren op processen die als SYSTEM draaien. Kijk waar ze bestanden aanmaken of overschrijven.
2. Vervolgens moeten we onze toegangsrechten controleren. Ga na of we in deze mappen mogen schrijven en verwijderen. Dit kunnen we doen met icacls of via Get-ACL in PowerShell:
Get-Acl C:\ProgramData\AppLogs\ |
3. Dan verwijderen we het bestand en maken we een NTFS symlink aan:
del C:\ProgramData\AppLogs\service.log mklink C:\ProgramData\AppLogs\service.log C:\Windows\System32\license.rtf |
4. Vervolgens testen we wat er gebeurt als we een bestand verwijderen. Sommige services maken het bestand automatisch opnieuw aan. Dit geeft ons de kans een symlink te plaatsen.
Sommige applicaties weigeren NTFS symlinks. In dat geval kunnen we, als de bron en het doel op hetzelfde volume staan proberen een hardlink te gebruiken. Hardlinks hebben het voordeel dat ze door veel oudere API’s niet herkend worden als link. Dit maakt detectie lastiger.
fsutil hardlink create C:\ProgramData\AppLogs\service.log C:\Windows\System32\license.rtf |
Arbitrary File Deletion – Attack
1. In dit voorbeeld is er een Windows service welke periodiek een bestand verwijderd. In dit voorbeeld een logfile, namelijk: C:\Temp\abc\file.txt. We hebben alle rechten op deze folder.
2. We willen het bestand “C:\Windows\controlled.txt” verwijderen maar hebben hier geen toegang toe.
3. We kunnen nu een “Object Manager symbolic link” maken van “\RPC Control\file.txt” naar C:\Windows\Controlled.txt.
CreateSymlink.exe "\RPC Control\file.txt" "\??\C:\Windows\controlled.txt" |
4. Dan verwijderen we alle bestanden uit “C:\Temp\abc”:
del /Q C:\Temp\abc\* |
5. En dan maken we een NTFS Mount Point van C:\Temp\abc naar \RPC Control. Dit kan niet met Windows standaard tools, maar kan wel met SetSymlink.exe:
SetSymlink.exe C:\Temp\abc \RPC Control |
6. Op het moment dat de Windows service zijn verwijdertaak gaat uitvoeren (DeleteFile()) op het bestand C:\Temp\abc\file.txt dan zal deze via de “Object Manager symbolic link” verwijzen naar \RPC Control. Dus wordt \RPC Control\file.txt benaderd wat ook een symbolische link is en verwijst naar “C:\Windows\controlled.txt”. Hierdoor volgt de service twee symbolische links en verwijdert in plaats van het gewenste C:\Temp\abc\file.txt het bestand C:\Windows\controlled.txt.
Naast “Arbitrary File Deletion” kun je ook te maken krijgen met bepaalde kopieerbewerkingen, het aanmaken van bestanden, het verplaatsen van bestanden of het overschrijven van bestanden. Hier diverse voorbeelden:
- CVE-2024–26238 – Windows 10 PlugScheduler EOP. Arbitrary Create;
- CVE-2024–12754 – AnyDesk LPE. Arbitrary Copy;
- CVE-2024–37726 – MSI Center Arbitrary File Overwrite Vulnerability;
- CVE-2024–21111 – Oracle VirtualBox LPE;
- CVE-2020–1076 – Arbitrary file write in VaultSvc.
Privilege escalation – Attack
Zoals je in bovenstaande link kunt lezen kunnen we in sommige gevallen ook privilege escalation verkrijgen via symlinks. Om dit te doen gaan we ervan uit dat de service een DLL aanroept vanuit een folder waar we toegang toe hebben om bestanden te schrijven en verwijderen. We hebben echter geen rechten om de DLL te verwijderen. Wanneer de service ook logbestanden maakt en/of verwijderd kunnen we via bovenstaande “Arbitrary File Deletion” een symlink maken om de DLL te verwijderen. Daarna plaatsen we onze eigen DLL met malicious code welke bij de volgende service-reboot wordt geladen en uitgevoerd.:
Stap voor stap volgt dit dus het volgende proces:
1. Je hebt schrijfrechten op een directory waar de service logbestanden weggooit. De service laadt een DLL in welke we qua rechten niet kunnen overschrijven, bijvoorbeeld:
C:\Program Files\VulnerableService\service.dll |
We hebben deze informatie gevonden via een tool als ProcMon.
2. Nu moeten we controleren of we wel schrijfrechten hebben in deze folder:
icacls "C:\ProgramData\VulnerableService" |
3. Verwijder de logs:
del "C:\ProgramData\VulnerableService\logs\*" /Q |
4. Link het “logbestand” naar de doel-DLL:
mklink /D \\?\GLOBALROOT\RPC Control\log1.txt C:\Program Files\VulnerableService\service.dll #Of CreateSymlink.exe "\RPC Control\log1.txt" "\??\C:\Program Files\VulnerableService\service.dll" |
5. Trigger de service om de log te verwijderen. Nu is het wachten tot de logfile verwijderd wordt waardoor uiteraard de beveiligde DLL verwijderd wordt. Als je het recht hebt om de service handmatig te rebooten kan dat ook helpen:
sc stop VulnerableService sc start VulnerableService |
6. Nu zetten we onze malicious DLL terug.
copy C:\Users\attacker\evil.dll "C:\Program Files\VulnerableService\service.dll" |
7. Om de DLL in te laden als SYSTEM moeten we weer wachten, de service rebooten als we hier rechten toe hebben of simpelweg de machine rebooten.
Hoe verdedig je hiertegen?
Er zijn een paar manieren om deze aanval te voorkomen:
- Laat services niet in mappen schrijven die voor iedereen toegankelijk zijn.
- Controleer of een bestand een symlink is. Dit kan met “GetFileAttributes”.
- Gebruik veilige API’s die geen symlinks volgen.
- Geef mappen strengere ACL’s zodat normale gebruikers geen bestanden mogen verwijderen.
Conclusie
Symlinks, hardlinks en object manager symlinks zijn krachtig. Veel Windows-processen letten niet goed op als ze bestanden openen of aanmaken. Als je weet waar je moet zoeken, kun je SYSTEM-processen misleiden en local privilege escalation verkrijgen. Dit is weer een mooie red-team techniek waar slecht op gemonitored wordt en mogelijk verstrekkende gevolgen heeft.