← Back to Writeups
HTBN/AWeb

Passman

XESXOR8/23/20262 min read
#web#htb#n/a

Passman

Platform: HackTheBox | Category: Web | Difficulty: N/A | Author: D3v0o0Nu11 | Date: 2026-02-10

Description

Pandora discovered the presence of a mole within the ministry. To proceed with caution, she must obtain the master control password for the ministry, which is stored in a password manager. Can you hack into the password manager?

Solution Approach

Core idea: Identify the weakness from source review or fingerprinting first. Iterate with incremental payloads instead of guessing.

Steps

  1. Analyzing the entrypoint.sh, it seems the objective is to login as admin, because the flag is hardcoded there, and we can't login easily as admin, because the password is the flag.

SNIPPET OF ENTRYPOINT.SH

INSERT INTO passman.saved_passwords (owner, type, address, username, password, note)
VALUES
    ('admin', 'Web', 'igms.htb', 'admin', 'REDACTED', 'password'),
    ('louisbarnett', 'Web', 'spotify.com', 'louisbarnett', 'YMgC41@)pT+BV', 'student sub'),
    ('louisbarnett', 'Email', 'dmail.com', 'louisbarnett@dmail.com', 'L-~I6pOy42MYY#y', 'private mail'),
    ('ninaviola', 'Web', 'office365.com', 'ninaviola1', 'OfficeSpace##1', 'company email'),
    ('alvinfisher', 'App', 'Netflix', 'alvinfisher1979', 'efQKL2pJAWDM46L7', 'Family Netflix'),
    ('alvinfisher', 'Web', 'twitter.com', 'alvinfisher1979', '7wYz9pbbaH3S64LG', 'old twitter account');

GRANT ALL ON passman.* TO 'passman'@'%' IDENTIFIED BY 'passman' WITH GRANT OPTION;
FLUSH PRIVILEGES;
EOF

/usr/bin/supervisord -c /etc/supervisord.conf
  1. Notice the web application using graphql to manage interactions with the database, knowing it uses graphql, hence the approach here unlikely to be SQLi.
  2. Anyway after analyzed the GraphqlHelper.js, notice the UpdatePassword mutation does not require any validation.
UpdatePassword: {
            type: ResponseType,
            args: {
                username: { type: new GraphQLNonNull(GraphQLString) },
                password: { type: new GraphQLNonNull(GraphQLString) }
            },
            resolve: async (root, args, request) => {
                return new Promise((resolve, reject) => {
                    if (!request.user) return reject(new GraphQLError('Authentication required!'));

                    db.updatePassword(args.username, args.password)
                        .then(() => resolve(response("Password updated successfully!")))
                        .catch(err => reject(new GraphQLError(err)));
                });
            }
        },
  1. It accepts both username and password, but not checks who we are. Seems the vuln here is IDOR.

FLOW

REMEMBER THE VULN IS IDOR

- It's very straightforward, we just need to make an account, then login.
- Next we intercept the request to refresh the page using burpsuite and grab our cookie.
- Logout and intercept the login request.
- At the request tab, we change the mutation to UpdatePassword, the username to admin, and the password as random character.
- Then we use the cred to login --> get flag.
  1. Try that.

INTERCEPT REQUEST --> CHANGE THE MUTATION TO UPDATE PASSWORD AND THE CREDS.

LOGIN

  1. Got the flag!

Flag

REDACTED

Lessons Learned

  1. Identify the weakness from source review or fingerprinting first.
  2. Iterate with incremental payloads instead of guessing.
  3. Reuse the same pattern in future engagements.