Finding a Hardcoded Database Password in a Web App Config File

Privilege Escalation & Post-Exploitation Level 2/5 ~3 min 2026-06-17

The challenge

You popped a shell on a web server as www-data. The app reads its database password from a file in the web root. Explore the shell, read the right file, and submit the password.

What you'll learn

  • Recognise where PHP and other web apps store database connection settings
  • Use basic shell recon to list the web root and read a config file
  • Search source and config for credential keys like db_pass and password
  • Explain how a readable config turns web access into database access
  • Apply the standard fix: environment variables and a secret manager

Skills tested

Shell recon and file enumerationConfiguration and source reviewCredential discoveryWeb application post-exploitation

Prerequisites

  • Comfortable with basic shell commands (ls, cat, grep)
  • Can read a simple PHP configuration file

How it works

Every web application that talks to a database needs a username and password to open that connection. In PHP projects those settings almost always live in a small configuration file - typically config.php - that sits right next to index.php in the web root and is pulled in with require or include. The same pattern shows up everywhere else under different names: settings.py for Django, application.properties for Spring, .env for Node and Laravel, and docker-compose.yml for containerised stacks.

Storing the credential in a file that ships with the app is convenient, but it is also the weakness this challenge exercises. Once you have any read access to that file - a low-privilege shell as the web server user, a path traversal bug, an exposed .git directory, or simply a teammate cloning the repository - the database password is in plain sight. Unlike a stolen session that expires, a leaked database credential often grants direct, persistent access to every row the app can see.

Finding the secret is mostly about knowing where to look. From a shell, the fast path is to list the web directory, spot the config file, and read it; a recursive grep for keywords such as password, passwd, or db_pass surfaces the same value if the filename is not obvious. The credential is stored so the app can send it to the database, so it is kept in plain text, not hashed - which is exactly why reading the file is enough.

Common mistakes

  • Hunting for the password in the wrong place. The credential is not in /etc/passwd (that file holds user accounts, not app secrets) - it lives in the application's own config next to the front controller.
  • Only checking the obvious file. Credentials are often duplicated in an example config, a backup such as config.php.bak, or a commented-out line left over from testing.
  • Ignoring version control history. A password removed from the current file may still sit in an earlier commit, recoverable with the git log.
  • Assuming a random-looking value is hashed. A database connection string keeps the password in clear text so the app can authenticate - it is not a one-way hash.

How to defend against it

The durable fix is to keep secrets out of files that ship with the code, so reading the web root never reveals them:

  • Load the database credential from an environment variable at runtime instead of hardcoding it in config.php.
  • Store and rotate it in a secret manager - a vault service or your cloud provider's secrets store - rather than on disk in the web root.
  • Add any secret-bearing file to .gitignore and commit only a .env.example with placeholder values.
  • Run a secret-scanning tool in CI so a credential is caught before it ever reaches the remote.

If a credential has already been committed or exposed, treat it as burned and rotate it immediately. Deleting the line is not enough, because the old value remains in the git history and in any backups - change the database password and update the running app to use the new secret.

Full solution

Pro and Max members unlock the complete step-by-step walkthrough.

Go Pro

Community stats

28 completions
67% success rate
Butch First blood

Go deeper

Related Daily Hacks

15,000+ Hackers 100+ Labs & Courses Free
Start Hacking Free