> For the complete documentation index, see [llms.txt](https://sarpers-organization.gitbook.io/ctftricks/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sarpers-organization.gitbook.io/ctftricks/_chapter-intro-6/credentials/trick-0182.md).

# Credential Discovery in Source Code

***

Developers often hardcode sensitive information like database credentials or API keys directly in application source code or configuration files. After gaining filesystem access (e.g., via RCE or a shell in a container), look for common configuration file names (like `config.py`, `settings.py`, files containing `db`, `secrets`, etc.) or environment variable files (`.env`).

Examine these files for hardcoded values. For example, if `/app/app/db.py` is found:

```bash
cat /app/app/db.py
```

This might reveal something like `DATABASE_URL = os.getenv("DATABASE_URL", "postgresql://postgres:postgres@172.22.0.1/mentorquotes_db")`, exposing usernames and passwords.

Beyond `.py` files, credentials can be stored in various formats. Configuration files are a common way to store settings, including sensitive data. Ini files are a simple format often used. You can access them in Python using the `configparser` module. An attacker finding a `config.ini` file might find content like:

```ini
[database]
user = admin
password = sUp3rS3cr3t
host = localhost
port = 5432
dbname = app_db
```

And the corresponding Python code to read it would look like this:

```python
import configparser

config = configparser.ConfigParser()
config.read('config.ini')
db_user = config['database']['user']
db_password = config['database']['password']
```

Using a `.env` file with libraries like `python-dotenv` is another popular method to manage variables outside the source code. The `.env` file is a simple text file containing key-value pairs:

```dotenv
DATABASE_URL="postgresql://user:password@host:port/dbname"
DB_USER="myuser"
DB_PASSWORD="mypassword"
API_KEY="sk-xxxxxxxxxxxxxxxxxxxx"
```

The `python-dotenv` library allows you to load these variables from the `.env` file into your application’s environment. A Python script would use `load_dotenv()` to load the variables and `os.getenv()` to retrieve them:

```python
from dotenv import load_dotenv
import os

load_dotenv() # take environment variables from .env.

# Accessing variables
db_user = os.getenv("DB_USER")
db_password = os.getenv("DB_PASSWORD")
api_key = os.getenv("API_KEY")
```

Credentials might also be stored in a simple text file, one per line. An attacker finding a `credentials.txt` file might see:

```
admin_user
my_secret_password
```

And the Python code to read this would involve opening and reading the file line by line:

```python
with open('credentials.txt', 'r') as f:
    username = f.readline().strip()
    password = f.readline().strip()
```

Another approach is to put credentials in a separate Python file (e.g., `db_credentials.py`) and import the variables. This file might look like:

```python
host = "localhost"
user = "app_user"
password = "YetAnotherHardcodedPassword"
dbname = "app_db"
```

The main application script would then import these directly:

```python
from db_credentials import host, user, password, dbname

# Use these variables to connect
```

Identifying and examining these various file types and the code used to access them is crucial during post-exploitation reconnaissance to uncover hardcoded secrets. Environment variables themselves, while often used to *avoid* hardcoding in source, can also be dumped if an attacker gains shell access to the running process or system.
