Hack The Box - Passman

March 24, 2023

passman

Passman is a web challenge that features a password manager application built with GraphQL. Analysis of the code reveals an insecure direct object reference vulnerability in the UpdatePassword function within the mutationType schema. This vulnerability can be exploited to change the password of the admin user by using a session cookie of a newly registered user. Signing in to the admin user's account provides access to the flag.

Initial visit to the Docker instance brought up a login page:

login page

Viewing the code provided with the challenge showed that it was built using GraphQL and entrypoint.sh showed that the flag was located in the admin user's account.

There was an option to create a new account, so I registered a new user mike:

mike register

Dashboard after logging in:

dashboard mike

After further analysis of the code, I found a /graphql route which contained the schema.

graphql route

I sent the following query from HackTricks to the /graphql route which extracts the types, names, fields, and arguments from the database schema.

?query={__schema{types{name,fields{name,args{name,description,type{name,kind,ofType{name, kind}}}}}}}

graphql schema

The UpdatePassword function seemed worth taking a look at.

schema update password

Here's the UpdatePassword function code:

UpdatePassword mutation resolver function

The UpdatePassword function takes two arguments username and password, but the function isn't checking if the authenticated user has permission to update the password of the user specified in the username argument. It simply checks if the user attempting to update the password is authenticated at all. This means that any authenticated user's session cookie can be used to update the password of any other user on the system by changing the value of the username argument when sending a query to the database.

In other words, the function is blindly accepting the username and password arguments as long as the session cookie being used belongs to any user on the system, it doesn't necessarily need to belong to that specific user.

This is an example of insecure direct object reference, which is when a direct object reference based on user input can be leveraged, in this case username, to access unauthorized resources or perform unauthorized actions.

Since the UpdatePassword function code was vulnerable to IDOR, I was able to use the session cookie of the user I created (mike) to update the password of the admin user with the following payload:

{
  "query": "mutation { UpdatePassword(username: \"admin\", password: \"admin\") { message } }"
}

admin password change

The response returned "Password updated successfully!", so I tried logging in as the admin user with the updated password:

login admin

It worked, and brought me to the dashboard for admin:

admin dashboard

Only thing left was to view the password and reveal the flag:

admin flag


CTF Writeups | InfoSec Topics

Written by Mike Garrity

Email RSS