2025 Winter Challenge: Quinindrome

Written by Timothée Schneider-Maunoury - 01/12/2025 - in Challenges - Download

A few months have passed and the first snowflakes have fallen since the end of the Synacktiv Summer Challenge. This event was a success, with one of the participants even finding a zero-day vulnerability while working on his solution! Although it hasn't been made public yet, it will be covered in an upcoming article on the Synacktiv website. As winter is coming, it's now time to introduce the Synacktiv Winter Challenge! Join other participants in this code golfing contest and send us your solution before January 1st 🏌️. 

Looking to improve your skills? Discover our trainings sessions! Learn more.

🎁 Prizes

The top three contestants will receive the following prizes:

  1. first place: this outstanding IFixIt kit and a soldering iron to get all your electronics fixed,
  2. second place: this 8-port PoE+ Netgear switch, perfect for your home network,
  3. third place: a Yubikey 5C NFC for secure authentication!

🏆 The challenge

The idea is to design a quinindrome, which is an ELF binary that meets these two requirements:

1. be a palindrome, meaning it's totally symmetrical,
2. and be a byte-wise quine: print its own file on stdout when executed.

Of course, the process must end without a segfault, and the return code has to be set to 0.

Those who took part in the previous challenge will recognize the topic, but be aware: you will need to come up with very different techniques to optimize your solution as much as possible. This time, you will have to play with the header of an ELF file and find the optimal layout for the x86 instructions that will constitute your program!

Here is the test script: 

#!/bin/bash

##### Argument checks #####
# Check if binary path is provided
if [ $# -ne 1 ]; then
    echo "[+] Usage: $0 <binary_path>"
    exit 1
fi

binary=$1

# Check if file exists and is readable
if [ ! -f "$binary" ] || [ ! -r "$binary" ]; then
    echo "[!] Error: File '$binary' does not exist or is not readable."
    exit 1
fi


##### First check: byte-wise palindrome #####
reversed_file=$(mktemp)
size=$(wc -c < "$binary")

# Read the file byte by byte in reverse order (in a very efficient way)
for ((i = size - 1; i >= 0; i--)); do
    dd if="$binary" bs=1 skip=$i count=1 2>/dev/null
done > "$reversed_file"

if cmp -s "$binary" "$reversed_file"; then
    echo "[+] First check passed: binary is a byte-wise palindrome."
    rm "$reversed_file"
else
    echo "[!] First check failed: binary is not a byte-wise palindrome."
    rm "$reversed_file"
    exit 1
fi


##### Build a scratch Podman image with the binary to test #####
# Create the containerfile
image_name="quinindrome_test"
containerfile=$(mktemp)

cat > "$containerfile" <<EOF
FROM scratch
COPY $binary /binary
CMD ["/binary"]
EOF

# Build the image
if ! podman build . -t "$image_name" -f "$containerfile" >/dev/null; then
    echo "[!] Failed to build Podman test image."
    rm "$containerfile"
    exit 1
fi
rm "$containerfile"


##### Second check: quine property #####
output_file=$(mktemp)
max_run_time=120

# Run the binary in the scratch container and capture output & return code
timeout "$max_run_time" podman run --rm "$image_name" > "$output_file"
return_code=$?

if [ $return_code -ne 0 ]; then
    echo "[!] Second check failed: binary execution returned non-zero status: $return_code."
    rm "$output_file"
    exit 1
fi

if cmp -s "$binary" "$output_file"; then
    echo "[+] Second check passed: binary is a true quine, its output matches itself."
    rm "$output_file"
else
    echo "[!] Second check failed: Is that a quine? Binary output does not match itself."
    rm "$output_file"
    exit 1
fi

echo "[+] Both checks passed: your binary is a very nice quinindrome!"
echo "[+] Your score: $size"

 

📩 How to participate

Solutions will be accepted until December 31 at 11:59 p.m. UTC+1.
To submit your solution, send it to winter-challenge@synacktiv.com.

  1. As you may already guess, the winner will be the one who manages to obtain the lowest score obtained by the test script above.
  2. The challenge will take place during the month of December and the write-up will be published in early 2026.
  3. You can submit your solutions as you progress.
  4. You can send us as many as you like, up to one per day. This means that if you send a binary on the morning of January 4, you will not be entitled to another chance.
  5. Once your entry has been received and validated, the overall ranking will be updated. However, scores will not be disclosed in order to maintain the suspense.
  6. If you have any concerns or questions about the rules, feel free to contact us by email.

 

🖥️ The testing VM

Below is a description of the virtual machine where the test script will be run to validate your solutions:

  1. Debian 13 operating system,with a 6.12.57+deb13-amd64 Linux kernel,
  2. x86_64 architecture: this means your binary will have to use a header and instruction set for either 32-bit or 64-bit x86,
  3. podman version 5.4.2 is installed,
  4. the VM does not have access to internet,
  5. it is configured with 4 vCPUs and 8 GB of RAM.

🥷🏼 Bonus

We have already produced a quite effective solution. Will you succeed in surpassing Synacktiv?
In order to avoid revealing the result of this solution, here is the hash of a text file that shows our score: c4f704d883bdfdd3d4963bb74054af9abd3d78c35b85812dc8a5d2e9cc2df060.
The file will be published in this challenge writeup.
 
Good luck and happy holidays!