Cheater Cheater
dawgctf
A Java Swing Pac-Man clone called HacMan ships a decoy `flag` field and a deliberately unreachable highscore (6,942,069) with a trap at score==64,000 that kills the process. The real flag is an AES/CBC ciphertext stored in `SimplePacMan.pacVelocityZ` that the game only decrypts in the `winner` branch of `paintComponent`, which calls `setName(Integer.toString(score))` on the panel and then invokes `revalidate()` on the first child component (`barbecue`, a custom `JTextBasket`). `JTextBasket.revalidate()` reads the parent panel's name as a `BigInteger`, computes `N = (name*10+1)^4`, feeds `N.toString()` as a **hex** string to derive a 16-byte AES key, feeds the *reversed* decimal string as a 16-byte IV, and decrypts the base64 blob. You don't need to play or patch the game: replicating the derivation in Python with score `6942069` yields `DawgCTF{ch3at3R_ch34t3r_pumk1n_34t3r!}`.
$ ls tags/ techniques/
Cheater Cheater — DawgCTF SP26
Description
There's this game called Hac-Man and I've been trying really hard to beat this guy's high score but I swear it's impossible! Can you help?
The flag will be in the format
DawgCTF{Anyth1ngIsP0ss1bl3!}File:
PacManForCTF.jar
The task title is the hint: cheat. The description even spells it out ("I swear it's impossible"). Running the JAR (java -jar PacManForCTF.jar) opens a 1920×2045 Swing window titled "HacMan" with a Prim's-algorithm maze, a yellow Pac-Man, and a red "Highscore: 6942069" — obviously unreachable if each dot only gives 10 points and the maze holds fewer than that many dots.
Recon
$ file PacManForCTF.jar
PacManForCTF.jar: Java archive data (JAR)
$ unzip -l PacManForCTF.jar
Length Date Time Name
--------- ---------- ----- ----
51 04-20-2023 00:59 META-INF/MANIFEST.MF
498 04-20-2023 00:58 SimplePacMan$1.class
971 04-20-2023 00:58 SimplePacMan$2.class
11749 04-20-2023 00:58 SimplePacMan.class
7292 04-20-2023 00:59 JTextBasket.class
$ cat META-INF/MANIFEST.MF
Manifest-Version: 1.0
Main-Class: SimplePacMan
Two relevant classes: SimplePacMan (the game) and JTextBasket (a suspicious "text basket" — the name is already a red flag for a custom swing component that shouldn't normally exist).
Decompile with jadx:
$ jadx -d decompiled PacManForCTF.jar
$ ls decompiled/sources/defpackage/
JTextBasket.java SimplePacMan.java
Analysis
1. SimplePacMan — the decoys
SimplePacMan extends JPanel implements ActionListener. Relevant highlights:
public class SimplePacMan extends JPanel implements ActionListener { private static final int numTiles = 80; private static final int tileSize = 24; // ... private int score; private JTextBasket barbecue; private JTextBasket barbecue2; ...
Permission denied (requires auth)
Sign in to read this free writeup
This writeup is free — just sign in with GitHub to read it.
$ssh [email protected]