Challenge Title: Valenfind Category: Web Difficulty: Medium

None

The target web app is running on port "5000".

None

Before exploring the app, I ran an initial `nmap` scan to check for other exposed services.

None

The service fingerprint on port `5000` shows: `Server: Werkzeug/3.0.1 Python/3.12.3`

That strongly suggests a Flask application, and port `5000` is Flask's default dev port.

I then used Burp Suite proxy and started interacting with the web app.

None

I began with the signup flow.

After submitting credentials on `/register`, the app redirected me to `/complete_profile`.

None

After completing the profile, the app redirected me to `/dashboard`.

None

I tested profile actions like **Like** and **Send Valentine** while watching traffic in Burp.

On `/profile/cupid`, I found this JavaScript comment:

function loadTheme(layoutName) {
        // Feature: Dynamic Layout Fetching
        // Vulnerability: 'layout' parameter allows LFI
        fetch(`/api/fetch_layout?layout=${layoutName}`)
            .then(r => r.text())
            .then(html => {
                const bioText = "I keep the database secure. No peeking.";
                const username = "cupid";
                
                // Client-side rendering of the fetched template
                let rendered = html.replace('__USERNAME__', username)
                                   .replace('__BIO__', bioText);
                
                document.getElementById('bio-container').innerHTML = rendered;
            })
            .catch(e => {
                console.error(e);
                document.getElementById('bio-container').innerText = "Error loading theme.";
            });
    }
None

The comment clearly points to an LFI issue.

`loadTheme()` is triggered when the profile theme changes, and it sends the `layout` value to the backend.

None

I sent this API request to Burp Repeater and tested path traversal payloads.

First test was `/etc/passwd` with:

`../../../../etc/passwd`

It worked.

None

Next, I enumerated files and successfully read the main app source at:

`/opt/Valenfind/app.py`

None

The key clue came from `app.py`.

It exposes an admin database export route: `/api/admin/export_db`.

The code also includes a hardcoded admin API key.

By sending that key in the `X-Valentine-Token` header, the database can be downloaded.

None

I sent the request with the token and got the flag in plain text in the response.