Description
A Unity game walls you in with invisible boundaries. The flag is readable with strings, or you can use dnSpy to modify the game assembly and unlock infinite jumping to fly over the wall.
Setup
Download and unzip the game.
wget https://artifacts.picoctf.net/c/504/no-way-out.zip && unzip no-way-out.zipSolution
Want to try it yourself first?
The guided walkthrough reveals hints one step at a time.
Step 1
Fast path: strings on the level dataObservationI noticed the game is a Unity build with a *_Data/ folder containing binary level files, which suggested that scene text objects like a displayed flag would be stored as plain strings in level0 and could be extracted without ever running the game.Unity games store scene data including text objects in the level data files. Running strings on the level0 file reveals the flag directly without running the game at all.bashstrings 'no-way-out_Data/level0' | grep -i 'WELCOME\|picoCTF'bashstrings 'no-way-out_Data/level0'Expected output
picoCTF{WELCOME_TO_UNITY!!}What didn't work first
Tried: Running strings on the main game executable instead of the level data file.
The executable itself (no-way-out.exe or the Linux binary) contains engine code and startup logic but not scene assets. Scene text objects are serialized into the level0 binary inside no-way-out_Data/, so strings on the wrong file produces thousands of engine symbol names with no flag present.
Tried: Using grep -i 'picoctf' without also grepping for 'WELCOME' or checking the raw strings output.
The flag text 'WELCOME_TO_UNITY!!' sits right above the picoCTF wrapper in the file, but a grep pattern that only matches the curly-brace form might miss it if the encoding splits the prefix. Running strings with no filter first to inspect the surrounding lines confirms the full flag string before narrowing the pattern.
Learn more
Unity stores scene data for each level in a binary file called
level0,level1, etc. inside the*_Data/folder. Text objects placed in the scene (like 3D text meshes showing the flag) are stored as plain UTF-16 or UTF-8 strings in this file. Thestringscommand extracts any printable run of characters, which surfaces the flag text without running the game.This is the fastest CTF approach: run strings on every data file in the game bundle before spending time on dynamic analysis. Unity games are particularly friendly to this because scene assets are not encrypted by default.
Step 2
Alternative: patch the game with dnSpyObservationI noticed the game uses Mono/IL2CPP and ships Assembly-CSharp.dll in the Managed/ folder, which suggested the C# player controller logic (including the grounded jump restriction) could be decompiled and patched with dnSpy to enable infinite mid-air jumping over the invisible wall.For the more interactive approach, open the game assembly in dnSpy and remove the grounded check from the jump logic so you can jump infinitely and fly over the wall.bash# Download dnSpy from https://github.com/dnSpy/dnSpy/releasesbash# Open no-way-out_Data/Managed/Assembly-CSharp.dll in dnSpybash# Navigate to PlayerController -> Update methodbash# Remove the isGrounded condition from the jump checkbash# File -> Save Module, then run the gameWhat didn't work first
Tried: Opening the game executable directly in dnSpy instead of Assembly-CSharp.dll.
dnSpy is a .NET tool and cannot parse the native Unity game launcher. The actual C# game logic is compiled into Assembly-CSharp.dll inside no-way-out_Data/Managed/. Opening the wrong file shows either an error or an empty assembly tree with no PlayerController class to edit.
Tried: Editing the jump height or speed values in dnSpy rather than removing the isGrounded condition.
Increasing jump height just lets you jump higher from the ground - the invisible wall is tall enough that no finite jump height clears it. The correct fix is to remove the isGrounded boolean check entirely, which enables repeated mid-air jumps and lets you fly up indefinitely until you clear the boundary.
Learn more
dnSpy is a .NET assembly editor and debugger. Unity games compile C# scripts to
Assembly-CSharp.dllin theManaged/folder. dnSpy decompiles this DLL back to readable C# and lets you edit the code directly, then save the modified assembly.The jump logic in this game checks
if (Input.GetButton("Jump") && canMove && isGrounded && !isClimbing). Removing theisGroundedcondition lets you jump while airborne, effectively giving infinite flight. After patching, jump over the invisible wall, land outside, turn around, and read the flag displayed as a 3D text object in the enclosed area.The flag reads: WELCOME TO UNITY!!
Interactive tools
- Strings ExtractorPull printable text from any binary, library, or image. ASCII and UTF-16 detection, configurable minimum length, flag-like highlight, no command line needed.
- Hex ViewerView text or raw hex bytes as a xxd-style hex dump with byte offset, hex columns, and ASCII sidebar. Highlights printable characters and null bytes.
Flag
Reveal flag
picoCTF{WELCOME_TO_UNITY!!}
The simplest approach is strings on the level0 data file. The dnSpy patch is more fun but takes longer.