This is a mini challenge hosted by Intigriti at https://hackdonalds.intigriti.io/.
- Difficulty:
Easy - No source code is provided this time (so this is a black box test)
- DDoSing and Social Engineering are out of scope, everything else is allowed
/
The index of the website is a pretty simple landing page with the ability to go to either the menu or the admin section of the website. Not really many more things to note here :p
/menuA really cute menu page filled with references to certain vulnerabilities (0day nuggets, SQLi sundae :)). Nothing is clickable or interactive though, so doesn't peak much interest from the vulnerability side
/login
The most interesting page so far — this is the page you get redirected to if you try to access the 'admin' part of the site without actually being authorized. Presents you with an admin login page and requires a password to gain access.
When I discovered that login page, the first thing I tried was just trying some basic combinations (leaving it empty, admin, 123456), also tried some basic SQL injection prompts (' OR 1=1 -- , the "SQLi Sundae" in the website menu gave me the idea it might be a hint and might work, buuut no :(). Then, I decided to look through my Caido HTTP History, and here's the first thing I saw -
- this thing uses Next! (the _next/static directory gives it away, but you can also use certain browser extensions, like Wappalyzer, to check what the website uses under the hood)
The absolute first thing that came to my mind was the recent and pretty critical CVE found in Next, which, assuming it uses a vulnerable Next version, could allow us to completely bypass the need for authorization! :)
Tip
If somehow you haven't done so yet, I really recommend to thoroughly read the amazing research that zhero, the CVE author, has done on this. link
In a nutshell, a normal user's page request processing in Next might look roughly something like this:
graph TD
A[Normal User] -->|GET /example| B{Next Middleware};
B --> C[Is the requested page public?];
C -->|Yes| D{Next Router};
C -->|No| G{"Is the user authenticated to view the page?"};
G -->|Yes| D;
G -->|No| H{Drop the request; HTTP 403 Forbidden or HTTP 401 Unauthorized error};
D --> E{/example/page.tsx};
E --> F{HTTP 200 OK; the page is served to the user};
Because of the vulnerability, it is possible to completely bypass the Next Middleware, so now the request flowchart might look something like this:
graph TD
A[Malicious User];
A -->|GET /example| D;
D{Next Router};
D --> E{/example/page.tsx};
E --> F{HTTP 200 OK; the page is served to the user};
To exploit this vulnerability, we need to add a x-middleware-subrequest header with one of these two values:
middleware:middleware:middleware:middleware:middleware- or
src/middleware:src/middleware:src/middleware:src/middleware:src/middleware
This depends on whether the project code is contained inside of the /src folder (2nd header value), or not (1st header value), but the sure way to know would be to just try them both!
I've thrown in a quick Match & Replace rule in Caido to automatically add this header to all outgoing requests -
And, guess what, with this rule enabled, we finally get access to the admin page! No password needed :)
/admin
The admin dashboard, has four buttons for navigation - "Ice Cream Machines", "Inventory Management", "Staff Schedule" and "Security Settings", but only the first one - Ice Cream Machines - actually works and redirects somewhere, the other three just add a hash, link to /admin#.
Clicking on the Ice Cream Machines button redirects you to /ice-cream-machines
/ice-cream-machines
Hey, there is a list of ice cream machines in our HackDonalds with some more interesting vulnerability references (XSShake Creator, Buffer OverCone), and, what is even more of a surprise, two of them are working! (if we believe the status, of course) Jokes aside, the only part of this page that interests us is the 'View Settings' button, which further redirects you to /ice-cream-detail/[id]
/ice-cream-detail/[id]This is really interesting - this page provides you with some XML about the ice-cream machine, giving you the ability to edit it, and then, by clicking the 'Parse Settings' button, send it to the backend, which parses the XML and then spits out the raw data.
Seeing some raw XML being parsed by the backend is always exciting - and the first vulnerability that should come to your mind when seeing XML is XML External Entity (XXE); which could allow us to read files locally (which then will allow us to, hopefully, find and leak the flag)
Intigriti actually has a really nice article about this vulnerability, which I've found really useful! :)
Tip
Read the Intigriti article about XXE here.
The first payload in the article (the one exploiting file inclusion) is the one that interests us the most; let's try it and see what comes of it :)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<data>
<post>
<post_title>&xxe;</post_title>
<post_desc>...</post_desc>
</post>
</data>Hey! And we were actually able to leak the /etc/passwd file on the server!
/etc/passwd is not what we're looking for though, we're looking for the flag. I think the hardest part of this challenge and the one I struggled with the most is finding the file
in which the flag is contained. I tried going into a bunch of user's (taken from the /etc/passwd) directories, checking for flag or flag.txt files, but found no luck.
Luck did strike though, when I saw this message by CryptoCat on Intigriti's discord server
So, the flag must be contained in some file within the application. Let's ask the question, what is a common file that can be found in every Node.JS project/package?
Right, package.json! That was the first one I tried after seeing the message, aaaand, jackpot! :)
The final XXE payload used:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data [
<!ENTITY xxe SYSTEM "package.json">
]>
<data>
<post>
<post_title>&xxe;</post_title>
<post_desc>...</post_desc>
</post>
</data>The flag: INTIGRITI{XXE_1n_Ic3Cr34m_M4ch1n3s}
Thank you for reading the writeup! <3