Playing with internal path traversal leads to a lot of fun
Table of Contents
Hello There :)
It’s been a while since my last post, sorry for that.
To make up for it, i will talk about a pretty cool vulnerability i found !
I hope you will like it and it will give you nice ideas for the future vulns you will find :)
Appetizer
Well, this story is about a vulnerability i found when enjoying time with friends !
There was a company who paid us a trip to their HQ, speaking about our experiences and stuff.
But, as you know me, A way to have a ton of fun is by digging into applications to find vulnerabilities ;)
Primer
Before anything else, some of you may not know what I mean by Internal Path Traversal
, so let me clarify.
Basically, a Path Traversal
is a vulnerability that lets you move around an application’s directories arbitrarily, in ways that weren’t intended.
An Internal Path Traversal
uses the same principle, except it applies to the call made by one application to reach another application.
In short, you make a request to application A, which then makes a request to application B, usually using the parameters you provided in your original request.
Here is a slightly more concrete example:
https://example.com/group.php?id=5&username=Kuromatae
https://api.example.com/Group/5/User/Kuromatae
https://example.com/group.php?id=5&username=Kuromatae/../../../6
https://api.example.com/Group/5/User/Kuromatae/../../../6
https://api.example.com/Group/6
Anyway, back to the point :)
Practice
So, I started working on an application from this company.
It was for getting goodies by answering questions to earn points (basically a little game).
This application was made using Next.JS.
As i was looking at it, i found there was a NextJS action vulnerable to Internal path traversal
.
As you can see here, if i do ["410220460/../410220460"]
, i have the exact same response as if i simply did ["410220460"]
.
Which made me think there is a Path Traversal
here.
I did some tests in order to confirm this and, as i tried to traversal to the root of the application, i was able to retrieve the full url of the application.
You probably wonder HOW i found this Internal Path Traversal
in the first place ?
Well, i’d say it’s not really hard to do so, you simply have to do things similar to what i did in the first screen and pray for it to return the same informations as if you didn’t put anything weird here…
When you see that the response is the same as the initial one, you try to go deeper into it to be sure it’s a Path Traversal
:)
Main Course
After finding out that this parameter was giving me an entry point to the API, i tried to poke it more and found some interesting information.
I started by looking for informations regarding CrowdTwist API: https://docs.oracle.com/en/cloud/saas/marketing/crowdtwist-develop/Developers/UserActivities.html
Unfortunately, after trying everything i could, i wasn’t able to do much with this Path Traversal
, here is what i found:
- The API is CrowdTwist
- We can't change the request method
- The
apiKey
is sent in the url as parameter meaning it's not possible to add parameters to our request - The
UserID
use one of the following forms:- Third Party ID
- CrowdTwist ID
- Email Address
- Mobile Phone Number
- Facebook User ID
- Twitter User ID
- User Name
Obviously, i tried everything i could, i even did a bit of Bruteforce on the UserID
as there was an example on the API Doc but, without success…
Dessert
As i was working on this application, i had to do some pictures for the company.
I took my computer and continued to work while doing it and, this is when my brain started to do many different tries.
Then, looking back at how the other request on the website were done, i thought “why not try to send another parameter?”
So, this is what i did and then, i saw that a second request was done in the response.
My request was like this:
[
"410223480/../../../../../../../foobar",
"xxxx"
]
And the response received was:
0: ["$@1", ["NVkDou1nig_jVfc89raAl", null]]
1: {
"survey": {
"exception": "iapi_Version_Mismatch_Error",
"script_uri": "http://[REDACTED].crowdtwist.com/foobar",
"remote addr": "[REDACTED]"
},
"response": {
"exception": "iapi_Version_Mismatch_Error",
"script_uri": "http://[REDACTED].crowdtwist.com/foobar/response",
"remote addr": "[REDACTED]"
}
}
But seeing how the response was done, i thought “what about an ID which shouldn’t have a second parameter ?”
Yes because, remember, we are on an application where you answer questions but, what if the ID i use doesn’t expect answers ?
Bingo !
The response was leaking my UserID and, guess what ? It was incremental ;)
I checked back the documentation and then, i found the endpoint i was able to call using it: https://docs.oracle.com/en/cloud/saas/marketing/crowdtwist-develop/Developers/UserProfile.html
So, i tried the full path traversal and … It worked !
I was able to retrieve the PII of all the other users :D
Digestive
In the end, this vulnerability was really interesting and even helped me better understand how NodeJS works.
After finding the vulnerability, it took me a good hour to figure out how it was all tied together / how to turn it into something concrete!
I want to thank everyone who was there to share the moment, as well as the company that invited me so we could all have a great time together :)
Thank you for reading !
~ Kuromatae