# HackDonalds Intigriti CTF 2025

Welcome back to my writeup!! In this post, I’ll walk you through how I successfully pwned the **HackDonalds** challenge by **Intigriti**, a web exploitation challenge that pushed me to think critically about common web vulnerabilities. I’ll cover the entire process step by step—from how I approached the target, to identifying the core vulnerability, and ultimately exploiting it to gain control. Along the way, I’ll share the tools, techniques, and thought process I used to solve the challenge, making this write-up a solid learning resource for anyone diving into web hacking or CTFs.

**Enumeration**

Here's the site

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2Fp9MegtGJPus1H3eLd9sM%2FScreenshot%20(771).png?alt=media&#x26;token=7e6de048-ad76-4753-9afd-a7c5f25ae845" alt=""><figcaption></figcaption></figure>

As you can see, there's an admin panel

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FayISO07f1YXXcPQFHSp2%2FScreenshot%20(772).png?alt=media&#x26;token=3f5653c9-4449-481b-ad78-88767b4cafb3" alt=""><figcaption></figcaption></figure>

We’ll tackle this challenge with a bug bounty mindset. After reading some initial information about it, I found out that the vulnerability was based on a recently disclosed CVE. So, I decided to use **Nuclei** to scan and enumerate all the known CVEs from 2025 to pinpoint the exact one being used.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FB6TeiBk4JwrhaxPiUFFF%2FScreenshot%20(773).png?alt=media&#x26;token=557bc927-4e08-420c-8e0f-7ed4f9b4ea9a" alt=""><figcaption></figcaption></figure>

It turns out the vulnerability in this challenge is **CVE-2025-29927 (Next.js Middleware Bypass)**. To understand it better, I searched for documentation and I found out that this vulnerability impacts the middleware feature in **Next.js**, which is often used for things like authorization, URL rewriting, server-side redirects, and setting response headers such as CSP. When exploited, it allows an attacker to **bypass these controls entirely** by including a specially crafted `x-middleware-subrequest` header in their HTTP requests.

**What is Next.js Middleware?**

Next.js middleware is a powerful tool that lets developers execute code before a request is fully processed. According to the official Next.js documentation, **Middleware enables you to run code before a request is completed. Based on the incoming request, you can modify the response by rewriting URLs, performing redirects, changing request or response headers, or even sending a direct response.** This functionality serves a variety of purposes, with some of the most important use cases including:

* **Path rewriting** - Dynamically changing the requested path before it reaches the application logic.
* **Server-side redirects** - Redirecting users based on certain conditions
* **Adding response headers** - Including security headers like Content Security Policy (CSP)
* **Authentication and Authorization** - Ensuring user identity and checking session cookies before granting access to specific pages or API routes.

One common use of middleware is for handling **authorization**, where specific routes are protected based on certain conditions. For instance, when a user tries to access a restricted path like `/dashboard/admin`, the middleware steps in to verify the session cookies and check if the user has the appropriate permissions. If everything checks out, the request proceeds; if not, the user is redirected to the login page.

**How does the vulnerability actually work?**

The vulnerability in **CVE-2025-29927** arises from a design flaw in how Next.js handles the `x-middleware-subrequest` header. This header was originally intended for internal use within the Next.js framework to avoid infinite middleware execution loops. When middleware is used in a Next.js application, the `runMiddleware` function processes incoming requests. As part of this process, the function checks for the presence of the `x-middleware-subrequest` header. If the header is found and contains a specific value, the middleware is skipped, and the request is directly forwarded to its destination using `NextResponse.next()`. The issue is that this header check can be manipulated by external users. By adding the correct value to the `x-middleware-subrequest` header, an attacker can bypass any middleware-based security controls entirely. Here's how this vulnerability works at the code level

```javascript
const subreqHeader = params.request.headers["x-middleware-subrequest"];
const subrequestList = (typeof subreqHeader === "string") ? subreqHeader.split(":") : [];

if (subrequestList.includes(middlewareInfo.name)) {
  result = {
    response: NextResponse.next(),
    waitUntil: Promise.resolve(),
  };
  continue;
}
```

This code demonstrates that if the value of the `x-middleware-subrequest` header, when split by the colon character (:), contains the `middlewareInfo.name` value, **the middleware is completely bypassed.**

**Exploitation**

Now that we know the vulnerability, how can we exploit it?

We’ll be using Burp Suite for this! Before intercepting, I go to **Match and Replace** and modify the request by adding this.

```
x-middleware-subrequest: middleware
```

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FMMKnnHUYuioIUPaOhtgm%2FScreenshot%20(780).png?alt=media&#x26;token=a4789238-b07f-45a9-80df-ccda36c1887d" alt=""><figcaption></figcaption></figure>

Based on the documentation I reviewed, the next step is to identify the protected endpoint we want to access, which is clearly the **admin** page. So, I ran **Nuclei** again and modified the login endpoint to point to **admin**, and here’s the result.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2F8jU5UnCfFWFoW7hP0K4W%2FScreenshot%20(777).png?alt=media&#x26;token=6f587913-49de-4225-90c5-ca40ecbe9d83" alt=""><figcaption></figcaption></figure>

It's confirmed. Now, all we need to do is intercept the **admin** endpoint, and once intercepted, here’s the request

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FXBfsHnCNVDhSDzPclUv4%2FScreenshot%20(781).png?alt=media&#x26;token=19be0c47-93cd-4566-b932-e7f5dc7c646c" alt=""><figcaption></figcaption></figure>

As you can see at the very bottom, our payload has been successfully added. From here, we just need to forward the request and disable interception.

Going back to our browser, here's the result

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FRcVZbHrJv3mIg8OwEK5K%2FScreenshot%20(783).png?alt=media&#x26;token=a0007aa8-8941-43e9-be4b-56bd4391fd7f" alt=""><figcaption><p>We're now admin!!!!</p></figcaption></figure>

While exploring the admin dashboard, I noticed that one of the ice cream machines includes an option to edit the XME configuration.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FsyM5yAY3NQCd1SAaOX9K%2FScreenshot%20(786).png?alt=media&#x26;token=69496329-fdbb-4015-80a9-e7646b3bc889" alt=""><figcaption></figcaption></figure>

Hmm, when dealing with this kind of application, the first thing that probably comes to mind is an **XXE (XML External Entity) vulnerability**, right? You guessed it! So, I started searching for some XXE payloads and came across this one.

```html
<!DOCTYPE test [<!ENTITY abc SYSTEM "file://etc/passwd">]>
<products>
    <product>
        <description>&abc;</description>
    </product>
</products>
```

Parsed it and here's the result

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2Fb26xa8xmqMrxCSlgSidM%2FScreenshot%20(787).png?alt=media&#x26;token=33b1670d-d0eb-4366-97d2-407e5cb5fa6e" alt=""><figcaption></figcaption></figure>

It worked!!! Now, the real challenge begins, where's the flag? This part is a bit tricky because we can read file contents, but we don’t have the ability to browse through directories to locate where the flag is stored.&#x20;

After long time of determining where the flag is, I realized that this application is running in **node**, so the first thing I did is to look for **package.json**, which is **metadata file** used in **Node.js** projects (especially with **npm** or **yarn**) to manage the project’s dependencies, scripts, and settings.&#x20;

```html
<!DOCTYPE test [<!ENTITY abc SYSTEM "file://package.json">]>
<products>
    <product>
        <description>&abc;</description>
    </product>
</products>
```

Unfortunately, this one does not work, but when I only specify the file name without **file://,**&#x20;

```html
<!DOCTYPE test [<!ENTITY abc SYSTEM "package.json">]>
<products>
    <product>
        <description>&abc;</description>
    </product>
</products>
```

This is the output

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2F6KaB9OSQ1vfueVoR44st%2FScreenshot%20(789).png?alt=media&#x26;token=e49e43b4-a46f-4660-9712-d762b706a6ed" alt=""><figcaption></figcaption></figure>

This second payload works, and we got the the flag!!

Now why does the first payload failed? (But worked in **/etc/passwd**)

Few reasons:

1. The **file://** scheme with an absolute path (**/etc/passwd**) explicitly points to a well-known file on Unix-like systems. The parser resolves this as a full filesystem path, and if the application has sufficient permissions (e.g., running as a privileged user or in an insecure container), it can access /etc/passwd.
2. The parser allows relative paths or the current working directory contains **package.json**. That's why just **package.json** alone works.&#x20;

**Conclusion**

This CTF challenge from **Intigriti** was an exciting and engaging experience! It tested not only technical knowledge but also the ability to think critically and adapt quickly to unexpected scenarios. From identifying and exploiting the Next.js middleware bypass vulnerability (CVE-2025-29927) to crafting payloads for an XXE attack within the admin dashboard, each step pushed the boundaries of web exploitation. Overall, it was a great exercise in modern vulnerability exploitation, and I thoroughly enjoyed diving into it!
