Checkmate, Liver King
Checkmate, Liver King
Platform: dawgctf | Category: Reversing | Type: Challenge | Difficulty: Medium | OS: Linux | Author: XESXOR | Date: 2026-04-10 | Status: Solved Techniques: static_string_deobfuscation, xor_blob_decryption, opening_reconstruction_from_move_squares, fen_checkpoint_validation, domain_knowledge_inference
Summary
Task: a stripped Rust chess GUI hides XOR-obfuscated strings and intermediate board states inside the binary. Solution: decrypt the blobs, recognize the Fried Liver Attack from the recovered move squares and FEN checkpoints, then append the unprinted but forced Kxf7 destination square to complete the line and build the flag.
Checkmate, Liver King — DawgCTF SP26
Description
Binary:
theliverkingHint: "Consider the title of the challenge, and if that fails, all the secrets are in the binary!"
English summary: this is a stripped 64-bit Linux Rust chess GUI. The goal is not to beat the program normally, but to reverse the hidden strings, recover the intended chess line, and convert the move sequence into the final DawgCTF{...} flag.
Recon
The binary is a stripped ELF64, so the first useful path is static analysis rather than symbol-driven reversing. Looking through the data section reveals multiple blobs that do not decode as plaintext directly but do decrypt under a repeated XOR key:
text read-only • copy allowedxnasff3wcedj
Applying that key to the hidden buffers yields two especially important strings:
text read-only • copy allowedREDACTED You did it! The flag is your moves to get here.
The binary also contains hidden FEN checkpoints:
text read-only • copy allowedrnbqkbnr/pppp1ppp/8/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R r1bqkb1r/pppp1ppp/2n2n2/4p1N1/2B1P3/8/PPPP1PPP/RNBQK2R r1bqkb1r/ppp2ppp/2n2n2/3Pp1N1/2B5/8/PPPP1PPP/RNBQK2R r1bqkb1r/ppp2Npp/2n5/3np3/2B5/8/PPPP1PPP/RNBQK2R
Those positions are a strong clue that the decrypted string is not random text: it is a chess move path.
Analysis
The title is the second hint. Liver King points directly at the Fried Liver Attack, a well-known opening line:
- e4
- e5
- Nf3
- Nc6
- Bc4
- Nf6
- Ng5
- d5
- exd5
- Nxd5
- Nxf7
If we record only the destination squares of those moves, we get exactly the decrypted output:
text read-only • copy allowede4 e5 f3 c6 c4 f6 g5 d5 d5 d5 f7
joined as:
text read-only • copy allowedREDACTED
The embedded FEN snapshots match the same sequence at several checkpoints, which confirms that the intended interpretation is the Fried Liver line and not just a loose chess reference.
Solution
1. Decrypt the hidden strings
Reverse the string-obfuscation routine and apply the repeated XOR key xnasff3wcedj to the hidden blobs. This recovers both the move-square string and the message telling us that the flag is based on the moves used to reach the winning state.
2. Read the move string as chess destination squares
The output is not SAN or LAN; it is the sequence of destination squares only:
text read-only • copy allowedREDACTED
Together with the title, that reconstructs the opening line:
e2-e4->e4e7-e5->e5g1-f3->f3b8-c6->c6f1-c4->c4g8-f6->f6f3-g5->g5d7-d5->d5e4xd5->d5f6xd5->d5g5xf7->f7
3. Notice the line is still incomplete
This is the key reasoning step. The binary prints the white attacking line only, but after Nxf7 the natural and forced continuation for black is:
Kxf7->f7
That final destination square is not printed by the binary, yet it is required to complete the Fried Liver continuation implied by the puzzle. This was also consistent with the public competition discussion and the challenge's intended solution path.
4. Append the missing final square and wrap the flag
So the completed square sequence becomes:
text read-only • copy allowedREDACTED
and the final flag is:
text read-only • copy allowedDawgCTF{REDACTED}
python read-only • copy allowed#!/usr/bin/env python3 partial = "REDACTED" missing_reply = "f7" # Kxf7 flag = f"DawgCTF{{{partial}{missing_reply}}}" print(flag)