Challenge

A web app backed by Firebase. The database rules were wide open, so the whole tree could be read from the client:

1
2
3
firebase.database().ref('/').once('value').then((snapshot) => {
  console.log(snapshot.val());  // dumps everything
});

Approach

The dumped data held a flag structure that was a linked list rather than a string: each node had a character (chr) and a next field containing an expression to evaluate for the index of the following node. Walk it, evaluating next each step:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import json
data = json.load(open('chall.json'))
flag_chars, i = [], 0
while i is not None:
    item = data["flag"][i]
    flag_chars.append(item["chr"])
    try:
        nxt = eval(item["next"])
        i = int(nxt) if isinstance(nxt, (float, int)) and 0 <= int(nxt) < len(data["flag"]) else None
    except Exception:
        i = None
print(''.join(flag_chars))

Flag

UDCTF{JS0N_1n_tr33}