Hammer TryHackMe Writeup | Beginner Friendly → SuNnY
Room Objectives
The “Hammer” room on TryHackMe is a Capture The Flag (CTF) challenge that typically involves bypassing authentication and achieving Remote Code Execution (RCE) to obtain two objective as flags.
Let’s Start !
Grab Yourself a Hot cup of Coffee , Milkshake , Oreo Shake 😋 , Frappuccino 😃 , Orange Juice , Beetroot Juice 🤢
This Walkthrough has some miles !
Nmap Scan
Let’s start with scanning all ports
We find two ports in Open State : 22 and 1337
Let’s check what we find on port 1337
There is a login page @ port 1337 and we don’t really know the username and password , using default credentials like — admin:admin , admin:password , etc — were of no use and returned as login failure
On further inspecting the Page and going to the Storage Section we found the cookie that might be useful for a later stage
PHPSESSID Value : datlnccflgrmhqc9d5pkb6b8a7
We now know how to check the Cookie ID/SessionID Value ,
This process will be useful in the coming steps
Let’s try clicking on Forgot your Password?
We are redirected to a new page → /reset_password.php , in order to reset the password we need to have an email id Let ‘s go back to the login page and Check the framework by checking the page source
( Ctrl + U )
Sweet ! we found that the Directory naming convention must be hmr_DIRECTORY_NAME
Time to Brute-Force the Directory by fuzzing
ffuf scan command :
I have used the SecList from danielmiessler -GitHub
But you can also use this command →
ffuf -u 'http://hammer.thm:1337/hmr_FUZZ' -w /usr/share/wordlists/seclists/Discovery/Web-Content/raft-medium-directories.txt -mc 200,301
We have found 4 directories →
Let’s check Logs
http://hammer.thm:1337/hmr_logs
We find error.logs file in /hmr_logs/
Nice ! We found an email address inside the directory → /hmr_logs/error.logs
email id found : tester@hammer.thm
Let’s Head back to the login page @ port 1337 and try resetting the password using the email id we just found
After submitting the reset request for email id — tester@hammer.thm
we find that we are being redirected to an OTP based recovery code to in order to reset the password .
Since we need to reset the password we have to enter 4-Digit Recovery code , in order to attempt for all the 4 digit codes our maximum entries could be not more than 9999 for a 4 digit code and minimum can be 0000 also being a 4 digit code
We need to create a wordlist from 0000 to 9999
Here we will use the command seq ( Sequence command )
This will generate a wordlist file from 0000 to 9999 and would help us guess the recovery code for the password reset . Let’s name this wordlist as → codes
seq 0000 9999 >> codes.txt
The file codes.txt that we created using seq command has generated us a wordlist from 0000 to 9999 ( Total 10000 characters )
Let’s now use the wordlist that we created above to guess the right 4 Digit recovery code by firing each one individually by Brute-forcing using the ffuf command
Let’s prepare our payload first
Things we have to keep in mind :
1) As we saw @ the password reset page → we are only given 180 seconds to input the 4 digits recovery code , we need to override this limit because Brute-forcing 10000 digits can take a while to successfully find us the right combination for the 4-digit .
we will be using the command flag with ffuf → X-Forwarded-For
This will act as a Rate-Limit ByPass
Reference : HackTricks (Link)
Do Note : This can also be used with Burp Suite Method
2) We will be needing the cookie ( PHPSSESID ) that we found earlier
Let’s Prepare our Payload
ffuf -w codes.txt -u “http://hammer.thm:1337/reset_password.php" -X “POST” -d “recovery_code=FUZZ&s=60” -H “Cookie: PHPSESSID=Cookie-ID” -H “X-Forwarded-For: FUZZ” -H “Content-Type: application/x-www-form-urlencoded” -fr “Invalid” -s
Breakdown of the above command :
-w codes.txt
: Specifies the wordlist (codes.txt
) that will be used for fuzzing. This wordlist contains the payloads that will replace theFUZZ
keyword in the command.-u "http://hammer.thm:1337/reset_password.php"
: The URL of the target web application. This is where the fuzzing request will be sent.-X "POST"
: Specifies the HTTP method to be used, which in this case isPOST
.-d "recovery_code=FUZZ&s=60"
: The data being sent in the body of the POST request. TheFUZZ
keyword here will be replaced with each entry fromcodes.txt
during the fuzzing process. It appears that the fuzzing is targeting therecovery_code
parameter.-H "Cookie: PHPSESSID=datlnccflgrmhqc9d5pkb6b8a7"
: Adds a custom header to the request, specifically aCookie
header with a session ID. This is likely needed to maintain a session with the web application.-H "X-Forwarded-For: FUZZ"
: Adds another custom header,X-Forwarded-For
, which is often used to identify the originating IP address of a client connecting to a web server. In this case, it's being fuzzed to see if the application behaves differently based on the IP address.-H "Content-Type: application/x-www-form-urlencoded"
: Specifies the content type of the data being sent. This is typical for form submissions.-fr "Invalid"
: Filters out responses that contain the string"Invalid"
. This helps in identifying successful or interesting responses that differ from the common invalid ones.-s
: Runsffuf
in silent mode, which reduces the amount of output to only essential information.
Let’s Fire it up 🔥
We know that we have 180 seconds to input the new 4 digit recovery key .
lets prepare our payload and leave space for the cookie header section .
Then head back to the password reset page and quickly grab the new cookie ID and paste it into our payload and then execute it .
We have to do this under 180 seconds other wise a new cookie ID will be generated . After successfully executing the payload we will get the 4 Digit recovery code to reset our password
For making it easier i have added snippets of video to this writeup for you to follow
Let’s prepare our payload leaving the space for cookie ID and then we go to the reset password page and get the new cookie ID value and use it in our payload to launch the brute force attack ( We have 180 seconds to do this )
We got our recovery code by running the command with the new Cookie ID , when we enter the 4 digit code that we brute forced we get redirected to the reset your password page for setting a new password
Do note : The Recovery code that i found , may not be similar to yours
You can either enter the password recovery code or refresh the page .
We can now reset our password to any thing we want to
Here we are going to set it to 1234
After setting the password to 1234 , we can see that the page redirects us back to the login page but with /index.php this time .
Let’s login using the email id — tester@hammer.thm and password — 1234 that we just reset
Voila ! We can see that we can now successfully login to the user account for whom the password we have just reset .
Congratulations we found our first flag ! Well Done !
Finding the Second Flag
By successfully login in we got our first flag
If we inspect the page thoroughly we can see there is a search box which says enter command .
Let’s try entering the command — ls
Once we use the command ls we can see the return entries
188ade1.key
composer.json
config.php
dashboard.php
execute_command.php
hmr_css
hmr_images
hmr_js
hmr_logs
index.php
logout.php
reset_password.php
vendor
The first entry seems kind of interesting = 188ade1.key
Let’s try to read the contents of this file by using the command cat
Whoops , the command cat is disabled and the output says —
command not allowed
We somehow have to find a way to check the contents of the file — 188ade1.key
Let’s check other options
Let’s try to explore using the page source — Ctrl+U |
By doing a view page source we find one thing interesting
There is a jwtToken found inside of the script ,
We have to find a way to decode the token , Let’s explore !!
let’s ask our trusty friend Mr. Google
There are a lot of results , but we will go with the first one
Let’s paste the jwt Token and check the results
There is a need to input a 256 bit secret code for signature verification
Let’s use the 256 bit secret key we found inside the file → 188ade1.key
We find one interesting clue while trying to decode the jwt Token →
By decoding the Token we find that the key location is →
/var/www/mykey.key
earlier we have found a key name — 188ade1.key by using ls command .
Which means this key is uploaded in /var/www/html →
Since the key is saved on the /var/www/html , we can directly open the file with the filename on the index page using it as a directory and down load it to our VM —
Let’s open the file 188ade1.key to check the contents , we can’t open this file directly on Kali or Linux . To view the contents we have to install Office Libre ( This comes pre-installed in some Linux-Based-Distro )
To install Libre Office use the same command →
sudo apt install libreoffice libreoffice-gtk4
On Opening the file we found the key →
56058354efb3daa97ebab00fabd7a7d7
Now let’s use this key as the 256 bit secret key
After entering the secret key we see that the signature gets verified
Question for Flag 2 : What is the content of the file /home/ubuntu/flag.txt?
To access sensitive data like a flag , we always have to have high privileges , the role is set to user , so Let’s try changing the role from user to admin .
( Verifying the signature is needed in order to manipulate the jwt Token )
After changing the role from user to admin , the token get manipulated .
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6Ii92YXIvd3d3L2h0bWwvMTg4YWRlMS5rZXkifQ.eyJpc3MiOiJodHRwOi8vaGFtbWVyLnRobSIsImF1ZCI6Imh0dHA6Ly9oYW1tZXIudGhtIiwiaWF0IjoxNzI1MzE0MzAzLCJleHAiOjE3MjUzMTc5MDMsImRhdGEiOnsidXNlcl9pZCI6MSwiZW1haWwiOiJ0ZXN0ZXJAaGFtbWVyLnRobSIsInJvbGUiOiJhZG1pbiJ9fQ.YKBqC22iD4G-jXjjD9Y5j6mLjb62ZhR9b-un-8waUS4
Since we have successfully changed our user to admin , now we can directly use the token to login as admin
Login back into the dashboard then Using Burp Suite to intercept the command and replacing the JWT Token as admin and then using cat /home/ubuntu/flag.txt →
We get our Flag for the second Task
Room Done !
Flags