← Back to Writeups
CUSTOMEasySteganography

I Hate Physics!

XESXOR9/10/20267 min read
#steganography#custom#easy#first_and_last_character_acros#leet_speak_decoding#recognition_of_deliberate_text

I Hate Physics!

Platform: CUSTOM | Category: Steganography | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: first_and_last_character_acrostic, leet_speak_decoding, recognition_of_deliberate_text_anomalies

Summary

Walkthrough of the CUSTOM Steganography I Hate Physics!. A plain-text file of messy physics study notes hides the flag as a first-and-last-character acrostic: taking the first character and the last character of each of the first 15 lines and concatenating

Description

There's a secret message in these Physics study notes. Can you find it? The flag will be in the format DawgCTF{squarer00tofpi}.

File: STUDYME.txt

The provided STUDYME.txt is a 71-line plain-text file that looks like someone's thermodynamics study notes: kinetic energy, work, heat capacities at constant pressure/volume, ideal gas law, Boltzmann's entropy formula, a fully-worked ice + water mixing problem, and so on. The flag format example squarer00tofpi (i.e. "square root of pi" in leet speak) strongly hints that the hidden content is a short English phrase written with leet substitutions.

Analysis

1. First impression — many things are "wrong"

Reading the first 15 lines carefully:

D=1/2mv^2 (force * displacement) = 1/2 * mass * velocity^2 + alpha
w=fd (force * displacement) with respect to displacement lag
Cp=20.79 J/K/Mol for a constant pressure ONLY FOR OUTPUT
FINAL TEMPERATURE ALWAYS COMES FIRST BECAUSE THE TEMPERATURE DELTA IS INSIDE {
temperature min, temperature max}, like with
e=u+pVr
m=0
dU=mcdT and remember that sometimes mcdT can be a dy
nA is number of moles of gas A/B^4
mA*cA*∆T=cB*cB*∆T when two things are equalizing i.e and indirect carnot cycli
c, such as with the following equation: 2500kg*cA*(500-400)=cB*cB*∆T*5
s=ksubb * ln * omega * tau
cv=12.47J/K/Mol for a constant vol, Klevin is k
s=integral from vi to vf of (1/T *dU) for a general delta!
}]\d\wa\dT

Almost every line contains something that does not belong in a physics textbook:

  • Line 1 uses D as a symbol for kinetic energy and tacks on a stray + alpha.
  • Line 2 ends with the ungrammatical "with respect to displacement lag".
  • Line 3 ends in the ALL-CAPS fragment "ONLY FOR OUTPUT".
  • Line 4 is pure ALL-CAPS meta text "FINAL TEMPERATURE ALWAYS COMES FIRST BECAUSE THE TEMPERATURE DELTA IS INSIDE {" and ends on a lone opening brace.
  • Line 6 is e=u+pVr — the real enthalpy formula is H = U + pV, the trailing r is unexplained.
  • Line 7 is the tiny and pointless m=0.
  • Line 8 ends in the random fragment "can be a dy".
  • Line 9 has A/B^4, which is not a real expression.
  • Line 10 breaks the word "cyclic" unnaturally across two lines (cycli / c,).
  • Line 11 ends with a stray *5.
  • Line 12's Boltzmann entropy formula has an extra * tau.
  • Line 13 misspells Kelvin as "Klevin" and then tacks on "is k".
  • Line 14 ends with "for a general delta!".
  • Line 15 is pure regex-looking junk: }]\d\wa\dT.

These anomalies are too consistent to be sloppy note-taking — they are the encoding.

2. The instruction hints are red herrings

Several ALL-CAPS fragments look like instructions:

  • ONLY FOR OUTPUT
  • FINAL TEMPERATURE ALWAYS COMES FIRST
  • REMEMBER - YOU CAN SET FUNCTIONS EQUAL TO ANOTHER AND CANCEL LIKE TERMS
  • USE KELVIN FOR ENTROPY

It is tempting to interpret them as instructions for the extraction ("output only the caps", "cancel duplicates", "convert to Kelvin"). None of these lead anywhere. They exist only to provide the correct uppercase first letter at specific line positions (see step 4).

3. The key observation — flag prefix in the line starts

The flag format is DawgCTF{...}. Writing down the first character of each of the first four lines gives:

L1: D
L2: w
L3: C
L4: F

So lines 1..4 already supply D, w, C, F — every capital letter of DawgCTF except a, g, T. That strongly suggests an acrostic, but single first characters alone are not enough.

4. The actual encoding — first and last character of each line

Take the first character and the last character of each of the first 15 lines:

LineLine endingFirstLastPair
1...velocity^2 + alphaDaDa
2...displacement lagwgwg
3...ONLY FOR OUTPUTCTCT
4...DELTA IS INSIDE {F{F{
5...like withthth
6e=u+pVrerer
7m=0m0m0
8...can be a dydydy
9...of gas A/B^4n4n4
10...indirect carnot cyclimimi
11...=cBcB∆T*5c5c5
12s=ksubb * ln * omega * taususu
13...constant vol, Klevin is kckck
14...for a general delta**!**s!s!
15}]\d\wa\dT}(distractor T)}

Concatenating all pairs:

Da + wg + CT + F{ + th + er + m0 + dy + n4 + mi + c5 + su + ck + s! + }
= DawgCTF{REDACTED}

Decoding the leet (0→o, 4→a, 5→s) gives "thermodynamics sucks!" — exactly what a frustrated student who "hates physics" would write. The task title is literal.

5. Why each oddity is there

Every strange element in the first 15 lines exists solely to force the right first/last character pair:

LineWhat was insertedWhy
1+ alphaends in a
2with respect to displacement lagends in g
3ONLY FOR OUTPUTends in T
4ALL CAPS FINAL TEMPERATURE ALWAYS COMES FIRST BECAUSE THE TEMPERATURE DELTA IS INSIDE {starts with F, ends with {
5, like withends in h
6unexplained trailing r in e=u+pVrends in r
7m=0 (tiny formula)supplies both m and 0
8trailing ...can be a dyends in y
9nonsensical A/B^4ends in 4
10carnot cycli (word broken across lines)ends in i
11trailing *5ends in 5
12extra * tau in Boltzmann's formulaends in u
13, Klevin is k (with the deliberate misspelling "Klevin")ends in k
14for a general delta!ends in !
15the whole line }]\d\wa\dT is junkfirst char } closes the flag; the rest is a distractor

Lines 16–71 are cover text: more (still buggy) physics, two more ALL-CAPS "REMEMBER" hints, USE KELVIN FOR ENTROPY, and a concrete ice + water mixing problem that actually solves to T = 334.915873016. None of that contributes to the flag.

Solution

Python solver

python
#!/usr/bin/env python3
"""Solver for DawgCTF SP26 'I Hate Physics!' — first-and-last-char acrostic."""

from pathlib import Path


def solve(path: str) -> str:
    lines = Path(path).read_text(encoding='utf-8').splitlines()
    flag = ''
    for i, line in enumerate(lines[:15], 1):
        if not line:
            continue
        first = line[0]
        last = line[-1]
        if i == 15:
            # Line 15 is `}]\d\wa\dT`: only the first char (`}`) is part of the flag
            flag += first
        else:
            flag += first + last
        print(f'L{i:2d}: first={first!r:>4}  last={last!r:>4}  -> {first + (last if i != 15 else "")!r}')
    return flag


if __name__ == '__main__':
    flag = solve('STUDYME.txt')
    print(f'\nFlag: {flag}')
    # DawgCTF{REDACTED}

TL;DR

  1. Look at the first character of each of the first few lines: D, w, C, F — matches the DawgCTF prefix of the flag format, so an acrostic is almost certainly in play.
  2. Lines 5–15 don't start with the expected letters for the inside of {...}, so first-char-only isn't enough.
  3. Take first char + last char of each of the first 14 lines, plus first char of line 15 (}).
  4. Concatenate: DawgCTF{REDACTED}.
  5. Ignore the ALL-CAPS "instruction" fragments, the }]\d\wa\dT regex-looking line, and the ice + water entropy calculation at the bottom — all red herrings.

Key Takeaways / Lessons

  • Mastering first_and_last_character_acrostic, leet_speak_decoding, recognition_of_deliberate_text_anomalies was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2026-04-10 • CUSTOM • I Hate Physics! • Difficulty: Easy