Hacking
Writeups
Misc
HeatKeeb

HeatKeeb

Description

CTF: STACK the Flags 2022

Jaga had gained interest in custom keyboards and has created a platform to create your own keebs! We know we created his custom keeb on the 22nd of September 2022, at 09:41:17 SGT. Oddly specific but we know it's true.


misc_heatkeeb.zip

Solution

Pwned by @skytect (opens in a new tab) and @fishjojo1 (opens in a new tab)

Let's open up the webpage.

Webpage

It seems that we need a token. Let's check out the source code.

# app.py L98–L135
@app.post("/build")
def build(
    request: Request,
    name: str = Form(...),
    frameColor: str = Form(...),
    keyColor: str = Form(...),
    textColor: str = Form(...),
    specialColor: str = Form(...),
):
    t = datetime.datetime.now(pytz.timezone("Asia/Singapore"))
    seed = int(t.timestamp())
    random.seed(seed)
    token = "".join(
        random.choices(
            "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", k=16
        )
    )
    with shelve.open("keebdb") as db:
        db[token] = {
            "name": name,
            "frameColor": hex_to_rgb(frameColor),
            "keyColor": hex_to_rgb(keyColor),
            "textColor": hex_to_rgb(textColor),
            "specialColor": hex_to_rgb(specialColor),
            "text": "default",
        }
    img = draw_keeb(
        name,
        hex_to_rgb(frameColor),
        hex_to_rgb(keyColor),
        hex_to_rgb(textColor),
        hex_to_rgb(specialColor),
    )
    img.save(f"keebs/keeb-{token}.png")
    request.session["token"] = token
    return templates.TemplateResponse(
        "build.html", {"request": request, "resp": "Success!", "token": token}
    )

The seed is based on the time :0 Let's try to generate the seed based on the time given in the description.

import datetime
import pytz
import random
 
t = datetime.datetime(2022, 9, 22, 9, 41, 17, 0)
seed = int(t.timestamp())
random.seed(seed)
token = "".join(
    random.choices(
        "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", k=16
    )
)
print(token)  # rMwwbpMkzAwyRoWs

Using the seed, we can access Jaga's keeb!

Webpage

Let's go back to the code to find where the flag is.

# app.py L237–L251
@app.post("/text")
def flag(request: Request, text: str = Form(...)):
    if "token" in request.session:
        with shelve.open("keebdb") as db:
            token = request.session["token"]
            if token in db:
                if token == ADMIN_TOKEN and text.upper() == KEY:
                    return templates.TemplateResponse(
                        "flag.html", {"request": request, "word": text, "flag": FLAG}
                    )
                elif text.upper() == db[token]["text"]:
                    return templates.TemplateResponse(
                        "flag.html", {"request": request, "word": text}
                    )
    return templates.TemplateResponse("flag.html", {"request": request})

It seems that we need to key the matching word in the following text field somehow.

Webpage

If we explore further around the GUI, we find that we can generate a heatmap of the word.

Webpage

Looking at our keyboard, the hotspots appear to make out the letters asertghnil. Let's try to unscrable the letters.

Webpage

When we key in earthlings to check the latest favourite word, we get the flag!

STF22{h34t_k3yb04rD}