CubeCTF 2025

Solutions for 10 questions (out of 13 with at least 1 solve). Also advertisement for https://krauq.ai.

Misc

Is this stego? (165 solves)

Description:

Someone was asking us for a stego challenge, hopefully this is what they were looking for.

Flag format: cube{LAT,LON} with only two digits after the decimal point.

e.g. cube{12.34,-56.78}

Author: @rdj & @ski

Resources:

Attachment

Solution:

Google search by image finds many images with the location, all the results are instagram though. A trick for these OSINT is to resize the search section to get more results.

Eventually it can be narrowed down by a few things like Chile, cable cars, etc., many ways to find.

On release, flag was cube{-33.41,-70.61} but I think they fixed it to also accept cube{-33.41,-70.62}.

Fairly Basic Programming Assignment (105 solves)

Description:

We wanted the intern to learn how to code... but we're not quite sure what he did here. Can you make any sense of what it does?

Note: the flag format for this challenge is USCGCTF{EX4MPLE_FL4G}

Authors: @samwise and @arcticx

Resources:

Attachment

Solution:

Paste in to krauq.ai for one-shot solve. Needed to ask a few times though

Web

Description:

We got hungry writing this challenge...

http://legalsnacks.chal.cubectf.com:5000

Author: @outwrest

Resources:

Attachment

Solution:

This is the freebie of the competition, worth only 100 points. The below script generated by AI solves it.

Todo (55 solves)

Description:

I'm sure at some point we'll get around to finishing this one...

http://todo.chal.cubectf.com:1337

Authors: @quasar098, @jakesss_ and @downgrade

Resources:

Attachment

Solution:

I don't specialize in web so here's a writeup assisted by AI.

This challenge involves chaining two vulnerabilities:

  1. Django-Unicorn class pollution vulnerability (CVE-2025-24370)

  2. Command injection in the application's home route

The exploitation requires polluting Python runtime settings to redirect a curl command that leaks the flag.

File Structure

After extracting the provided zip file, we find:

Key Findings from Dockerfile

Important observations:

  • Uses django-unicorn==0.60.0 (vulnerable version)

  • Flag is copied to /tmp/flag.txt

  • Application runs on port 1337

1. Command Injection Vulnerability

In myproject/urls.py:

The home() function executes a system command with settings.CONTACT_URL interpolated directly into the command string. This runs every time someone visits the homepage.

2. Django-Unicorn Class Pollution (CVE-2025-24370)

Research reveals that Django-Unicorn 0.60.0 is vulnerable to CVE-2025-24370:

  • CVSS Score: 9.3 (Critical)

  • Type: Python class pollution

  • Impact: Allows remote modification of Python runtime objects

  • Fixed in: Version 0.62.0

The vulnerability exists in the set_property_value function, which can be exploited by crafting requests with special property paths like __init__.__globals__.

Django-Unicorn Component

The todo component (myproject/components/todo.py):

Frontend Integration

The application uses Django-Unicorn's reactive components to handle the todo list functionality. When visiting the homepage, we can see the Unicorn component data in the HTML:

The attack chain:

  1. Use Django-Unicorn's class pollution to modify settings.CONTACT_URL

  2. Change it from the default https://example.com to our controlled server

  3. Trigger the command injection by visiting the homepage

  4. Receive the flag content via the curl command

1. Create a Webhook Listener

Using ngrok to create a public endpoint:

This provides a URL like: https://5f9b-185-245-87-188.ngrok-free.app

2. Create the Exploit Script

Run the exploit:

Expected output:

The flag will appear in your ngrok interface as a GET request with the flag content in the body. The executed command is:

Race Condition

  • The pollution affects the global Python runtime

  • Only one person can receive the flag at a time

  • The last person to pollute settings.CONTACT_URL will receive all subsequent flags

  • The pollution persists until the server restarts

Why the Flag Keeps Coming

Once polluted, every visit to the homepage triggers the command injection, including:

  • Other players visiting the site

  • Health checks or monitoring

  • Search engine crawlers

Django-Unicorn Request Flow

  1. The frontend sends AJAX requests to /unicorn/message/todo

  2. The actionQueue contains syncInput actions that update component properties

  3. The vulnerability allows property paths to escape the component scope

Class Pollution Path

The magic happens with this path:

Breaking it down:

  • __init__: Access the component's initializer

  • __globals__: Access the global namespace

  • sys.modules: Python's module cache

  • django.conf.settings: Django's settings object

  • CONTACT_URL: The specific setting we want to modify

To prevent this vulnerability:

  1. Update Django-Unicorn to version 0.62.0 or later

  2. Never interpolate user-controllable data into system commands

  3. Use subprocess with proper argument lists instead of system()

  4. Implement input validation for all user inputs

Rev

Gnisrever (30 solves)

Description:

Normally you get a binary and have to reverse engineer it. That sounds like a lot of work. Instead, this time you give us a binary and we do the reversing for you.

nc gnisrever.chal.cubectf.com 5000

Author: @B00TK1D

Resources:

Attachment

Solution:

First, here's how the solution looks like:

So after solving the PoW, the challenge only allows you to submit flat binaries of up to 100 lines whose bytes, when reversed line-wise and then having their line order reversed (rev | tac), remain exactly the same, and which print the flag on stdout. The trick is to write a tiny shell-script in raw bytes that runs printenv (dumping the entire environment, including the flag) and mirror each line so the reversal yields the identical script. Below is how the script was created.

Numba One (13 solves)

Description:

Snake lang best lang.

Flag format is cube{[0-9a-z_]+}

Authors: @flocto and @oh_word

Resources:

Attachment

Solution:

Initially I had a solve script that decrypts in pairs but it would have taken at least like 10 hours to finish decrypting even after optimization. I was tempted to just leave it running overnight. Handles interruptions and can resume progress. Here's the script for reference.

Here's the actual solve script after reversing the logic (decompiled the .so and a lot of AI analysis). Solves instantly. Need to run with python 3.13.

Then manually fix the PNG header (many ways to do such as adding it back in a hex editor).

Crypto

Incantation (52 solves)

Description:

While walking through a meadow, you find a magical book on the ground. The letters seem to be dancing off the page, dancing to a rhythm of a song you used to know, but you can't quite make them out.

nc incantation.chal.cubectf.com 5757

Author: @B00TK1D

Resources:

Attachment

Solution:

I think it's just correct letters show up more often than not or something? Solve script below.

Elementary (31 solves)

Description:

I made a calculator for elementary students. I made sure it can only do basic operations, so it should be safe.

nc elementary.chal.cubectf.com 3456

Author: @B00TK1D

Resources:

Attachment

Solution:

Solve script below.

Forensics

Operator (113 solves)

Description:

I think someone has been hiding secrets on my server. Can you find them?

Author: @B00TK1D

Resources:

Attachment

Solution:

Stage
What was in the capture
What I did

1 โ€“ Recon

Port-2025 traffic (โ‰ˆ17 KB) delivering a file called xcat with nc -lvp 2025 > /tmp/xcat.

Re-assembled the TCP stream and saved the ELF.

2 โ€“ Binary review

xcat is a tiny net-cat look-alike. Symbols (run_server, run_client, chat, xor_encrypt) and a 16-byte key at .data:0x4010.

Found the XOR key: 04 07 17 76 42 69 b0 0b de 18 23 22 1e ed f7 ae.

3 โ€“ Second stage traffic

Another stream between 5.161.100.25:2025 โ†” 5.161.95.137:53930 (244 B).

De-segmented the stream, then XOR-decrypted each packet with the key, resetting at each packet (matching how chat() calls xor_encrypt()).

4 โ€“ Result

Clear-text dialogue containing the flag.

Extracted the flag string above.

Discord (64 solves)

Description:

I got a really awesome picture from my friend on Discord, but then he deleted it! I asked someone for a program that could get those pictures back, but when I ran it, all it did was close Discord! Send help, I need that picture back!

NOTE: The flag format for this challenge is uscg{.*}.

Authors: @poke_player and @ajmeese7

Resources:

Download the disk image here: link

Solution:

Tired of writeups now and authors released writeup for everything so here it is quick and simple. First extract with FTK Imager, find the encrypt binary in downloads, unpack with pyinstxtractor, decode pyc (can use pylingual or krauq.io), then build solve script.

Last updated

Was this helpful?