在本节中,我们将介绍LDAP攻击。LDAP通常用作身份验证的后端,尤其是在单点登录(SSO)解决方案中。LDAP有自己的语法,我们将在以下示例中更详细地看到。
如有不懂什么是LDAP请查看
Example 1
在第一个示例中,使用您的用户名和密码连接到LDAP服务器。在这种情况下,LDAP服务器不会对您进行身份验证,因为您的凭据无效。
但是,某些LDAP服务器授权NULL绑定:如果发送NULL空值,LDAP服务器将继续绑定连接,并且PHP代码将认为凭据是正确的。 要获取具有2个空值的bind绑定,您需要从查询中完全删除此参数。 如果您在URL中保留了username=&password=之类的内容,则这些值将不起作用,因为它们不会为null; 相反,它们将是空的。
这是对将来要测试的所有登录表单执行的重要检查,即使后端不是基于LDAP的。
Example 2
最常见的LDAP注入模式是能够注入过滤器。在这里,我们将看到如何使用LDAP注入来绕过身份验证检查。
首先,您需要学习一些LDAP语法。当您检索用户时,将根据其用户名使用以下内容:
(cn=[INPUT])
如果要添加更多条件和一些布尔逻辑,可以使用:
- 布尔OR使用|: (|(cn=[INPUT1])(cn=[INPUT2]))获取匹配的记录[INPUT1]或[INPUT2]。
- 布尔值AND使用 &: (&(cn=[INPUT1])(userPassword=[INPUT2]))获取cn匹配[INPUT1]和密码匹配的记录[INPUT2]。
如您所见,布尔逻辑位于过滤器的开头。由于您可能会在它之后注入,因此并不总是可以(取决于LDAP服务器)在过滤器内部注入逻辑,如果它只是(cn=[INPUT])。
LDAP经常使用通配符*字符来匹配任何值。这可以用于匹配所有*或只是子串(例如,adm*对于所有以单词开头的单词adm)。
与其他注入一样,我们需要删除服务器端代码添加的任何内容。我们可以使用NULL BYTE(编码为%00)来消除过滤器的结尾。
在这里,我们有一个登录脚本。我们可以看到,如果我们使用:
- name=hacker&password=hacker 我们得到认证(这是正常的请求)。
- name=hack*&password=hacker 我们得到验证(通配符匹配相同的值)。
- name=hacker&password=hac* 我们没有经过身份验证(密码可能会被散列)。
现在,我们将看到如何在name参数中使用LDAP注入来绕过身份验证。根据我们之前的测试,我们可以推断过滤器可能看起来像:
(&(cn=[INPUT1])(userPassword=HASH[INPUT2]))
其中HASH是未加盐的哈希值(可能是MD5或SHA1)。
LDAP支持多种格式:`{CLEARTEXT}`, `{MD5}`, `{SMD5}` (salted MD5), `{SHA}`, `{SSHA}` (salted SHA1), `{CRYPT}`用于储存密码。
由于[INPUT2]是哈希,我们不能用它来注入我们的有效载荷。
我们这里的目标是注入内部[INPUT1](用户名参数)。我们需要注入:
使用当前过滤器的结尾hacker)。
始终为真的条件(例如(cn = *))
一个)保持有效的语法并关闭第一个)。
一个NULL BYTE(%00)来摆脱过滤器的结束。
一旦你把它放在一起,你应该可以使用任何密码登录hacker这个用户名。
然后,您可以尝试使用通配符技巧查找其他用户。 例如,您可以在过滤器的第一部分中使用a*,并检查您登录的对象。
在大多数情况下,LDAP注入只允许您绕过身份验证和授权检查。 检索任意数据(而不仅仅是获得更多结果)通常非常具有挑战性或不可能。