LDAP注入攻击可致信息泄露、权限绕代及域控接管;防御需严格校验输入、最小化查询逻辑、隔离服务权限,禁用黑名单过滤,须用白名单与强类型校验。
ldap注入攻击在windows运维环境中虽不如sql注入常见,但一旦发生,可能导致目录信息泄露、权限绕过甚至域控账户接管。防御核心在于输入严格校验、查询逻辑最小化、服务权限隔离,而非依赖后端过滤或编码转换。
严格校验与白名单约束用户输入
所有传入LDAP查询的参数(如用户名、邮箱、部门名)必须进行强类型校验和字符白名单过滤。避免仅做黑名单过滤(如只剔除*()&|!>=等符号),因LDAP语法灵活,绕过方式多。
- 对用户名字段:仅允许字母、数字、短横线、下划线,长度限制在3–20字符,拒绝以..、.开头或含@(除非明确支持UPN)
- 对搜索关键词(如displayName模糊匹配):禁用通配符*和子字符串匹配操作符(如~=),改用前缀匹配(如cn=John*)并限制通配位置(仅允许结尾)
- 使用正则预检:例如
^[a-zA-Z0-9_-]{3,20}$校验sAMAccountName,匹配失败直接返回400错误,不构造LDAP语句
使用参数化查询或安全封装接口
原生System.DirectoryServices(.NET)不支持参数化LDAP查询,但可通过抽象层规避拼接风险。关键不是“如何转义”,而是“不让用户输入参与查询结构构建”。
- 优先调用DirectorySearcher.Filter属性赋值时,使用固定模板+预处理值:例如
searcher.Filter = $"(sAMAccountName={SanitizeForLdap(sam)})",其中SanitizeForLdap()仅保留可安全出现在DN/Filter中的字符,并对剩余特殊字符做\xx转义(如空格→\20) - 禁用string.Format或$""直接拼接Filter字符串;若必须动态构造,用预定义枚举限定属性名(如UserSearchField.DisplayName),禁止用户指定任意属性
- Java环境推荐使用UnboundID LDAP SDK的Filter.createEqualityFilter()等类型安全方法,避免手写Filter字符串
降低LDAP服务运行权限与网络暴露面
即使应用层存在疏漏,限制LDAP服务本身的权限和可达性可大幅压缩攻击收益。
- 域内应用服务器查询AD时,使用专用只读服务账号(非Domain Admin),并通过ACL限制其仅能读取必要OU(如仅OU=Employees,DC=corp,DC=local),禁止遍历CN=Users或查询userPassword等敏感属性
- 关闭不必要的LDAP端口暴露:生产环境禁用LDAPS(636)以外的明文LDAP(389);若需389,强制要求客户端启用StartTLS,并在防火墙层限制源IP段(如仅允应用服务器网段)
- 对面向互联网的应用(如SSO网关),绝不可直连域控;应通过AD FS或专用LDAP代理(如OpenLDAP slapd with back-ldap + strict ACL)中转,代理层实施额外过滤和速率限制
启用审计与异常行为监控
主动发现异常查询模式比被动修复更有效。Windows事件日志与LDAP操作日志是关键线索。
- 在域控上启用DS Access审核策略(组策略→计算机配置→Windows设置→安全设置→高级审核策略→目录服务访问),记录Audit Directory Service Access为“成功+失败”
- 关注事件ID 4662(对象访问)中Operation Type=5(LDAP查询)且Properties包含大量通配符或嵌套逻辑(如(|(cn=*)(sn=*)))的日志
- 部署SIEM规则:1分钟内同一IP发起≥5次含*或(objectClass=*)的查询,自动告警并临时封禁该IP










