0x00 前言

随着互联网的广泛使用,Web应用的数量越来越多,越来越多的数据呈分布式存储于目录中。目录服务在开发内部网和与互联网程序共享用户、系统、网络、服务和应用的过程中占据了重要地位。例如,目录服务可能提供了组织有序的记录集合,通常有层级结构,例如公司电子邮件目录。同理,也可以提供包含了地址和电话号码的电话簿。

目录访问协议Directory Access ProtocolDAP),X.500,由 ITU-T (X.500) 和 ISO (ISO/IEC 9594)定义的目录访问协议,提供一种方法,开发一个组织中的成员电子目录,使得世界各地具有因特网访问权限的任何人都可以访问作为全球目录一部分的该目录。

鉴于原先的目录访问协议(Directory Access Protocol即DAP)对于简单的互联网客户端使用太复杂,IETF设计并指定LDAP做为使用X.500目录的更好的途径。LDAP在TCP/IP之上定义了一个相对简单的升级和搜索目录的协议。

轻型目录访问协议Lightweight Directory Access ProtocolLDAP)是一个开放的,中立的,工业标准的应用协议,通过IP协议提供访问控制和维护分布式信息的目录信息。

LDAP和很多其他协议一样,基于tcp/ip协议通信,注重服务的可用性、信息的保密性等等。部署了LDAP的应用不会直接访问目录中的内容,一般通过函数调用或者API,应用可以通过定义的C、Java的API进行访问,Java应用的访问方式为JNDI(Java Naming and Directory Interface)

0x01 LDAP 数据结构

LDAP目录与普通数据库的主要不同之处在于数据的组织方式,它是一种有层次的、树形结构。

LDAP目录的条目(entry)由属性(attribute)的一个聚集组成,并由一个唯一性的名字引用,即专有名称distinguished name,DN)。例如,DN能取这样的值:“ou=people,dc=wikipedia,dc=org”。

0x02 LDAP查询语法

标识符 含义
= 等于,参数为表明某个属性
>= 大于等于
<= 小于等于
& 逻辑与
\ 逻辑或
逻辑非
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
LDAP目录:

dc=domain
|-ou=user
|-cn=zhangsan
|-cn=lisi
|-cn=wangwu
|-cn=zhaoliu
cn=zhangsan
objectClass=top
objectClass=person
name=张三
sex=男
age=28
pwd=123456
email=zhangsan@163.com

#查询所有name为张三,sex为男的用户:
(&(name=张三)(sex=男))
#查询所有age不为28的用户:
(!(age=28))
#查询所有age为28,并且name不为张三的用户:
(&(age=28)(!(name=张三)))
#查询所有age为28,或者name为张三的用户:
(|(age=28)(name=张三))

0x03 出现LDAP注入的情况

过滤器用于构造查询单缺少逻辑操作符:

1
(attribute=value)

构造attribute的值为value)(injected\_filter),则第二个过滤器将被忽略

注:而在ADAM中,有两个过滤器的查询是不被允许的,因而这个注入毫无用处。

第一个用于构造查询的过滤器有操作符

1
(|(attribute=value)(second_filter)) or (&(attribute=value)(second_filter))

构造attribute的值为value)(injected\_filter),则过滤器会变成(|(attribute=value)(injected_filter)) (second_filter),虽然过滤器语法不正确,但是服务器是从左向右执行处理,进而会忽略掉后面的过滤器。

0x04 注入实例

and注入
绕过访问验证

使用用户名和密码进行登陆,服务器会执行一下查询语句:

1
(&(USER=Uname)(PASSWORD=Pwd))

倘若构造USER=yunee)(&),则服务器执行的语句是:

1
(&(USER= slisberger)(&)(PASSWORD=Pwd))

它会引入任何字符作为PASSWORD的值,而服务器只处理了第一个过滤器,这个查询永真,类似于万能密码

权限提升

现假设下面的查询会向用户列举出所有可见的低安全等级文档:

1
(&(directory=document)(security_level=low))

构造document)(security_level=*))(&(directory=documents,则生成的过滤器为:

1
(&(directory=documents)(security_level=*))(&(direcroty=documents)(security_level=low))

这样,他就会列出所有权限的文档

OR注入
信息泄露

假设一个资源管理器允许用户了解系统中科用的资源,如打印机(printer),扫描器(scanner)。

当查询打印机的查询语句为:

1
(|(type=printer)(uid=*))

构造uid=1))(type=scanner),则过滤器则变为:

1
(|(type=printer)(uid=*))(type=scanner)

这样,会列出uid=1的打印机和所有扫描器。

0x05 参考文章

https://blog.csdn.net/quiet_girl/article/details/50716312

https://www.beichengjiu.com/computerscience/341701.html

https://blog.csdn.net/zlin3007/article/details/50834099