LDAP注入的深入利用
字数 1329 2025-08-29 08:31:41
LDAP注入深入利用技术文档
1. LDAP注入概述
LDAP注入是指攻击者通过构造恶意的LDAP过滤器语句(filter)来获取未授权信息或绕过认证的安全漏洞。LDAP过滤器是LDAP查询的核心部分,用于筛选目录中的条目。
1.1 LDAP过滤器基本语法
=等于>=大于等于<=小于等于|逻辑或&逻辑与!逻辑非*通配符(语句)语句分组
示例:
(cn=admin)- 搜索cn属性为admin的条目(|(cn=admin)(mail=admin)(mobile=admin))- 搜索cn、mail或mobile为admin的条目
2. LDAP注入检测方法
2.1 注入点识别
- 括号测试:插入半个括号
(或),观察返回是否出现异常 - 通配符测试:输入
*,观察返回结果:- 用户存在但密码错误
- 服务器错误(当查询返回多条结果且后端未处理时)
2.2 常见注入场景
LDAP注入常见于:
- 判断用户名是否存在的功能点
- 较少出现在用户名密码同时判断的地方
3. LDAP注入基础利用
3.1 通配符查询
通过构造通配符查询实现布尔注入,逐步获取LDAP中存储的数据。
示例:
-
猜测用户名:
(cn=a*) - 返回密码错误 (cn=b*) - 返回用户名不存在递归匹配:
(cn=a*) (cn=ad*) (cn=adm*) (cn=admi*) (cn=admin*) -
通配符位置:
- 开头:
(cn=*n) - 中间:
(cn=a*n) - 单独使用:
(cn=*)
- 开头:
-
获取其他属性:
(cn=admin)(mobile=13*)
4. LDAP注入高级利用 - 获取用户密码
4.1 密码属性特点
LDAP密码存储在userPassword属性中,其类型为Octet String(字节序列),而非常规字符串。因此普通通配符无法用于部分匹配。
4.2 特殊匹配规则
使用octetStringOrderingMatch匹配规则(OID: 2.5.13.18)可以逐字节比较密码值。
规则说明:
- 比较两个字节序列的大小
- 从第一个字节到最后字节,从最高位到最低位逐位比较
- 第一个不同的位决定顺序(0位优先于1位)
- 如果长度不同但短序列与长序列前缀相同,则短序列优先
4.3 密码提取技术
-
使用十六进制转义
\xx匹配单个字节 -
构造查询:
(cn=admin)(userPassword:2.5.13.18:=\7b)- 返回"用户名错误":不匹配
- 返回"密码错误":匹配成功
-
逐步匹配每个字节:
(cn=admin)(userPassword:2.5.13.18:=\7b\4d) (cn=admin)(userPassword:2.5.13.18:=\7b\4e)注意:匹配到每个字节后,需要将该字节值减1再进行下一个匹配
-
将匹配到的字节序列转换为字符串得到密码
4.4 LDAP密码存储格式
新版本LDAP通常存储哈希后的密码,格式为:
{哈希类型}base64编码值
常见哈希类型:
{SHA}- SHA1{SSHA}- 加盐SHA1{MD5}- MD5{SMD5}- 加盐MD5
加盐hash存储格式:
hash值 + 盐值
5. 防御措施
5.1 输入过滤
转义可能改变LDAP过滤器语法的字符:
function ldapspecialchars($string) {
$sanitized = array(
'\\' => '\\5c',
'*' => '\\2a',
'(' => '\\28',
')' => '\\29',
"\x00" => '\\00'
);
return str_replace(array_keys($sanitized), array_values($sanitized), $string);
}
5.2 其他防御建议
- 使用预编译的LDAP查询语句
- 实施最小权限原则,限制LDAP绑定账户的权限
- 对查询结果数量进行限制
- 避免在错误信息中泄露敏感信息
- 使用LDAP服务器提供的安全功能(如TLS加密)
6. 参考资源
- RFC4519 - LDAP目录数据模型
- RFC4517 - LDAP语法和匹配规则
- LDAPWiki - octetStringOrderingMatch规则说明