零基础玩转bWAPP靶场(十一):LDAP 注入——搜索型
摘要本文是 bWAPP 靶场系列的第十一篇聚焦于LDAP Injection (Search)LDAP 搜索注入漏洞。文章从零基础角度出发首先讲清楚 LDAP 搜索注入与连接设置的本质区别然后讲解 LDAP 的基本概念、树状数据结构、搜索过滤器语法接着按照 Low、Medium、High 三个安全级别逐一进行源码分析、通关演示。本文加入了完整的 OpenLDAP 服务搭建教程因为 bWAPP 的 LDAP 搜索注入必须连接真实的 LDAP 服务器才能生效。同时加入了大量真实世界的经典案例——从 Apache Archiva 到 2025-2026 年的 SuiteCRM、EspoCRM、Zitadel、Yamcs 等——帮助读者理解 LDAP 注入在现实世界中的持续威胁。一、前言在前十篇文章中我们分别介绍了环境搭建、三种反射型 HTML 注入、存储型 HTML 注入、iFrame 注入、普通型和盲注型的 OS 命令注入、PHP 代码注入以及 SSI 注入。今天我们要讲的漏洞很多初学者甚至从未听说过——LDAP Injection (Search)LDAP 搜索注入。LDAP 是什么它是一种轻量级目录访问协议用于访问和管理目录服务如企业员工通讯录、用户身份认证系统。很多大型企业、学校、政府机构都在使用 LDAP 来管理用户信息。而 LDAP 搜索注入就是攻击者在搜索框中注入恶意的 LDAP 过滤器语法操纵服务器执行非预期的 LDAP 查询——轻则绕过登录认证重则窃取整个目录的用户信息。更重要的是LDAP 注入的漏洞从未消失。就在 2025-2026 年SuiteCRM、EspoCRM、Zitadel、Yamcs 等众多企业级产品中接连曝出了 LDAP 注入的高危漏洞。二、LDAP 概述2.1 什么是 LDAP在理解漏洞之前先搞清楚 LDAP 到底是什么。LDAP全称是Lightweight Directory Access Protocol轻量级目录访问协议。它是一种用于访问和管理目录服务的网络协议。什么是“目录服务”你可以把目录服务理解为一本“电话簿”——它存储了关于人、组织、设备等实体的信息并允许你按照特定条件进行查询。一个典型的 LDAP 目录中存储的信息包括用户名uid姓名cn即 common name邮箱mail部门ou即 organizational unit公司o即 organization国家c密码userPassword2.2 LDAP 的数据结构——树状目录LDAP 的数据是树状结构的类似于文件系统的目录树。一个 LDAP 条目的唯一标识是DNDistinguished Name区分名——它描述了该条目在目录树中的完整路径。例如一个用户的 DN 可能是uidjdoe, ouUsers, dcbwapp, dclocal这表示在dcbwapp,dclocal这个域下ouUsers组织单元中用户名为jdoe的条目。DN 的组成部分dcDomain Component域组件如dcbwapp,dclocalouOrganizational Unit组织单元如ouUsers、ouAdministratorscnCommon Name通用名称如cnAdministratoruidUser ID用户 ID如uidjdoe2.3 LDAP 搜索过滤器LDAP 最常用的操作是搜索——根据特定条件查找目录中的条目。搜索条件通过LDAP 搜索过滤器Search Filter来表达。LDAP 过滤器使用波兰表示法前缀表示法即操作符写在操作数前面。逻辑操作符操作符含义示例AND与((uidjdoe)(mail*))\|OR或(\|(uidjdoe)(uidasmith))!NOT非(!(uidadmin))比较操作符操作符含义示例等于(uidjdoe)大于等于(uidjdoe)小于等于(uidjdoe)~近似等于(cn~John)*通配符任意字符(uidjo*)一个完整的 LDAP 查询示例(|(cnJohn)(mailJohn))翻译成自然语言查找所有通用名称是 John 或者邮箱是 John 的用户。2.4 LDAP 注入与 SQL 注入的对比LDAP 注入和 SQL 注入的原理完全相同——都是将用户输入拼接到查询语句中且没有经过充分过滤。但两者的语法完全不同对比维度SQL 注入LDAP 注入查询语言SQLLDAP 过滤器语法数据存储关系型数据库表、行、列目录服务树状结构逻辑表示中缀表示法a AND b波兰表示法((a)(b))关键字符、;、--(、)、*、、\|典型攻击 OR 11*)(、admin*关键点LDAP 注入的“武器”是圆括号(和)而不是 SQL 中的引号。理解了这一点你就掌握了 LDAP 注入的核心。三、LDAP 搜索注入的产生原因与危害3.1 为什么会产生 LDAP 搜索注入漏洞LDAP 搜索注入产生的根本原因与 SQL 注入完全相同应用程序将用户输入直接拼接到 LDAP 查询中没有进行充分的过滤或转义。一个典型的有漏洞的 PHP 代码$filter (|(cn . $search_for . )(mail . $search_for . )); $search ldap_search($ds, $dn, $filter);如果用户输入search_for为*)(最终的过滤器变成了(|(cn*)()(mail*)())由于()永远为真这个过滤器匹配了目录中的所有条目3.2 LDAP 搜索注入的危害LDAP 搜索注入的危害极其严重认证绕过攻击者无需密码即可登录任意用户账户信息泄露攻击者可以枚举目录中的所有用户、组和属性权限提升攻击者可以获取管理员权限拒绝服务攻击者可以构造复杂的查询耗尽服务器资源四、LDAP 注入的历史背景与真实案例4.1 历史背景LDAP 协议诞生于1990 年代初期随着互联网和企业信息化的发展LDAP 成为企业身份管理的基础设施。当 Web 应用开始将用户输入直接拼接到 LDAP 查询中时LDAP 注入就诞生了。LDAP 注入与 SQL 注入几乎同时期被发现但关注度要低得多——很多开发者甚至不知道 LDAP 注入的存在。这种“被忽视”的状态使得 LDAP 注入成为最容易被忽略的高危漏洞之一。4.2 经典案例一Apache Archiva LDAP 注入CVE-2020-9495时间2020 年Apache Archiva 是一个企业级的制品仓库管理工具。安全研究人员发现Archiva 2.2.5 之前的版本的登录服务存在 LDAP 注入漏洞攻击者可以通过在登录表单中提供特殊构造的值从连接的 LDAP 服务器中检索用户属性数据。4.3 经典案例二SuiteCRM LDAP 过滤器注入CVE-2026-33289时间2026 年 3 月CVSS 评分8.8高危SuiteCRM 是一款开源的企业级 CRM 软件。安全研究人员发现在 SuiteCRM 7.15.1 和 8.9.3 之前的版本中认证流程存在 LDAP 注入漏洞。应用程序未能正确净化用户输入就将其嵌入到 LDAP 搜索过滤器中导致认证绕过和信息泄露。4.4 经典案例三EspoCRM 盲 LDAP 注入CVE-2025-52575时间2025 年 7 月EspoCRM 是另一款流行的开源 CRM 软件。安全研究人员发现EspoCRM 9.1.6 及更早版本在启用 LDAP 认证时存在盲 LDAP 注入漏洞。攻击者可以通过注入包含通配符如*的精心构造的输入来操纵 LDAP 查询实现绕过认证和枚举有效用户名。4.5 经典案例四Zitadel LDAP 身份提供者注入CVE-2026-44671时间2026 年 5 月Zitadel 是一个开源的身份和访问管理IAM平台。安全研究人员发现Zitadel 的LDAP 身份提供者实现在将用户提供的用户名纳入 LDAP 搜索过滤器之前未能正确转义这些用户名导致盲 LDAP 注入。4.6 经典案例五Yamcs LDAP 认证绕过CVE-2026-42568时间2026 年 5 月Yamcs 是一个开源的任务控制系统被用于航天、科研等关键领域。安全研究人员在 Yamcs 的LdapAuthModule中发现了一个 LDAP 注入漏洞——username 参数被直接插入到 LDAP 搜索过滤器中没有进行 RFC 4515 标准的转义。该漏洞允许未经认证的攻击者完全绕过认证以任意用户包括管理员的身份获得访问权限。4.7 经典案例六Maddy LDAP 注入CVE-2026-40193时间2026 年 4 月Maddy 是一个开源的多合一邮件服务器。安全研究人员发现Maddy 0.9.3 之前版本的auth.ldap模块存在 LDAP 注入漏洞——用户提供的用户名通过strings.ReplaceAll()被插入到 LDAP 搜索过滤器中未进行任何 LDAP 过滤器转义。代码中已经导入了go-ldap/ldap/v3库该库提供了ldap.EscapeFilter()函数——但开发者没有使用它。这个案例的教训是深刻的即使安全工具可用如果开发者没有安全意识漏洞依然会发生。五、环境准备搭建 OpenLDAP 服务器重要提示bWAPP 的 LDAP 搜索注入功能必须连接一个真实的 LDAP 服务器才能正常工作。如果 LDAP 服务器没有正确配置ldap_search()函数会返回错误无法进行注入测试。5.1 在小皮面板中配置 LDAP 扩展访问小皮面板点击对应版本的“PHP设置” → “PHP扩展”找到ldap扩展进行安装重启 Apache 服务使配置生效5.2 在CentOS 7中搭建 OpenLDAP步骤一安装 OpenLDAP# 安装 OpenLDAP 服务器和客户端 yum install -y openldap openldap-servers openldap-clients步骤二初始化 LDAP 数据库# 复制数据库模板 cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG # 归属权限 chown ldap:ldap /var/lib/ldap/* # 启动开机自启 systemctl start slapd systemctl enable slapd # 确认运行正常 systemctl status slapd步骤三配置管理员密码生成密文密码自定义管理员密码示例123456slappasswd -s 123456输出类似{SSHA}xxxxxxx复制保存。创建配置文件chrootpw.ldifcat chrootpw.ldif EOF dn: olcDatabase{0}config,cnconfig changetype: modify add: olcRootPW olcRootPW: {SSHA}你刚才复制的密文 EOF导入密码配置ldapadd -Y EXTERNAL -H ldapi:/// -f chrootpw.ldif步骤四配置域名、管理员账号bWAPP 默认根域bwapp.local管理员账号cnadmin,dcbwapp,dclocal新建chdomain.ldifcat chdomain.ldif EOF dn: olcDatabase{1}monitor,cnconfig changetype: modify replace: olcAccess olcAccess: {0}to * by dn.basegidNumber0uidNumber0,cnpeercred,cnexternal,cnauth read by * none dn: olcDatabase{2}hdb,cnconfig changetype: modify replace: olcSuffix olcSuffix: dcbwapp,dclocal - replace: olcRootDN olcRootDN: cnadmin,dcbwapp,dclocal - replace: olcRootPW olcRootPW: {SSHA}前面生成的密钥 EOF导入配置ldapadd -Y EXTERNAL -H ldapi:/// -f chdomain.ldif步骤五创建基础组织域结构新建base.ldifcat base.ldif EOF dn: dcbwapp,dclocal objectClass: top objectClass: dcObject objectClass: organization o: BWAPP Company dn: cnadmin,dcbwapp,dclocal objectClass: simpleSecurityObject objectClass: organizationalRole cn: admin userPassword: 123456 dn: ouusers,dcbwapp,dclocal objectClass: organizationalUnit ou: users EOF导入ldapadd -x -D cnadmin,dcbwapp,dclocal -w 123456 -f base.ldif步骤六添加测试用户新建user.ldifcat user.ldif EOF dn: cntestuser,ouusers,dcbwapp,dclocal objectClass: top objectClass: simpleSecurityObject objectClass: organizationalRole cn: testuser userPassword: test123 EOF导入用户ldapadd -x -D cnadmin,dcbwapp,dclocal -w 123456 -f user.ldif步骤七开放防火墙临时关闭SELinux以及放行防火墙 389 端口setenforce 0 firewall-cmd --add-port389/tcp --permanent firewall-cmd --reload步骤八验证 LDAP 服务ldapsearch -x -b dcbwapp,dclocal -H ldap://localhost如果返回了之前创建的用户信息说明 OpenLDAP 服务配置成功。六、bWAPP LDAP 搜索注入漏洞实战6.1 漏洞页面完整流程介绍先打开页面LDAP Connection Settings页面作用填写 LDAP 服务连接参数存入 session 供搜索页面调用必填项Login管理员完整 DNcnadmin,dcbwapp,dclocalPasswordLDAP 管理员密码示例 123456ServerLDAP 服务器 IP你的 10.0.0.171Base DNdcbwapp,dclocal填写完成点击Set保存连接配置并自动跳转搜索页面。跳转后页面LDAP Injection (Search)页面功能输入关键词查询 LDAP 内用户后端拼接 LDAP 过滤器执行查询表格仅渲染Common Name(cn)字段无 cn 属性的域 / 分组行会空白。页面元素输入框、Search 按钮、结果展示表格SID/SAM Name/UPN/Common Name/Display Name6.2 完整源码逐段分层分析6.2.1 头部公共引入与过滤分发函数include(security.php); include(security_level_check.php); include(functions_external.php); include(selections.php); // 输入过滤分发核心函数 function ldapi($data) { switch($_COOKIE[security_level]) { case 0 : // Low级别无任何过滤原样返回输入 $data no_check($data); break; case 1 : // Medium级别调用ldapi_check_1 清洗危险字符 $data ldapi_check_1($data); break; case 2 : // High级别和Medium使用完全相同的清洗逻辑 $data ldapi_check_1($data); break; default : $data no_check($data); break; } return $data; }函数逻辑解读安全等级 0Lowno_check()为空函数输入不做任何处理安全等级 1Medium、2High统一执行ldapi_check_1()过滤二者防护强度一致不存在差异。6.2.2 LDAP 会话校验逻辑必须先配置连接if(!(isset($_SESSION[ldap][login]) $_SESSION[ldap][login])) { // 未配置LDAP账号强制跳转配置页 header(Location: ldap_connect.php); exit; } // 读取Session内保存的LDAP连接信息 $login $_SESSION[ldap][login]; $password $_SESSION[ldap][password]; $server $_SESSION[ldap][server]; $dn $_SESSION[ldap][dn];关键点不配置 LDAP 连接无法进入搜索功能这是你前期测试的前置必要操作。6.2.3 页面顶部欢迎信息 LDAP 绑定查询和搜索注入无关// 建立LDAP基础连接 $ds ldap_connect($server); ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); ldap_set_option($ds, LDAP_OPT_REFERRALS, 0); $r ldap_bind($ds, $login, $password); if($r) { // 判断登录DN是否带\Windows AD域SAM账号逻辑你的openLDAP环境不会触发 if(strpos($login, \\) ! false) { $login_array explode(\\, $login); $samaccountname $login_array[count($login_array) - 1]; $search_for $samaccountname; $search_field samaccountname; } else { // 你的环境执行此分支搜索字段userprincipalname搜索值为管理员DN $search_for $login; $search_field userprincipalname; } // 拼接欢迎页查询过滤器仅用于获取用户名展示Welcome $filter (($search_field$search_for)(objectClassuser)); $sr ldap_search($ds, $dn, $filter); $info ldap_get_entries($ds, $sr); $message Welcome . ucwords($samaccountname $info[0][samaccountname][0]) . ,; } ldap_close($ds);说明这一段仅用于页面顶部Welcome xxx文字渲染和下方搜索框注入逻辑完全隔离互不影响。6.2.4 搜索框 POST 提交核心漏洞代码注入核心if(isset($_POST[user])) { // 重建LDAP连接用于执行用户搜索 $ds ldap_connect($server); ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); ldap_set_option($ds, LDAP_OPT_REFERRALS, 0); $r ldap_bind($ds, $login, $password); if($r) { // 1. 获取用户输入的搜索关键词 $search_for $_REQUEST[user]; // 2. 根据安全等级执行过滤函数漏洞/防护分水岭 $search_for ldapi($search_for); // 固定三个查询字段givenname、sn、userprincipalname $search_field_1 givenname; $search_field_2 sn; $search_field_3 userprincipalname; // 【漏洞核心直接拼接可控输入无原生转义】 // 原生过滤器模板(|(givenname输入)(sn输入)(userprincipalname输入)) $filter (|($search_field_1$search_for)($search_field_2$search_for)($search_field_3$search_for)); // 指定仅查询表格需要渲染的字段 $ldap_fields_to_find array(objectsid, samaccountname, userprincipalname, cn, displayname); // 执行LDAP检索 $sr ldap_search($ds, $dn, $filter, $ldap_fields_to_find); $info ldap_get_entries($ds, $sr); // 循环渲染表格 for($x0; $x$info[count]; $x) { $objectsid bin_sid_to_text($info[$x][objectsid][0]); $samaccountname $info[$x][samaccountname][0]; $userprincipalname $info[$x][userprincipalname][0]; $cn $info[$x][cn][0]; $givenname $info[$x][displayname][0]; // 输出表格行仅Common Name列展示cn文本 ? tr height40 td?php echo $samaccountname?/td td?php echo $userprincipalname?/td td?php echo $cn?/td /tr ?php } } }漏洞核心总结用户输入$_REQUEST[user]完全可控直接拼接进 LDAP 过滤器字符串Low 级别无任何字符清洗攻击者可自由插入()*|篡改过滤器逻辑过滤器外层固定一层括号(|条件1)(条件2)(条件3)仅需闭合前置括号即可追加自定义查询条件。6.2.5 Medium/High 共用过滤函数完整拆解function ldapi_check_1($data) { // 批量强制删除所有LDAP过滤器危险元字符 $input str_replace((, , $data); $input str_replace(), , $input); $input str_replace(, , $input); $input str_replace(, , $input); $input str_replace(|, , $input); $input str_replace(*, , $input); $input str_replace( , , $input); return $input; }过滤规则逐条说明()LDAP 过滤器括号结构关键字用于篡改查询逻辑直接删除属性匹配关键字删除后无法构造字段值查询|LDAP 逻辑与 / 或运算符删除后无法拼接恒真条件*LDAP 通配符批量枚举全量数据核心字符直接删除空格全部清空。关键结论只要 Payload 包含上述任意字符提交后会被直接清空仅剩纯文字Medium、High 无任何可用注入 Payload。七、Low 安全级别7.1 前置操作bWAPP 安全等级切换为 Low进入LDAP Connection Settings页面完整填写连接参数Logincnadmin,dcbwapp,dclocalPassword123456Server10.0.0.171Base DNdcbwapp,dclocal点击Set跳转搜索页面。7.2 通关步骤步骤 1正常查询搜索框输入普通字符testuser点击 Search过滤器(|(givennametestuser)(sntestuser)(userprincipalnametestuser))无匹配条目页面空白。步骤 2万能稳定 Payload搜索框输入*)(cn*拼接完整过滤器(|(givenname*)(cn*)(sn*)(cn*)(userprincipalname*)(cn*))逻辑说明强制匹配所有带cn属性的 LDAP 条目表格正常输出两行用户无空白。步骤 3全量遍历 Payload会多出空白行证明全库查询搜索框输入*)(objectClass*拼接完整过滤器(|(givenname*)(objectClass*)(sn*)(objectClass*)(userprincipalname*)(objectClass*))逻辑说明LDAP 所有条目强制携带objectClass查询库内全部 4 条数据dcbwapp,dclocal无 cn空白行cnadmin有 cn文字ouusers无 cn空白行cntestuser有 cn文字 页面出现两行空白仅用于证明可越权查询全部 LDAP 条目。7.3 Low 级别源码漏洞总结信息泄露攻击者无需权限一次性枚举 LDAP 目录内所有管理员、普通用户账号越权查询绕过字段限制读取所有 LDAP 对象域、分组、人员可拓展配合或逻辑 Payload构造恒真条件用于登录页面认证绕过。7.4 Low 级别标准防御方案使用 PHP 官方专用 LDAP 过滤器转义函数彻底拦截注入// 安全转义用户输入所有LDAP危险字符自动转义 $search_for ldap_escape($_REQUEST[user], , LDAP_ESCAPE_FILTER); // 安全拼接过滤器 $filter (|($search_field_1$search_for)($search_field_2$search_for)($search_field_3$search_for));八、Medium 安全级别8.1 防护机制安全等级设置为 Medium输入会经过ldapi_check_1()批量删除( ) * | 所有注入元字符。8.2 测试 Payload 全部失效演示输入*)(cn*过滤函数删除()*清洗后仅剩字符串cn 拼接过滤器(|(givennamecn)(sncn)(userprincipalnamecn))库内无匹配条目页面空白。输入*)(objectClass*过滤后仅剩objectClass无匹配条目页面空白。输入*))过滤删除*)仅剩空字符串无查询结果。8.3 结论Medium 级别通过强制删除 LDAP 特殊元字符从根源杜绝 LDAP 搜索注入无任何可利用 Payload。九、High 安全级别9.1 防护机制安全等级设置为 High分发函数同样调用ldapi_check_1()过滤逻辑、清洗规则和 Medium 完全一致无任何区别。9.2 测试结果所有带()*|的 Payload 都会被清空特殊字符无法篡改过滤器不存在 LDAP 注入漏洞。十、LDAP 搜索注入的防御方案总结LDAP 搜索注入的本质是用户输入可控、直接拼接 LDAP 语法语句。正规防御不能依赖黑名单过滤、不能依赖 XSS 过滤、不能依赖 SQL 过滤。企业生产环境标准防御组合优先使用 ldap_escape() 对所有用户输入做 LDAP 语法转义核心配合白名单正则输入校验使用最小权限只读 LDAP 业务账号限制查询目录范围与返回数据量只有从语法转义、输入校验、权限架构、查询限制四层防护才能彻底根治 LDAP 注入漏洞。十一、总结本文以 bWAPP 靶场 LDAP 搜索注入漏洞为核心完整完成了理论学习、环境搭建、源码审计、分级复现与安全防御的全套实验分析。文章简要介绍了 LDAP 协议原理、树状数据结构与搜索过滤器语法对比了 LDAP 注入与 SQL 注入的异同明确了括号、通配符、逻辑运算符为 LDAP 注入的核心攻击字符并结合近年真实 CVE 案例印证了该漏洞在企业级系统中持续存在、危害高危的现实安全问题。为实现漏洞复现本文搭建了完整的 OpenLDAP 服务环境解决了 bWAPP LDAP 模块依赖真实服务的实验前置问题。通过对靶场源码逐行审计明确了三级安全级别真实防护逻辑Low 级别无任何输入过滤存在完整 LDAP 注入漏洞可构造 Payload 批量枚举 LDAP 用户信息Medium、High 级别共用粗暴黑名单过滤函数强制删除所有 LDAP 特殊语法字符成功防御注入但该方式仅适用于靶场无法用于生产环境。本文最终总结了 LDAP 搜索注入的漏洞成因与危害验证了 addslashes、htmlspecialchars 等常规过滤手段对该漏洞无效梳理出以ldap_escape官方专用转义为核心搭配白名单校验、最小权限部署、查询范围限制的标准化防御方案。本次实验清晰阐明了 LDAP 注入的攻击原理与防护要点为 Web 漏洞学习、代码安全审计与 LDAP 服务安全加固提供了实用参考。写在最后LDAP 搜索注入是 Web 安全中最容易被忽视、却危害巨大的漏洞类型之一。从 2020 年的 Apache Archiva 到 2026 年的 SuiteCRM、EspoCRM、Zitadel、Yamcs——LDAP 注入从未消失而且在 2025-2026 年迎来了“大爆发”。为什么 LDAP 注入能够“生生不息”因为 LDAP 是企业身份管理的基石——只要企业还在用 LDAP 认证用户LDAP 注入就有存在的土壤因为开发者对 LDAP 安全认识不足——很多人知道 SQL 注入却不知道 LDAP 注入因为缺少参数化查询——与 SQL 不同LDAP 没有标准化的参数化查询接口记住三句话LDAP 搜索注入和 SQL 注入一样危险——只是你平时没注意到它*、(、)在 LDAP 中就是“武器”——永远不要相信用户输入的这些字符ldap_escape()是你的朋友——用它来转义所有用户输入重要声明本教程及文中所有操作仅限于合法授权的安全学习与研究。作者及发布平台不承担因不当使用本教程所引发的任何直接或间接法律责任。请务必遵守中华人民共和国网络安全相关法律法规。如果这篇文章帮你解决了实操上的困惑别忘记点击点赞、分享也可以留言告诉我你遇到的其它问题我会尽快回复。你的关注是我坚持原创和细节共享的力量来源谢谢大家。