LDAP简介
LDAP(Light Directory Access Portocol),它是基于X.500标准的轻量级目录访问协议。
目录是一个为查询、浏览和搜索而优化的数据库,它成树状结构组织数据,类似文件目录一样。
LDAP专注于优化查询,又很少有事务处理, 就像一个缓存一样
LDAP是Lightweight Directory Access Protocol的缩写,中文意思是目录服务的协议,并且以树状结构来存储数据.
主要用来存储企业人员信息和组织架构,进行统一认证管理.
同时可以与第三方应用集成,实现针对企业内部的人员或部门访问权限管理.
AD是windows Active Directory的缩写,AD应该是LDAP的一个应用实例,而不应该是LDAP本身。比如:windows域控的用户、权限管理应该是微软公司使用LDAP存储了一些数据来解决域控这个具体问题,
Active Directory = LDAP服务器+LDAP应用(Windows域控)
LDAP,轻量目录访问协议
Light Directory Access Portocol
dn:一条记录的位置
dc:一条记录所属的区域
ou:一条记录所属的组织
cn/uid:一条记录的名字/ID
dn Distinguished Name “uid=songtao.xu,ou=oa组,dc=example,dc=com”,一条记录的位置(唯一)
dc Domain Component 域名的部分,其格式是将完整的域名分成几部分,如域名为example.com变成dc=example,dc=com(一条记录的所属位置)
ou Organization Unit 组织单位,组织单位可以包含其他各种对象(包括其他组织单元),如“oa组”(一条记录的所属组织)
cn Common Name 公共名称,如“Thomas Johansson”(一条记录的名称)
uid User Id 用户ID songtao.xu(一条记录的ID)
LDAP用“树”来存数据。数据库主要是三个DB,TABLE,ROW来定位一条记录,而LDAP首先要说明是哪一棵树dc,然后是从树根到目的所经过的所有“分叉”, ou(group),最后就是目标的名字,例如UID等等。
dn:cn=honglv,ou=bei,ou=xi,ou=dong,dc=waibo,dc=com
其中树根是dc=waibo,dc=com,分叉ou=bei,ou=xi,ou=dong,目标cn=honglv
“cn=stan,ou=linux,ou=computer,dc=ourschool,dc=org”是一个整体,它只是属性dn的值
统一身份认证主要是改变原有的认证策略,使需要认证的软件都通过LDAP进行认证,在统一身份认证之后,用户的所有信息都存储在AD Server中。终端用户在需要使用公司内部服务的时候,都需要通过AD服务器的认证。
基本的LDAP语法
= 等于
& 逻辑和
| 逻辑或
! 逻辑不
* 通配符
逻辑符号 | 语法 | 含义 |
=(等于) | (givenName=John) | 这会返回“名”属性为“John”的所有对象。圆括号是必需的,以便强调 LDAP 语句的开始和结束 |
&(逻辑与) | (&(givenName=John)(l=Dallas)) | 操作符 & 表明,只有每个参数都为真,才会将此筛选条件应用到要查询的对象 |
!(逻辑非) | (!givenName=John) | 查找“名”为“John”的对象以外的所有对象 |
*(通配符) | (title=*) | 返回“title”属性包含内容的所有对象 |
(givenName=Jo*) | 返回“名”以“Jo”开头的所有对象。 |
**
LDAP注入
**
无逻辑操作符的注入
后端代码如果是这样写的:(attribute=$input)
构造输入语句:$input=value)(injected_filter
组合完整的语句了:(attribute=value)(injected_filter)
带有逻辑操作符的注入
(|(attribute=$input)(second_filter))
(&(attribute=$input)(second_filter))
此时带有逻辑操作符的括号相当于一个过滤器。此时形如value)(injected_filter)的注入会变成如下过滤器结构
(&(attribute=value)(injected_filter))(second_filter)
虽然过滤器语法上并不正确,OpenLDAP还是会从左到右进行处理,忽略第一个过滤器闭合后的任何字符。一些LDAP客户端Web组成会忽略第二个过滤器,将ADAM和OpenLDAP发送给第一个完成的过滤器,因而存在注入。
案例
万能用户名案例
验证登陆的查询语句是这样: (&(USER=$username)(PASSWORD=$pwd))
输入$username = admin)(&)(使查询语句变为: (&(USER=admin)(&))((PASSWORD=$pwd))
即可让后面的password过滤器失效,执行第一个过滤器而返回true,达到万能密码的效果。
权限提升案例
现假设下面的查询会向用户列举出所有可见的低安全等级文档:
(&(directory=document)(security_level=low))
这里第一个参数”document”是用户入口,low是第二个参数的值。如果攻击者想列举出所有可见的高安全等级的文档,他可以利用如下的注入:
document)(security_level=*))(&(directory=documents
生成的过滤器为:
(&(directory=documents)(security_level=*))(&(direcroty=documents)(security_level=low))
LDAP服务器仅会处理第一个过滤器而忽略第二个,因而只有下面的查询会被处理:(&(directory=documents)(security_level=*)),而(&(direcroty=documents)(security_level=low))则会被忽略。结果就是,所有安全等级的可用文档都会列举给攻击者,尽管他没有权限看它们。
防御
圆括号、星号、逻辑操作符、关系运操作符在应用层都必须过滤
正则表达式替换掉