hofill > ./blog Crypto enthusiast.

mine-server

misc
minetest
sqlite

Legend

Challenge Description

We failed to find the hidden information on the server, here are the filles.

Flag format: CTF{xxxxxxxxxxxxxxxxxx_xxx}

Flag Proof

CTF{this_was_a_hidden_room_lol}

Summary

Search the map database to find all signs and their text

Details

We get a bunch of files for a game called minetest, and we have to find a secret, somewhere. The first thing I tried to do was downloading the game (using brew) and running the world with a player called Splasher (found in the logs file).

We spawned on top of a sign, saying Try harder. To find the flag, we thought that we had to search for all of the signs in the map and read them all.

We generated a top view of the map, which didn’t help much:

a.png

We then started going through the world files and found map.sqlite, which, according to the minetest documentation, contains information about the blocks (nodes of 16x16x16) that have been generated.

We opened it up and we found pos and data for all blocks:

Untitled

Afterwards, we read the official documentation for how these rows get filled:

https://github.com/minetest/minetest/blob/master/doc/world_format.txt

Untitled

Byte:

Untitled

Apparently, the bytes are zipped using zstd (not zlib), after being serialized.

I created a simple script to get all of the data and unzip it(skipping the first byte), then tried searching for just blocks that have a sign in them.

import os
import sqlite3

c = sqlite3.connect('map.sqlite')
rows = c.execute('SELECT data FROM blocks')
for row in rows:
    a = row[0][1:]
    with open('res.zst', 'wb') as y:
        y.write(a)
    os.system("zstd -d res.zst")
    with open('res', 'rb') as y:
        a = y.read()
        if b'sign' in a.lower():
            print(a)
    os.system('rm res')

After running this script for a while, we got two results. At the end of the first result, there was the flag:

\x00\x00\x00\x03\x00\x08formspec\x00\x00\x00\x14field[text;;${text}]\x00\x00\x04text\x00\x00\x00\x1fCTF{this_was_a_hidden_room_lol}\x00\x00\x08infotext\x00\x00\x003\x1b(T@default)"\x1bFCTF{this_was_a_hidden_room_lol}\x1bE"\x1bE\x00EndInventory\n\x00\x00\x00\n\x00\x00'

The second result was the initial Try harder sign.

Don’t chat too much about RSA! oootp