Galaxy Dash - prototype pollution
This challenge had the hint of prototype pollution. A nice vulnerability for a weekly lab!
After clicking around a bit, I went to my Burp history, to check my requests out and see if something stood out. I clicked A LOT. And I tried tampering with JWT, try to exploit possible logic issues, triggering some XSS, but all in all, I did not find a surface for prototype pollution.
This was mainly due to the fact that when I test for prototype pollution, I tend to check the frontend code, but I have not been exposed to the server-side vulnerability. And in this case, there was not much frontend code to analyze.
Because I did not find anything to go on, I decided to enumerate the API. I noticed that this was an API-driven application, and I wondered if there where any endpoints that weren't used by the frontend.

I got a different length on GET /api/admin , combined with the 403 status code, and the fact I didn't found this endpoint using the application, I discovered a hidden endpoint!
Not all wordlists that you find online will find this exact endpoint. For example the API list from SecList has no entry for /api/admin , it's important to have a wordlist like that for a basis, but if you encounter an endpoint that's not in your wordlist, you should manually add it.
When I actually tried to hit /api/admin , I found a clue.

The application checked if the user had a property is_admin , this was something I could work with. I noticed that there was a /api/team/:id endpoint during my investigation. On this endpoint I was able to adjust user permissions. Maybe this endpoint was vulnerable for prototype pollution.
Because testing for prototype pollution can have a big impact on the target (especially real targets), it's best to test if an application is vulnerable with a relatively harmless payload, rather than making everybody admin by accident. To do this you can use
Inside the request, there was a JSON-array with permissions, I placed the payload above inside the request.

If polluting worked, this payload makes a error code (599) when something goes wrong, you can easily check this by forcing the application to create an error. I did this by sending invalid JSON.

Seeing the error code 599 meant that the payload worked!
This payload DOES break production! So make sure to restore it with
after confirming that the payload worked.
So now I knew where to place my payload. Because the /api/admin endpoint needed a is_admin:true property, I tried to update a user once again.

This successfully went through. So now all that was left, was to check if I could reach /api/admin

And I could! Another flag 🇧🇪
Last updated