endianness-v2 picoCTF 2024 Solution

Published: April 3, 2024

Description

Here's a file that was recovered from a 32-bits system that organized the bytes a weird way. We're not even sure what type of file it is. Download it here and see what you can get out of it

CyberChef workflow

Download the provided file (hurt.c).

Open CyberChef (or use a local script) to perform the endianness swap.

bash
wget https://artifacts.picoctf.net/c_titan/85/hurt.c

Solution

Want to try it yourself first?

The guided walkthrough reveals hints one step at a time.

Walk me through it
This builds on the basic endianness challenge by applying byte-order swapping to forensics. Instead of simple word conversion, you fix a corrupted image file by swapping 32-bit chunks.
  1. Step 1
    Convert to hex
    Observation
    I noticed the downloaded file had a .c extension but the challenge description said the bytes were reorganized in a weird way, which suggested the file was binary data in disguise and that inspecting the raw hex bytes was the right first move before applying any transformations.
    Load the file into CyberChef and run To Hex to view the raw bytes.
    What didn't work first

    Tried: Opening the file in a text editor or IDE as if it were C source code.

    The .c extension makes it look like source code, but the content is binary garbage. A text editor shows unreadable characters and gives no useful information. The correct approach is to treat it as raw binary data and view it through a hex representation in CyberChef.

    Tried: Using the 'From Base64' or 'From Hex' operation in CyberChef first before viewing anything.

    Beginners sometimes try to decode the file immediately without first inspecting the raw bytes. Applying a decoding operation on raw binary without knowing the format usually produces garbage output. The first step should always be 'To Hex' to see what you are working with before applying any transformations.

    Learn more

    Hex (hexadecimal) representation is the standard way to view raw binary data. Each byte becomes two hex digits (00 to FF), making it easy to spot patterns, magic bytes, and structure without needing to know the file format. Every forensics and reversing workflow starts with examining raw bytes.

    CyberChef is a web-based data transformation tool created by GCHQ (UK's intelligence agency). It uses a "recipe" metaphor where you chain operations - much like Unix pipes - to transform data. Operations include encoding/decoding, encryption, compression, file format parsing, and more. It's become indispensable in CTF competitions for quick data manipulation without writing code.

    The file extension .c is misleading - this is a technique called file masquerading, where a file is given an incorrect extension to hide its true type. The correct way to identify a file's type is to examine its magic bytes (the first few bytes that identify the format), not its extension. Commands like file on Linux and TrID on Windows do exactly this.

  2. Step 2
    Swap endianness
    Observation
    I noticed the challenge description stated the file came from a 32-bit system that organized bytes in a weird order, which pointed directly to a 4-byte (32-bit word) endianness swap as the transformation needed to restore the file to its original byte order.
    Apply CyberChef's Swap Endianness op with Word Length set to 4 (the toggle reads "little to big"). The first three bytes should now read FF D8 FF, the JPEG magic, confirming the recovery worked.
    What didn't work first

    Tried: Setting the Swap Endianness word length to 2 instead of 4.

    A 16-bit (2-byte) swap is for 16-bit systems. The challenge explicitly says 32-bit, which means 4-byte words. Using word length 2 produces a different byte order that does not match any valid file format, so the magic bytes still look wrong. The word size must match the architecture - 32-bit means 4 bytes per word.

    Tried: Trying to swap endianness manually by reordering individual bytes in the hex view.

    Manually reordering bytes in a large file is error-prone and extremely tedious. CyberChef's Swap Endianness operation handles the entire file automatically in correctly-sized chunks. Manual reordering also risks losing track of chunk boundaries, producing an equally corrupted result.

    Learn more

    Endianness describes the byte order used to store multi-byte values. In big-endian format (used by network protocols, older Motorola/SPARC processors), the most significant byte comes first. In little-endian format (used by x86/x64, ARM in typical configurations), the least significant byte comes first.

    A 32-bit value like 0x12345678 is stored as 12 34 56 78 in big-endian and 78 56 34 12 in little-endian. This difference is invisible to programs running on the same architecture but becomes critical when transferring binary data between different systems - as this challenge simulates.

    The JPEG magic bytes are FF D8 FF at the start of every valid JPEG file. If the first bytes after swapping look like this pattern, you've confirmed the file format. File carvers and forensics tools use extensive databases of magic byte signatures (maintained in databases like libmagic) to identify file types independent of their extensions.

    Endianness bugs are a real concern in systems programming, network code, and embedded systems. The htonl() / ntohl() family of C functions ("host-to-network" and "network-to-host" long) exist specifically to convert between host byte order and network byte order (big-endian) when writing socket code.

  3. Step 3
    Render the image
    Observation
    I noticed the first three bytes after the swap matched the JPEG magic bytes FF D8 FF, which confirmed the file was a valid JPEG image and suggested converting the hex output back to binary and rendering it directly in CyberChef to read the embedded flag.
    Run From Hex followed by Render Image (Raw) to display the image containing the flag text.
    What didn't work first

    Tried: Clicking 'Save output to file' after the Swap Endianness step and trying to open the saved file as an image.

    After Swap Endianness, the CyberChef output is still a hex string, not raw binary. Saving at that point writes the hex text to disk, not a valid JPEG. You need to add 'From Hex' to convert back to binary bytes before the data can be interpreted as an image file.

    Tried: Using 'Render Image' directly after Swap Endianness without adding the 'From Hex' step.

    Swap Endianness outputs a hex string (because the input came from 'To Hex'). Render Image expects raw binary bytes, not a hex string. Skipping 'From Hex' causes the render to fail or show a broken image. The full recipe must be: To Hex, Swap Endianness, From Hex, then Render Image (Raw).

    Learn more

    CyberChef's Render Image (Raw) operation takes raw binary data and displays it as an image directly in the browser, using a data URI. This eliminates the need to save the file to disk and open it in a separate viewer - useful for quick verification during CTF work.

    The From Hex operation converts the hex string back to binary bytes. The full recipe (To Hex → Swap Endianness → From Hex → Render Image) demonstrates CyberChef's power: each operation in a recipe transforms the data and passes it to the next, exactly like Unix pipes.

    The flag being embedded as text in an image is a technique called visual steganography at the most basic level - the data is visible to the eye once the image is rendered, but hidden if you're only looking at the raw (corrupted) bytes. More advanced visual steganography hides data in the LSBs (least significant bits) of pixel values, making it invisible to the naked eye.

    This challenge teaches a valuable forensics workflow: when a file doesn't open or looks corrupted, check its magic bytes, compare to known formats, and consider byte-order issues. Many "corrupted" files in forensics challenges are actually valid files with their byte order swapped, bytes XORed with a constant, or other simple transformations applied.

    The hex dumps guide covers reading magic bytes and spotting byte-order issues, and the CTF encodings guide walks through the family of transformations to try when a file looks corrupted.

Flag

Reveal flag

picoCTF{cert!f1Ed_iNd!4n_s0rrY_3nDian_76e...}

Swapping each 32-bit word back to big endian renders the image holding the flag.

Key takeaway

Binary file formats rely on a fixed byte order, specified per format, to parse multi-byte fields correctly. When a file is transferred between systems with different native byte orders without conversion, every multi-byte value is misread and the file appears corrupt. Forensics investigations routinely encounter this: the file extension is meaningless, but the magic bytes at fixed offsets reveal the true format and the expected byte order. Correcting the byte order is then a mechanical transformation applied in word-sized chunks matching the architecture's native word width.

Related reading

Want more picoCTF 2024 writeups?

Useful tools for Forensics

What to try next