Skip to content

SECURE_CONNECTION//PRESS[CTRL+J]FOR ROOT ACCESS

BACK TO INTEL
ForensicsEasy

Chronofolder

CTF writeup for Chronofolder from Vianu CTF

//ChronoFolder

Flag: Vianu_CTF{t1m3_m@st3r_4728290}

>TL;DR

The archive contains many decoy files, but their timestamps (mtime) are the real payload.

  1. Extract the zip.
  2. Sort the extracted .txt files by mtime.
  3. Select only the files whose minute-of-hour is a Fibonacci number: 1, 2, 3, 5, 8, 13, 21, 34.
  4. Concatenate those selected filenames (stems), then Base64-decode → flag.

>Challenge premise

We’re given a recovered directory that looks nearly empty. This is a classic forensics pattern: the "message" is often hidden in:

  • Hidden files or weird filenames
  • File timestamps (mtime/atime/ctime)
  • Extended attributes
  • Embedded metadata in images
  • Archive structure tricks

The challenge name ChronoFolder is an immediate hint that time matters.


>1) Initial triage (what’s in the folder?)

From the challenge directory:

bash

cd /home/noigel/CTF/VianuCTF/Forensics/ChronoFolder

ls -la

I found two key files:

  • chall-20251208T215041Z-1-001.zip
  • chall-20251208T215041Z-1-001.zip:Zone.Identifier

Why Zone.Identifier matters

On Windows, Zone.Identifier is an Alternate Data Stream (ADS) that can store “downloaded from the internet” metadata.

On Linux, you may see it as a separate file when a zip was created/extracted on Windows or transferred in a way that preserved the stream name.

It’s not always useful, but it’s a clue that the evidence was handled across platforms.


>2) List the archive contents and extract

Before extracting, I like to list the archive:

bash

unzip -l chall-20251208T215041Z-1-001.zip | sed -n '1,200p'

Then extract into a fresh directory:

bash

rm -rf extracted

mkdir extracted

unzip -q chall-20251208T215041Z-1-001.zip -d extracted

find extracted -maxdepth 3 -printf '%y %p\\n' | sed -n '1,200p'

This revealed a folder full of .txt files, plus a misnamed “png” that was actually a WebP.

At this point there were obvious decoys:

  • flag.txt contained Vianu_CTF{try_harder} (clearly not the final solution)
  • ffaH.txt contained Vianu_CTF{n0t_r34l_4t_4ll} (also a decoy)

So I pivoted to what the challenge name suggested: chronology.


>3) Why timestamps? (Reasoning)

The title: ChronoFolder

CTF designers often encode the intended method in the name:

  • “Chrono” → time
  • “Folder” → filesystem-level artifacts

What I checked first

I sorted files by modification time (mtime):

bash

find extracted/chall -maxdepth 1 -type f -name '*.txt' -printf '%T@\\t%f\\n' | sort -n | sed -n '1,200p'

This produced a very “engineered” sequence:

  • Many files spaced by neat minute increments
  • A long run of files on the same day/time window

That’s not how organic user files look. It strongly suggests intentional timestamp encoding.


>4) The key hint: Fibonacci numbers in image metadata

The file 676767.png was actually WebP:

bash

file extracted/chall/676767.png

# RIFF ... Web/P image

I inspected metadata:

bash

exiftool extracted/chall/676767.png | sed -n '1,200p'

The User Comment contained:

btw i like these numbers 1,2,3,5,8,13

That’s the Fibonacci sequence.

Why this is the “aha” moment

At this point we have:

  • Challenge title screams timestamps
  • An image metadata hint screams Fibonacci

So the natural hypothesis is:

“Pick items based on a Fibonacci rule applied to timestamps.”

There are multiple ways Fibonacci could be applied:

  • Fibonacci indices (1st, 2nd, 3rd, 5th file…)
  • Fibonacci time deltas between mtimes
  • Fibonacci minute values inside the timestamp

The simplest interpretation (and often the correct one in CTFs) is:

Use Fibonacci numbers as minute-of-hour values.

Because they gave raw numbers like 1,2,3,5,8,13 (not “1st, 2nd, …”) and because timestamps naturally contain minutes.


>5) Verify the minute-of-hour hypothesis

I printed each .txt file in chronological order with its UTC time:

bash

python3 - <<'PY'

import pathlib, datetime

p=pathlib.Path('extracted/chall')

items=sorted([f for f in p.glob('*.txt')], key=lambda f: f.stat().st_mtime)

base=datetime.datetime.utcfromtimestamp(items[0].stat().st_mtime).replace(second=0)

print('base',base)

for i,f in enumerate(items,1):

    dt=datetime.datetime.utcfromtimestamp(f.stat().st_mtime)

    delta=int((dt-base).total_seconds()/60)

    print(f"{i:02d} {dt.strftime('%H:%M')} (+{delta:02d}m) {f.name}")

PY

Then I selected files whose minute is Fibonacci:

  • 1, 2, 3, 5, 8, 13, 21, 34, 55, ...

In this dataset, the useful ones were:

  • minute 01Vmlh.txt
  • minute 02bnVf.txt
  • minute 03Q1RG.txt
  • minute 05e3Qxb.txt
  • minute 08TNfbU.txt
  • minute 13BzdDN.txt
  • minute 21yXzQ3Mj.txt
  • minute 34gyOTB9.txt

Notice how the selected stems look like Base64 chunks (e.g., Vmlh, bnVf, Q1RG, e3Qx...).

That’s a huge confirmation signal.


>6) Extract the message from filenames (Base64)

The solution is to concatenate the filename stems (without .txt) in chronological order and Base64-decode.

I used this script:

bash

python3 - <<'PY'

import base64, pathlib, datetime, re

p=pathlib.Path('extracted/chall')

items=sorted([f for f in p.glob('*.txt')], key=lambda f: f.stat().st_mtime)

fib_minutes={1,2,3,5,8,13,21,34,55}

sel=[]

for f in items:

    dt=datetime.datetime.utcfromtimestamp(f.stat().st_mtime)

    if dt.minute in fib_minutes:

        sel.append((dt.minute,f))

concat=''.join(f.stem for _,f in sel)

print('concat:', concat)

pad='='*((4-len(concat)%4)%4)

raw=base64.urlsafe_b64decode(concat+pad)

print('decoded:', raw)

m=re.search(rb'Vianu_CTF\\{[^}]{0,200}\\}', raw)

print('flag:', m.group(0).decode() if m else 'no match')

PY

Output included:

  • Decoded: Vianu_CTF{t1m3_m@st3r_4728290}

That matches the required format.


>7) Notes on decoys (why they’re there)

You’ll see at least two tempting strings:

  • flag.txtVianu_CTF{try_harder}
  • ffaH.txtVianu_CTF{n0t_r34l_4t_4ll}

These are deliberate “time wasters”. The correct solution is distinguished by:

  • It uses the challenge theme (time/chronology)
  • It uses the explicit hint (Fibonacci numbers)
  • It produces a clean Base64 decode into a properly formatted flag

>References