TryHackMe TOC2 Report

A web developer has taken a break from installing a CMS onto their web server.  As the attacker, we can use exposed credentials and database info to poison a config file during the CMS install, allowing for RCE (remote code execution). 

An interactive reverse shell is achieved with the low-privileged www-data user; horizontal privilege escalation to the Frank user is possible due to poor password strength.  Privilege escalation to the root user is possible due to a File Path Race Condition vulnerability. Also linked in the Tryhackme room is a video from LiveOverflow describing the race condition:

  • Port 22, ssh
    • No obvious usernames or possible passwords to brute force; skip for now
  • Port 80, http

The home page for the web server exposes what looks like web developer credentials, cmsmsuser:devpass:

Nmap’s default scripts show /robots.txt and a disallowed entry: /cmsms/cmsms-2.1.6-install.php

In addition to a cmsms install page, there’s also a note exposing the database name, cmsmsdb

There seems to be a public exploit available for this particular version of cmsms 2.1.6. (

To summarize the exploit:

  • the http request for step 4 of the installation can be intercepted and modified with malicious php, poisoning the cmsms config.php file.
  • after installation is complete, the malicious php can be executed by navigating to http://target/cmsms/config.php



Step four of the install requires the database name, and a valid username and password. All these parameters were found previously by enumerating the web server.  

  • database name: cmsmsdb
  • username: cmsmsuser
  • passowrd: devpass

Per the public exploit, this packet should be intercepted with Burp Proxy and the timezone parameter modified with malicious php as follows:

The payload for the timezone parameter is:


Step 5 of the installation is creating an Admin user; this can be anything and it won’t affect the vulnerability. 

Continue until installation is complete.

Once completed, navigate to the poisoned config.php file to execute the malicious php, specifying a cmd GET parameter who’s value is the system command to be executed. 



A bash one-liner can be specified to achieve a reverse shell.  I had to url-encode the payload or else it would fail.  



The user flag is in /home/frank/user.txt, which is readable to the www-data user:

The note on Frank’s home folder says the new machine he acquired has a weak password, and the current machine we are on also has a weak password.

With this information, an SSH session as Frank can be authenticated.

In Frank’s home folder there is a directory named root_access, with a password backup file for the root user, and a readcreds program including its source code.    The readcreds program is owned by root and also has the SUID bit set, so it will run as the root user, but it fails to read the password backup. 

Reading the source code: it checks to see if we have read access to the file path specified in argv[1]. If so, then it sleeps for 1 second before reading that same file path.

This is vulnerable to a file path race condition. After the access check, there is a one-second window of opportunity where the same file path could point to a different file, and the readcreds binary would read that file, even if it was previously unreadable.

To accomplish this, a symlink will be used, and also a program that swaps the names of two files constantly (a rename program is linked in the TryHackMe hint). 

    • First, create a file that can be read. Call this swag.txt.
    • Next, create a symlink to the unreadable root_password_backup file called pwbak.txt. Reading pwbak.txt will fail, even though it shows the owner as ‘Frank’.
    • Then, start the name-swapping program and it will constantly switch between pwbak.txt and swag.txt, linking to the password backup.
    • Finally, run the readcreds program; it doesn’t matter if pwbak.txt or swag.txt is read. This will succeed if the perfect conditions are met:
      the access check determines swag.txt readable
      after 1 second, the filepath is now pwbak.txt, linking to the password backup, and contents are read

In the screenshots, both pwbak.txt and swag.txt were passed to the readcreds program. By chance, it took 4 tries with pwbak.txt and 9 tries with swag.txt


Switch to the root user and read the root flag

Leave a Reply