THMLDAPInjection
Introduction
LDAP 是轻量级目录访问协议 (LDAP) 的缩写,是一种广泛使用的协议,用于通过互联网协议 (IP) 网络访问和维护分布式目录信息服务。LDAP 使组织能够集中管理用户、群组和其他目录信息,这些信息通常用于 Web 和内部应用程序中的身份验证和授权。
目标
- 深入了解 LDAP 及其在目录服务中的作用。
- 探索 LDAP 树形结构及其关键组件。
- 介绍 LDAP 注入、其影响以及如何利用它。
- 使学员掌握识别和缓解 LDAP 注入漏洞的知识和技能。
先决条件
- 对目录服务的工作原理(尤其是 LDAP)有基本的了解。
- 掌握 Web 应用程序安全原则和常见漏洞的基本知识。
- 熟悉 LDAP 的结构和组件,例如可分辨名称 (DN) 和属性。
- 熟悉 Web 应用程序安全测试工具和技术,例如 OWASP ZAP 或 Burp Suite。
Structure
在 LDAP 中,目录条目被构建为对象,每个对象都遵循特定的模式,该模式定义了适用于该对象的规则和属性。这种面向对象的方法确保了一致性,并控制了如何在目录中表示和操作用户或组等对象。
使用 LDAP 的服务:
- Microsoft Active Directory:一种面向 Windows 域网络的服务,利用 LDAP 作为其底层协议套件的一部分来管理域资源。
- OpenLDAP:一种 LDAP 的开源实现,广泛用于管理用户信息并支持跨平台的身份验证机制。
LDIF 格式
LDAP 条目可以使用 LDAP 数据交换格式 (LDIF) 表示,这是一种用于表示 LDAP 目录条目和更新操作的标准纯文本数据格式。LDIF 可以导入和导出目录内容,并描述目录修改操作,例如添加、修改或删除条目。
结构
LDAP 目录遵循类似于文件系统树的层次结构。该结构包含代表唯一项目的各种条目,例如用户、组或资源。

在 LDAP 树的顶部,我们可以找到顶级域名 (TLD),例如 dc=ldap,dc=thm。在 TLD 之下,可能存在子域名或**组织单位 (OU)**,例如 ou=people 或 ou=groups,它们进一步对目录条目进行分类。
- **可分辨名称 (DN)**:作为目录中每个条目的唯一标识符,指定从 LDAP 树顶部到该条目的路径,例如
cn=John Doe,ou=people,dc=example,dc=com。 - **相对可分辨名称 (RDN)**:表示目录层次结构中的各个级别,例如
cn=John Doe,其中cn代表通用名称。 - 属性:定义目录条目的属性,例如
mail=john@example.com表示电子邮件地址。
Search Queries
搜索查询
LDAP 搜索查询是与 LDAP 目录交互的基础,允许您查找和检索目录中存储的信息。了解如何构建这些查询对于有效使用 LDAP 服务至关重要。
LDAP 搜索查询由多个组件组成,每个组件在搜索操作中都发挥着特定的作用:
基本 DN(可分辨名称):这是搜索在目录树中的起始点。
范围:定义从基本 DN 开始的搜索深度。它可以是以下之一:
base(仅搜索基本 DN),one(搜索基本 DN 的直接子项),sub(搜索基本 DN 及其所有后代)。
过滤器:条件条目必须匹配才能在搜索结果中返回。它使用特定的语法来定义这些条件。
属性:指定应在搜索结果中返回匹配条目的哪些特征。
LDAP 搜索查询的基本语法如下:
(base DN) (scope) (filter) (attributes) |
过滤器和语法
过滤器是 LDAP 搜索查询的核心,它定义了目录中的条目必须满足哪些条件才能包含在搜索结果中。LDAP 过滤器的语法定义在 RFC 4515 中,其中过滤器以特定格式的字符串表示,例如 (canonicalName=value)。LDAP 过滤器可以使用各种运算符来优化搜索条件,包括相等 (=)、存在 (=*)、大于 (>=) 和小于 (<=)。
LDAP 过滤器中最重要的运算符之一是通配符 *,它表示任意数量的字符匹配。此运算符对于制定广泛匹配或部分匹配的搜索条件至关重要。
过滤器示例
简单过滤器:
(cn=John Doe) |
此过滤器会筛选与“John Doe”完全匹配的规范名称 (cn) 的条目。
通配符:
(cn=J*) |
此过滤器使用通配符运算符匹配任何 cn 以“J”开头的条目,无论其后是什么。
使用逻辑运算符的复杂过滤器:
对于更复杂的搜索查询,可以使用逻辑运算符(例如 AND (&)、OR (|) 和 NOT (!))将过滤器相互结合使用。
(&(objectClass=user)(|(cn=John*)(cn=Jane*))) |
此过滤器会搜索对象类别中被归类为“用户”且规范名称以“John”或“Jane”开头的条目。
虽然 LDAP 服务通常不直接公开,但可以通过端口 389(用于未加密或 StartTLS 连接)和 636(用于 SSL/TLS 连接)通过网络访问。当 LDAP 服务可公开访问时,可以使用诸如“ldapsearch”(OpenLDAP 套件的一部分)之类的工具与 LDAP 服务器进行交互。此工具允许用户从命令行查询和修改 LDAP 目录,使其成为合法管理任务以及潜在利用 LDAP 注入漏洞的攻击者的宝贵资源。例如:
使用 ldapsearch 的示例搜索查询
user@tryhackme$ ldapsearch -x -H ldap://10.10.190.242:389 -b "dc=ldap,dc=thm" "(ou=People)" |
此命令使用“ldapsearch”对位于端口 389 上的易受攻击的计算机的 LDAP 服务器执行搜索,从基本 DN“dc=ldap,dc=thm”开始,并使用过滤器搜索 People 组织单位下的条目。
Injection Fundamentals
注入基础知识
LDAP 注入是一个严重的安全漏洞,当用户输入在被纳入 LDAP 查询之前未经过适当的过滤时,就会发生这种情况。这种疏忽使攻击者能够操纵这些查询,从而导致未经授权的访问或操纵 LDAP 目录数据。
LDAP 注入利用了 Web 应用程序构建 LDAP 查询的方式。当用户输入未经适当的验证或编码而直接包含在这些查询中时,攻击者可以注入恶意的 LDAP 语句。这可能导致未经授权访问敏感信息、修改目录数据或绕过身份验证机制。
该过程类似于 SQL 注入,其中恶意 SQL 语句被注入到查询中以操纵数据库操作。在 LDAP 注入中,恶意代码的目标是 LDAP 查询。
常见攻击向量
- 身份验证绕过:修改 LDAP 身份验证查询,以便在不知道密码的情况下以其他用户身份登录。
- 未经授权的数据访问:更改 LDAP 搜索查询以检索攻击者不应访问的敏感信息。
- 数据操纵:注入修改 LDAP 目录的查询,例如添加或修改用户属性。
注入过程
发起 LDAP 注入攻击涉及几个关键步骤,从识别注入点到成功利用漏洞。

下图展示了 LDAP 注入攻击期间攻击者、Web 应用程序和 LDAP 服务器之间的交互。攻击者向 Web 应用程序登录表单提交恶意输入,该表单会构建一个包含该输入的 LDAP 查询。然后,LDAP 服务器执行修改后的查询,从而可能导致未经授权的访问或信息泄露,具体取决于注入的有效载荷的性质。
Exploiting LDAP
利用 LDAP
LDAP 注入在身份验证机制中被利用时尤其危险。攻击者可以操纵 LDAP 查询进行用户身份验证,从而绕过安全控制,获得对应用程序的未授权访问。
例如,以下是 Web 应用程序中用于针对 LDAP 服务器进行用户身份验证的简化 PHP 代码片段:
|
这段代码存在漏洞,因为它直接将用户提供的输入(“$username”和“$password”)插入到 LDAP 查询中,而没有进行适当的过滤或转义。攻击者可以利用此漏洞注入恶意的 LDAP 过滤器。
为了利用此漏洞,攻击者可以使用恶意 LDAP 过滤器提交用户名。例如,攻击者可以使用类似“*”的用户名,当将其插入到 LDAP 查询中时,实际上会将查询转换为始终为真的条件,从而绕过身份验证。
如果 LDAP 目录中有任何用户,则此查询将成功进行身份验证,因为注入的条件“uid=*”将始终被评估为真。
身份验证绕过技术
基于重言式的注入
基于重言式的注入是指将本质上为真的条件插入到 LDAP 查询中,从而确保查询始终返回正结果,而不管预期的逻辑如何。此方法对于使用未充分过滤的用户输入构建的 LDAP 查询特别有效。例如,考虑 LDAP 身份验证查询,其中用户名和密码直接从用户输入插入:
(&(uid={userInput})(userPassword={passwordInput})) |
攻击者可以提供基于重言式的输入,例如 *)(|(& 表示 {user Input} 和 pwd) 表示 {password Input},这会将查询转换为:
(&(uid=*)(|(&)(userPassword=pwd))) |
由于过滤器中使用了逻辑运算符,此查询有效地绕过了密码检查。该查询由两部分组成,使用 AND(“&”)运算符连接。
(uid=*):过滤器的这一部分匹配任何具有uid属性的条目,本质上是所有用户,因为通配符*可以匹配任何值。(|(&)(userPassword=pwd)):OR(“|”)运算符,表示只要包含的两个条件中的任何一个为真,过滤器即可通过。在 LDAP 中,空的 AND(“(&)”)条件始终被视为真。另一个条件检查userPassword属性是否与值pwd匹配,如果用户未使用pwd作为密码,则该条件可能会失败。
综上所述,由于 (&) 条件,过滤器的第二部分 (|(&)(userPassword=pwd)) 将始终被评估为真。 OR 运算符只需其包含的条件之一为真即可,由于 (&) 始终为真,因此无论 (userPassword=pwd) 为真还是假,整个 OR 条件都为真。
因此,这会导致任何用户查询成功,而无需验证密码是否正确,从而绕过密码检查机制。
通配符注入
通配符 (*) 在 LDAP 查询中用于匹配任意字符序列,使其成为进行广泛搜索的强大工具。但是,如果包含通配符的用户输入未正确过滤,则可能导致意外的查询结果,例如通过匹配多个或所有条目来绕过身份验证。例如,如果搜索查询如下:
(&(uid={userInput})(userPassword={passwordInput})) |
攻击者可能会在 uid 和 userPassword 中同时使用通配符作为输入。使用 * 表示 {userInput} 可能会强制查询忽略特定的用户名,转而关注密码。但是,由于 {passwordInput} 中也存在通配符,因此它不会根据特定的预期值验证密码字段的内容。相反,它只会检查 userPassword 属性是否存在,而不管其内容如何。
这意味着查询将对任何用户返回肯定匹配,而无需验证身份验证期间提供的密码是否与存储的密码匹配。因此,这实际上绕过了密码检查机制。
身份验证绕过示例
要演示简单的 LDAP 注入攻击,请访问 http://MACHINE_IP/normal.php。基于上述代码,应用程序会根据用户输入构建一个 LDAP 身份验证查询,而无需进行适当的过滤。
攻击者可以通过提交包含应用程序无法预料的字符的用户名和密码来利用此漏洞,例如,uid 和 userPassword 属性值中包含星号 (*)。这会导致条件始终为 true,从而有效地绕过密码检查:
注入的用户名和密码:
username=*&password=* |

Resulting LDAP Query Component:
(&(uid=*)(userPassword=*)) |

此注入始终使 LDAP 查询的条件为真。但是,仅使用 * 将始终获取查询中的第一个结果。为了定位以特定字符开头的数据,攻击者可以使用类似 f* 的负载,它会搜索以字母 f 开头的 uid。

Blind LDAP Injection
盲 LDAP 注入
盲 LDAP 注入是 LDAP 注入的一种更隐蔽的变体,攻击者不会从注入的有效载荷中直接获得输出。相反,他们必须根据应用程序的行为推断信息。这种攻击更具挑战性,但仍可用于从 LDAP 目录中提取敏感信息。
由于缺乏明确的查询结果,盲 LDAP 注入需要采用不同的方法。攻击者必须依靠间接迹象(例如应用程序行为的变化、错误消息或响应时间)来推断 LDAP 查询的结构和漏洞的存在。
例如,以下是 http://10.10.240.177/blind.php 的代码片段,它使用 LDAP 查询来检查用户是否存在,但在失败时仅返回一般错误消息。该应用程序还会检查提交的电子邮件地址是否与数据库中的电子邮件地址相同:
$username = $_POST['username']; |
此代码容易受到 LDAP 盲注攻击,因为它会使用未经过滤的用户输入构建 LDAP 过滤器。然而,它仅提供模糊的反馈,因此很难直接利用。
为了利用此漏洞,攻击者可以使用一种称为基于布尔值的 LDAP 盲注技术。攻击者会向用户名字段注入条件,使 LDAP 查询结果为真或假,从而观察应用程序的行为以推断信息。
例如,攻击者可能会尝试注入类似 a*)(|(& 的用户名,当该用户名包含在 LDAP 查询中时,会检查其 uid 中是否存在包含“a”的用户:
Injected Username and Password:
username=a*%29%28%7C%28%26&password=pwd%29 |
注意:上述有效载荷是有效载荷 a*)(|(& 表示用户名和 pwd) 表示密码的 URL 编码版本。使用前必须先进行 URL 解码。

Resulting LDAP Query:
(&(uid=a*)(|(&)(userPassword=pwd))) |

如果应用程序返回“您的密码有误”,攻击者可以推断 LDAP 目录中存在一个 uid 以“a”开头的用户。为了检查下一个字符,攻击者可以使用下一个字符重复执行有效载荷,例如:
Injected Username and Password:
username=ab*%29%28%7C%28%26&password=pwd%29 |

Resulting LDAP Query:
(&(uid=ab*)(|(&)(userPassword=pwd))) |

这表明下一个字符不是“b”。攻击者可以通过观察 Web 应用程序对精心设计的输入的响应行为,反复猜测电子邮件中的字符,从而自动执行此类检查,类似于基于布尔值的 SQL 注入攻击。
信息提取技术
- 布尔值利用:这涉及注入被评估为真或假的条件,并观察应用程序的响应以推断数据。例如,如果应用程序在条件为真时的行为有所不同,则攻击者可以推断注入的条件与 LDAP 目录中的现有条目匹配。
- 基于错误的推断:在某些情况下,特定的注入可能会触发错误消息或异常的应用程序行为,从而提供有关 LDAP 结构的线索或确认特定有效载荷是否成功。
Automating the Exploitation
Exploit Code
为了自动执行上一个任务中的数据泄露,您可以使用以下 Python 脚本:
import requests |
Click here for a breakdown of the script.
- 导入:
requests:用于发出 HTTP 请求的 Python 库。bs4中的BeautifulSoup:用于解析 HTML 文档的库,使导航和搜索解析树更加容易。string:包含常见字符串操作的模块,包括一组字符串常量。time:提供各种时间相关函数的模块。
- 设置:
url变量设置为 `’http://10.10.240.177/blind.php'',这是 HTTP POST 请求的目标 URL。char_set包含大小写字母、数字以及一系列特殊字符。此集合表示脚本将迭代以猜测密码的所有字符。
- 变量初始化:
successful_response_found是用于控制 while 循环的标志。它以True开始进入循环,当未找到成功字符时,设置为False。successful_chars存储成功猜测的字符序列。
- HTTP 标头:
- 定义一个字典
headers,其内容类型设置为 `’application/x-www-form-urlencoded’,指示 HTTP POST 请求的正文格式。
- 主循环:
- 脚本进入一个
while循环,只要successful_response_found为True,该循环就会继续执行。 - 在此循环中,它会遍历
char_set中的每个字符。
- 构造和发送 HTTP 请求:
- 对于每个字符,脚本都会创建一个字典
data,其中包含用于 HTTP POST 请求的键值对。username字段被注入了一个有效载荷,该载荷由成功找到的字符和当前正在测试的字符组合而成,后跟*)(|(&,这是注入语法的一部分。password字段被任意设置为 `’pwd)’。 - 向目标
url发送一个 HTTP POST 请求,其中包含精心设计的data和headers。
- 响应处理:
- 使用 BeautifulSoup 解析响应内容以分析 HTML 结构。
- 脚本查找
style属性为'color: green;'的<p>标签,假定该属性表示猜测成功。
- 字符验证:
- 如果找到这样的段落,则表示当前字符是密码的一部分。然后,将此字符附加到
successful_chars中,脚本跳出内部循环以测试下一个字符。 - 如果没有段落符合条件,脚本将得出结论,认为在当前迭代中未找到成功的字符,并打印一条消息,退出循环。
- 输出:
- 一旦所有字符都已测试或找到正确的序列,脚本将打印最终成功找到的字符序列。
上述脚本通过观察 Web 应用程序对精心设计的输入的响应行为,反复猜测电子邮件中的字符。
自动化
保存上述 Python 代码。如果您使用的是 AttackBox,则所需的 Python 模块已安装。由于 AttackBox 上已安装多个 Python 模块,请确保使用 python3.9 版本。
以下是运行自动化脚本的示例命令:
~/Downloads
user@tryhackme$ ls |
这将立即显示暴力破解的结果,如下所示:

使用最终的有效负载登录 http://10.10.240.177/login.php。确保使用 * 作为密码;这将自动将搜索查询评估为 true。


Conclusion
恭喜您完成 LDAP 注入!以下是我们涵盖的关键概念的回顾:
- LDAP 基础知识:我们首先了解了 LDAP 在目录服务中的作用,并学习了 LDAP 树的结构,包括 DN、RDN 和属性。
- LDAP 搜索查询:您学习了如何构建基本的 LDAP 搜索查询,并理解了过滤器及其语法的重要性。
- LDAP 注入基础知识:您了解了 LDAP 注入是什么、它的工作原理以及常见的攻击媒介,并重点介绍了 LDAP 查询中未正确过滤的输入所带来的风险。
- 在登录机制中利用 LDAP 注入:我们探讨了通过 LDAP 注入绕过身份验证的技术,并进行了模拟易受攻击的登录系统的实践练习。
- LDAP 盲注入技术:探讨了通过 LDAP 盲注入(一种更隐蔽的 LDAP 注入形式)提取信息的挑战和方法。
其他资源
为了继续掌握 LDAP 及相关安全概念,请考虑探索以下资源:
- **TryHackMe:突破 AD**:本会议室将深入探讨 Active Directory 环境,提供利用常见 AD 漏洞的实践经验,并帮助您理解 AD 内部的安全机制。
