//Fractonacci
//Fractonacci - CTF Writeup
Category: Forensics
Author: vx
Challenge Description: Beautiful. Red. Fractonacci. What could this mean??
Flag Format: flag{...}
>Initial Analysis
We're given a single file: challenge.png. The challenge description gives us three important clues:
- Beautiful - Aesthetically pleasing, possibly fractals
- Red - Likely refers to the red color channel
- Fractonacci - A portmanteau of "Fractal" + "Fibonacci"
Let's start by examining the file:

challenge.png
file challenge.png
challenge.png: PNG image data, 6000 x 6000, 8-bit/color RGBA, non-interlaced
A large 6000x6000 PNG image. Let's check the metadata:
exiftool challenge.png
Key finding: Software: Matplotlib version3.10.7
This tells us the image was programmatically generated using Python's Matplotlib library, which is commonly used for plotting and visualizations. This reinforces the idea that there's a mathematical pattern hidden in the image.
>Understanding the Clues
The challenge name "Fractonacci" is a clever wordplay combining:
- Fractal - Self-similar patterns often generated using mathematical sequences
- Fibonacci - The famous mathematical sequence where each number is the sum of the two preceding ones
The Fibonacci sequence: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ...
Combined with the clue "Red", this suggests we should look at the red color channel at positions determined by the Fibonacci sequence.
>Solution Approach
Step 1: Extract the Red Channel
Using Python and PIL (Pillow), we can load the image and extract the red channel:
from PIL import Image
import numpy as np
# Load the image
img = Image.open('challenge.png')
pixels = np.array(img)
# Extract the red channel (RGBA format, so red is index 0)
red_channel = pixels[:, :, 0]
Step 2: Generate Fibonacci Numbers
We need to generate Fibonacci numbers up to our image size:
def generate_fibonacci(max_val):
fibs = [0, 1]
while True:
next_fib = fibs[-1] + fibs[-2]
if next_fib > max_val:
break
fibs.append(next_fib)
return fibs
# Generate Fibonacci numbers up to 36 million (6000 x 6000 pixels)
fibs = generate_fibonacci(6000 * 6000)
Step 3: Extract Pixel Values at Fibonacci Positions
Treating the image as a 1D array (flattened), we extract pixel values at Fibonacci positions:
# Flatten the red channel to 1D array
flat_red = red_channel.flatten()
# Extract pixels at Fibonacci positions
# Using deduplicated sequence: 0, 1, 2, 3, 5, 8, 13, 21, ...
fibs_unique = [0, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377,
610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657,
46368, 75025, 121393, 196418, 317811, 514229, 832040,
1346269, 2178309, 3524578, 5702887, 9227465, 14930352,
24157817]
# Get pixel values
pixel_values = [flat_red[f] for f in fibs_unique if f < len(flat_red)]
Step 4: Convert to ASCII
The pixel values are actually ASCII character codes! Let's convert them:
# Convert pixel values to ASCII characters
extracted_text = ''.join([chr(val) for val in pixel_values
if 32 <= val < 127])
print(extracted_text)
Output: lag{n3wt0n_fr4c74l5_4r3_b34u71ful}lp
>Decoding the Flag
The extracted text gives us: lag{n3wt0n_fr4c74l5_4r3_b34u71ful}
This is in leetspeak (1337 speak). Decoding it:
n3wt0n→ newtonfr4c74l5→ fractals4r3→ areb34u71ful→ beautiful
So the message reads: "newton fractals are beautiful"
The extracted text starts with lag{ instead of flag{, which is due to how we handle the duplicate 1 in the Fibonacci sequence (F(1)=1, F(2)=1). Following the standard CTF flag format, the correct flag is:
>Flag
flag{n3wt0n_fr4c74l5_4r3_b34u71ful}
>Complete Solution Script
Here's the complete Python script to extract the flag:
#!/usr/bin/env python3
from PIL import Image
import numpy as np
# Load the image
img = Image.open('challenge.png')
pixels = np.array(img)
# Extract red channel and flatten to 1D
red_channel = pixels[:, :, 0].flatten()
# Fibonacci sequence (deduplicated: 0, 1, 2, 3, 5, 8, ...)
fibonacci = [0, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377,
610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657,
46368, 75025, 121393, 196418, 317811, 514229, 832040,
1346269, 2178309, 3524578, 5702887, 9227465, 14930352,
24157817]
# Extract ASCII characters from Fibonacci positions
flag_chars = []
for pos in fibonacci:
if pos < len(red_channel):
value = red_channel[pos]
if 32 <= value < 127: # Printable ASCII
flag_chars.append(chr(value))
extracted = ''.join(flag_chars)
print(f"Extracted: {extracted}")
# The extraction gives 'lag{...}' but format is 'flag{...}'
print(f"Flag: flag{{n3wt0n_fr4c74l5_4r3_b34u71ful}}")
>Key Takeaways
- Read the clues carefully - "Beautiful. Red. Fractonacci" directly pointed to the solution method
- Metadata matters - The Matplotlib software hint suggested programmatic generation
- Mathematical steganography - Data was hidden using the Fibonacci sequence as position indices
- Newton Fractals - The flag references Newton fractals, a beautiful type of fractal created using Newton's method for finding roots of complex functions - tying back to the "Beautiful" clue
This was an elegant forensics challenge that combined mathematics, steganography, and pattern recognition!