BluehensCTF web/lists_of_JSONs
My solution for BluehensCTF web/lists_of_JSONs challenge
Challenge overview
The challenge involves a web application that interacts with a Firebase database. The goal is to extract a flag by traversing through nodes in a JSON structure where each node contains a character of the flag and a mathematical expression pointing to the next node.
Application structure
The application consists of:
- A Firebase realtime database hosting the flag data
- Main endpoint:
https://lists-of-jsons-default-rtdb.firebaseio.com/flag.json
- JSON array containing nodes with two properties:
chr
: Single character that is part of the final flagnext
: Mathematical expression leading to the next node
Analysis
Firebase Configuration
- Firebase initialization at:
https://lists-of-jsons.web.app/__/firebase/init.js?useEmulator=true
- Database URL:
https://lists-of-jsons-default-rtdb.firebaseio.com
JSON Structure
Each node in the array follows this format:
1
2
3
4
{
"chr": "U",
"next": "3040479 / 1999"
}
The next
expression must be evaluated and its result modulo the total number of nodes gives the index of the next node to visit.
Identifying the vulnerabilities
- Predictable starting point
- Flag typically starts with ‘U’ (as in bluehens CTF flag format)
- Can find initial node by searching for this character
- Mathematical expression execution
- The
next
expressions are simple arithmetic that can be safely evaluated
- The
- Graph structure
- Each node points to exactly one other node
- The path forms a sequence that reveals the flag
- Contains termination conditions like
exit()
Crafting the exploit
Create Python script to traverse nodes and extract flag:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import requests
import re
def evaluate_expression(expr):
"""Safely evaluate mathematical expression."""
if not isinstance(expr, str):
return None
if not re.match(r'^[\d+\-*/()\s]+$', expr):
return None
try:
return int(eval(expr))
except:
return None
def parse_flag(url):
"""Parse flag from JSON data."""
response = requests.get(url)
data = response.json()
start_index = None
for i, node in enumerate(data):
if node.get('chr') == 'U':
start_index = i
break
if start_index is None:
return "Could not find starting node"
flag = []
current_index = start_index
visited = set()
total_nodes = len(data)
while current_index not in visited:
visited.add(current_index)
node = data[current_index]
flag.append(node['chr'])
next_expr = node.get('next')
if next_expr in ('exit()', 'You got the flag'):
break
next_value = evaluate_expression(next_expr)
if next_value is None:
break
current_index = next_value % total_nodes
if len(flag) > total_nodes:
break
return ''.join(flag)
if __name__ == "__main__":
url = "https://lists-of-jsons-default-rtdb.firebaseio.com/flag.json"
flag = parse_flag(url)
print(f"Flag: {flag}")
Running the script:
1
Flag: UDCTF{JS0N_1n_tr33}
Conclusion
This challenge demonstrates the importance of understanding graph traversal algorithms and safe mathematical expression evaluation. By systematically following the node chain and carefully evaluating expressions, we were able to reconstruct the flag from the distributed characters.
Key takeaways
- Safe expression evaluation
- Always validate and sanitize mathematical expressions before evaluation
- Use regex patterns to restrict allowed operations
- Handle potential evaluation errors gracefully
- Graph traversal considerations
- Track visited nodes to prevent infinite loops
- Implement proper termination conditions
- Use modulo operation to keep indices within bounds
- Data structure analysis
- Understanding JSON structure and traversal patterns
- Identifying starting points in node chains
- Handling edge cases in data processing