> For the complete documentation index, see [llms.txt](https://maurvan.gitbook.io/ctf-writeups/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://maurvan.gitbook.io/ctf-writeups/bluehens-ctf-2024/index/lists-of-jsons.md).

# lists of JSONs

## Challenge

> Web...ish...
>
> <https://lists-of-jsons.web.app/>

## Solution

When we click on the link, we end up on a simple webpage with a list of values.

<figure><img src="/files/pfuEZwQLuJboJToihXvY" alt=""><figcaption></figcaption></figure>

Using [Wappalyzer](https://www.wappalyzer.com/) you can see there's some Firebase database behind it.

<figure><img src="/files/RYIyu3r4eia1sqcpWkcu" alt=""><figcaption></figcaption></figure>

Using our Developer Tools, we can see there's some interesting public information in the `init.js` file.

<figure><img src="/files/iWcqRSr3b5I1M4Fp0f1k" alt=""><figcaption></figcaption></figure>

Thanks to this we have the database url and we can access the .json file by going on this page: `https://lists-of-jsons-default-rtdb.firebaseio.com/flag.json`

Now it's just a question of rebuilding the flag by following the clues. I let ChatGPT build me a Python script that does all the work for me.

```python
import json

# Replace 'your_file.json' with the path to your JSON file
file_path = '/path/to/my/flag.json'

# Read the JSON file
with open(file_path, 'r') as file:
    data = json.load(file)

# Ensure that the data is a list
if isinstance(data, list):
    # Starting point: index 251
    current_index = 251
    phrase = ""  # To concatenate the 'chr' values into a phrase

    while current_index < len(data):
        # Get the current item (dictionary)
        item = data[current_index]

        if 'chr' in item and 'next' in item:
            # Append the 'chr' value to the phrase
            chr_value = item['chr']
            phrase += chr_value
            print(f"Visited index {current_index}, chr = {chr_value}")

            # Check if we've reached the end of the phrase
            if chr_value == "}":
                print(f"End of phrase reached at index {current_index}.")
                break

            # Evaluate the "next" operation to get the next index
            try:
                next_index = int(eval(item['next']))  # Evaluate the operation (e.g., '1627 - 1151')
                print(f"Next operation: {item['next']} => {next_index}")
                
                # Check if the next index is within bounds
                if 0 <= next_index < len(data):
                    current_index = next_index  # Update current index
                else:
                    print(f"Next index {next_index} is out of bounds. Stopping.")
                    break
            except Exception as e:
                print(f"Error evaluating operation '{item['next']}' for index {current_index}: {e}")
                break
        else:
            print(f"Missing 'chr' or 'next' at index {current_index}. Stopping.")
            break

    # Print the final concatenated phrase
    print(f"\nThe final concatenated phrase is: {phrase}")
else:
    print("The data is not a list as expected.")
```

After running it, we get our flag.

<figure><img src="/files/svfDuQgU4cMCLW8s1P12" alt=""><figcaption></figcaption></figure>
