The Café's Fishy puzzle

October 18, 20251280 words7 mins read

Café badges

Well, you probably know about The Café by now: it’s a private, invite-only community I have started on August 29, 2025, after being in development for about one month before. We currently have about 160 members so far, and we talk about various stuff (both on the Café and its dedicated IRC channel), we plan events and do puzzles. And the latest puzzle challenge was something I named Fishy and it involved virtual fishing in the Café’s wate… API for clues and secrets. The reward is a unique member title (<Master baiter>) for the first solver + a cool Café badge, and a different title (<Fisher>) + the same badge for everybody who solves it after.

I’ll let the one and only bonk tell you how the puzzle can be solved, since he’s the first to solve it, and therefore will be forever known in the Café annals as <Master baiter> bonk (because he baits masterfully and not for other reasons, you perverts!):


The puzzle started by sizeofcat hinting us by saying “There might be something Fishy here, if you’re looking for a puzzle :D” and linking us the Café badges page. The first clue was the 303th badge’s label that says: “Fishy says L2ZpbGVzL3tiYWl0LGZpc2h5fQ==”.
At first glance, you can see it’s base64. Decoding it reveals: /files/{bait,fishy}.
In bash and many other Unix(-like) shells that would expand to: /files/bait /files/fishy. These are probably files on this website, so bait, fishy.
Bait is a plain text file with the contents being: p6EHsgP79RMUOcanpt8qlUWHC36XaseC, fishy is a 403 - Forbidden page…
I have tried all kinds of things with the contents of bait to get past the 403; GET, POST arguments, HTTP authorization headers, cookies, I even thought it could be a PHP session id, nope.
Just a few days back we got our hands on the shiny new Café API, that gave me an idea…
I requested the API with controller=fishy, it was just a guess lol… and I hooked onto something…

$ curl -X POST https://sizeof.cat/cafe/ -d 'action=api' -d 'token=' -d 'controller=fishy'                  
{"version":"1.5.66","time":"Wed, 15 Oct 2025 20:09:31 +0000","message":{"error":true,"text":"Fishy demands secrets."}}

Hmm, fishy demands secrets? How about secret=p6EHsgP79RMUOcanpt8qlUWHC36XaseC?

{"version":"1.5.66","time":"Wed, 15 Oct 2025 20:10:32 +0000","message":{"error":true,"text":"Fishy doesn't know you."}}

I think about giving name as a POST argument, nope. username, uid, nope, nothing works. The only thing I noticed was that no matter what’s being passed in secret it would always say “Fishy doesn’t know you”.
Everyone was stumped. Every person on the IRC was losing their sanity (:D), saying things like “RAAAAAAH” non-stop, just see for yourselves:

2025/10/15 21:37:06 <bonkbonk>	cat you bastard!!11!
2025/10/15 21:37:02 <sizeofcat>	what? :D
2025/10/15 21:37:11 <Myrdincx>	ARGHHH
2025/10/15 21:37:12 <Myrdincx>	aJDODIAHODAHd
2025/10/15 21:38:24 <bonkbonk>	RAAAAH
...
2025/10/15 21:42:27 <sizeofcat>	new badge, count the number of "RAAAAH" in the irc channel
2025/10/15 21:42:35 <Myrdincx>	fr
2025/10/15 21:42:38 <Myrdincx>	RAHHH
2025/10/15 21:43:52 <bonkbonk>	RAAAAAAAH
...
2025/10/15 21:45:19 <bonkbonk>	https://inv.nadeko.net/watch?v=PL9iMPx9CpQ
2025/10/15 21:45:21 <bonkbonk>	egggh
2025/10/15 21:45:23 <bonkbonk>	fibsh
...
2025/10/15 21:55:49 <sizeofcat>	i don't understand how you get onto a forbidden access page :D
...
2025/10/15 21:57:10 <sizeofcat>	oooh, a change!
2025/10/15 21:57:17 <sizeofcat>	no more RAAAAAAh?
2025/10/15 21:57:19 <rosetta>	fking 403
2025/10/15 21:57:34 <bonkbonk>	RAAAAAAAH
2025/10/15 21:57:25 <sizeofcat>	haha
2025/10/15 21:57:26 <rosetta>	RAAAH
2025/10/15 21:57:34 <rosetta>	WHAT MEAN FORBIDDEN
2025/10/15 21:57:49 <rosetta>	i deserve access im pure of heart
...
2025/10/15 22:07:44 <Myrdincx>	fishy doesnt like me either :(
...
2025/10/15 22:14:11 <Myrdincx>	Im not quite sure what type of secrets fishy demands..
2025/10/15 22:14:20 <Myrdincx>	Ive tried all kinds of things 
2025/10/15 22:14:35 <sizeofcat>	well, you gave fishy the bait?
2025/10/15 22:14:38 <Myrdincx>	yeah I did
2025/10/15 22:14:46 <Myrdincx>	fishy didnt like my bait :(
...
2025/10/15 22:19:33 <Myrdincx>	sizeofcat, fishy doesnt know me :(
2025/10/15 22:19:38 <sizeofcat>	:(
...
2025/10/15 22:25:57 <Myrdincx>	Im angry at fishy
2025/10/15 22:26:05 <Myrdincx>	Ive tried to tell fishy who I am
2025/10/15 22:26:09 <Myrdincx>	and he just doesnt care :')
2025/10/15 22:26:14 <Myrdincx>	He still doesn't know who I am..
2025/10/15 22:27:58 <bonkbonk>	sounds dramatic lol, "after all these years... fishy doesn't even know who i am..."
2025/10/15 22:28:29 <Myrdincx>	Fishy demands secrets, I give him secrets (i dont know the secret) and fishy doesnt want to know me..
...
2025/10/15 23:55:48 <bonkbonk>	this was the saddest attempt
2025/10/15 23:55:50 <bonkbonk>	curl -X POST https://sizeof.cat/cafe/ -d 'action=api' -d 'token=' -d 'controller=fishy' -d 'secret=fishy please let me in'
2025/10/15 23:55:50 <bonkbonk>	{"version":"1.5.66","time":"Wed, 15 Oct 2025 20:10:32 +0000","message":{"error":true,"text":"Fishy doesn't know you."}}
2025/10/15 23:55:56 <sizeofcat>	haha

(also come join us on irc.libera.chat, channel ##cafe :D)

And then…

2025/10/15 22:52:15 <sizeofcat>	oh, that was a big mistake on my side, the rights on the fishy file were not world read
2025/10/15 22:52:23 <sizeofcat>	so, go and download the fishy file again :(

(It’s okay cat, everyone makes mistakes.)
So, finally we can move forward again… just until I saw the contents of fishy… It’s a file that’s exactly 300KiB with its contents being encrypted.
The first two things that I though to do were:

$ file fishy
fishy: data
$ file --mime-type fishy 
fishy: application/octet-stream

Manually inspecting the start of the file also didn’t help… there is no header.
Here are some of my attempts on trying to read the contents of the file:

$ gpg --decrypt fishy
gpg: no valid OpenPGP data found.
gpg: decrypt_message failed: Unknown system error

$ algorithms=({A LOT OF DIFFERENT ALGORITHMS IN ARRAY HERE}); for i in "${algorithms[@]}"; do openssl enc -d -in fishy -pass file:bait -$i -nosalt; done

Suddenly I remembered one of sizeofcat’s old posts. The file is exactly 300KiB, could it be a LUKS volume?

$ cryptsetup open fishy fish
Device fishy is not a valid LUKS device.

Stumped again.

2025/10/16 14:25:09 <bonkbonk> sudo cryptsetup open fishy fish
2025/10/16 14:25:09 <bonkbonk> Device fishy is not a valid LUKS device.
2025/10/16 14:25:20 <sizeofcat> doublebonk, you might be onto something there

This clue was what got me on the track. I then checked; the LUKS header itself is 2MB, so it couldn’t be LUKS. But I “was onto something”. Might it be Veracrypt then???
DING DING DING DING DING!!! I opened the container using p6EHsgP79RMUOcanpt8qlUWHC36XaseC as password. Before my very eyes I saw fishy’s beautiful readme.txt. It finally explained what exactly to pass in the secret POST argument.

API
	http(s)://sizeof.cat/cafe/
ENDPOINT
	index.php
PARAMS
	action=api
	token=
	controller=fishy
	secret=md5(sha256(bait)+token)
RESULT
	enjoy fishy

Okay, bait = p6EHsgP79RMUOcanpt8qlUWHC36XaseC, token is your API access token from The Café, let’s say token = XYZ.
You can use coreutils from or your operating system or a website (sha256, md5).
sha256(bait):

$ echo -n p6EHsgP79RMUOcanpt8qlUWHC36XaseC | sha256sum
6e216b1f0ba01ae4001bd3d93f255d0820418205783290297551f8e6dc45a18e -

sha256(bait)+token = 6e216b1f0ba01ae4001bd3d93f255d0820418205783290297551f8e6dc45a18eXYZ.
md5(sha256(bait)+token):

$ echo -n 6e216b1f0ba01ae4001bd3d93f255d0820418205783290297551f8e6dc45a18eXYZ | md5sum
0c3901c1a6b86fba530c6c8d7f41f1be  -

Now to only pass that as secret.

$ curl -X POST https://sizeof.cat/cafe/ -d 'action=api' -d 'token=XYZ' -d 'controller=fishy' -d 'secret=0c3901c1a6b86fba530c6c8d7f41f1be'
{"version":"1.5.70","time":"Thu, 16 Oct 2025 12:44:43 +0000","message":{"error":false,"text":"You caught Fishy!"}}

Finally. Fishy.

After solving the puzzle my way I received this message:

<sizeofcat> there is a secret parameter called bait with the contents fishy
<sizeofcat> you can pass that to the api
<sizeofcat> and there is a 1/5 chance it will reply you with a clue
<sizeofcat> try it :D
<sizeofcat> that's what i was saying "you need to bait the fish!"
curl -X POST https://sizeof.cat/cafe/ -d 'action=api' -d 'token=' -d 'controller=fishy' -d 'bait=fishy'
{"version":"1.5.70","time":"Thu, 16 Oct 2025 20:09:09 +0000","message":{"error":false,"text":"You missed Fishy, but you caught a Vera."}}

Oh. It was that easy…


Moral of the event: fibsh, RAAAAH and

2025/10/15 22:23:42 <Myrdincx>	fuck this fish
2025/10/15 22:23:48 <Myrdincx>	i dont like him
2025/10/15 22:23:59 <bonkbonk>	FUCK THIS FISH

The whole thing was quite fun… The constant thinking and guessing about what could it be and how to open it connected the people on the IRC channel a little more.