Table of Contents

Team

Our team Hague Hackers placed #53 with 523 points.

Early on we almost got into the top 10, but oh well πŸ™‚

Sniff one

  • category: hardware
  • README.pdf
  • The flag is in flag{} format

The complete setup with Saleae Logic 8 sniffer.

We can open the capture.sal file with Salea Logic 2.

The CardKB Mini Keyboard communicates via I2C.

  • SDA: channel 0
  • SCL: channel 1
  • I2C address: 0x5F (datasheet)

So we need to look for reads to 0x5F in the sniffed data and for β€œflag” which would be 0x66, 0x6C, 0x61, 0x67 according to the data sheet.

Surely enough we (Ardemium actually) found 0x66 followed by 0x6C.

I wrote a simple script to parse the text and ignore 0x0 and 0x1 values.

-- Lua
local data = {
    -- shared
    [0x31] = "1",
    [0x32] = "2",
    [0x33] = "3",
    [0x34] = "4",
    [0x35] = "5",
    [0x36] = "6",
    [0x37] = "7",
    [0x38] = "8",
    [0x39] = "9",
    [0x30] = "0",
    [0x20] = " ",
    [0x2C] = ",",
    [0x2E] = ".",
    -- default
    [0x71] = "q",
    [0x77] = "w",
    [0x65] = "e",
    [0x72] = "r",
    [0x74] = "t",
    [0x79] = "y",
    [0x75] = "u",
    [0x69] = "i",
    [0x6F] = "o",
    [0x70] = "p",
    [0x61] = "a",
    [0x73] = "s",
    [0x64] = "d",
    [0x66] = "f",
    [0x67] = "g",
    [0x68] = "h",
    [0x6A] = "j",
    [0x6B] = "k",
    [0x6C] = "l",
    [0x7A] = "z",
    [0x78] = "x",
    [0x63] = "c",
    [0x76] = "v",
    [0x62] = "b",
    [0x6E] = "n",
    [0x6D] = "m",

    -- sym modifier
    [0x21] = "!",
    [0x40] = "@",
    [0x23] = "#",
    [0x24] = "$",
    [0x25] = "%",
    [0x5E] = "^",
    [0x26] = "&",
    [0x2A] = "*",
    [0x28] = "(",
    [0x29] = ")",
    [0x7B] = "{",
    [0x7D] = "}",
    [0x5B] = "[",
    [0x5D] = "]",
    [0x2F] = "/",
    [0x5C] = "\\",
    [0x7C] = "|",
    [0x7E] = "β€”", -- em dash
    [0x27] = "'",
    [0x22] = "\"",
    [0x3B] = ";",
    [0x3A] = ":",
    [0x60] = "`",
    [0x2B] = "+",
    [0x2D] = "-",
    [0x5F] = "_",
    [0x3D] = "=",
    [0x3F] = "?",
    [0x3C] = "<",
    [0x3E] = ">",
    -- shift modifier
    [0x51] = "Q",
    [0x57] = "W",
    [0x45] = "E",
    [0x52] = "R",
    [0x54] = "T",
    [0x59] = "Y",
    [0x55] = "U",
    [0x49] = "I",
    [0x4F] = "O",
    [0x50] = "P",
    [0x41] = "A",
    [0x53] = "S",
    [0x44] = "D",
    [0x46] = "F",
    [0x47] = "G",
    [0x48] = "H",
    [0x4A] = "J",
    [0x4B] = "K",
    [0x4C] = "L",
    [0x5A] = "Z",
    [0x58] = "X",
    [0x43] = "C",
    [0x56] = "V",
    [0x42] = "B",
    [0x4E] = "N",
    [0x4D] = "M",
}

local blacklist = {
    [0x00] = true,
    [0x01] = true,
}

local f = io.open("keyboard.md", "r")
local t = {}
for l in f:lines() do
    local hex_string = l:match("read to 0x5F ack data: (0x%x%x)")
    local hex = tonumber(hex_string)
    if hex and not blacklist[hex] then
        -- print(hex, data[hex])
        table.insert(t, data[hex])
    end
end

print(table.concat(t))
-- flag{717f7532}

Waiting For a Flag

  • category: hardware
  • author: Oshawk

I first tried to decompile the game with Godot RE Tools but the project was encrypted so it required a key. Later I saw other people reverse engineered the binary anyway with IDA.

Then I tried to do it the intended(?) way since it looked kinda fun.

As we learn in the tutorial levels, we need to turn on the LED with the button switches and the AND, OR, NAND, NOT gates.

  • All the button switches are on the top level: 126 on the left, 116 on the right, total 242.
  • There are 71 layers to the level.
  • You have to deduce what kind of logic gates there are and in which direction their output is. This makes it especially challenging to know whether a gate is an OR or a NAND gate.

I started tracing and marking the relevant switches, nodes and gates in order to keep track of them.

I did not finish the challenge in time since I made a huge mistake in trying to get to the bottom layer. I assumed the LED was all the way at the bottom layer at layer 71, but it was simply in the middle of the top layer, connected to something else at layer 62 🀦

At least I activated the line on the lowest layer by enabling inputs 78 and 43, starting from the left. If you look really close you can notice that line is now red.

I still have no idea where it leads to further on 🀷