0x01 LDAP简介

LDAP,轻量目录访问协议

|dn :一条记录的位置|
|dc :一条记录所属区域|
|ou :一条记录所属组织|
|cn/uid:一条记录的名字/ID|

此处我更喜欢把LDAP和 数据库类比起来,我是直接把LDAP看成是一个主要用于查询的数据库。数据库用“表”来存数据,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的值

具体的一条记录如下:

dn:cn=stan,ou=linux,ou=computer,dc=ourschool,dc=org
objectClass:organizationalPerson
cn:stan
cn:小刀
sn:小刀
description:a good boy

(保存成LDIF文件,可以导入到LDAP数据库中)

关于安装配置LDAP,贴一个网址
http://www.mandrakesecure.net/en/docs/ldap-auth.php

0x02 LDAP基本语法

  • =(等于)
    查找“名“属性为“John”的所有对象,可以使用:
(givenName=John) 

  这会返回“名”属性为“John”的所有对象。圆括号是必需的,以便强调 LDAP 语句的开始和结束。

  • &(逻辑与)
    如果具有多个条件并且希望全部条件都得到满足,则可使用此语法。例如,如果希望查找居住在 Dallas 并且“名”为“John”的所有人员,可以使用:
(&(givenName=John)(l=Dallas))

请注意,每个参数都被属于其自己的圆括号括起来。整个 LDAP 语句必须包括在一对主圆括号中。操作符 & 表明,只有每个参数都为真,才会将此筛选条件应用到要查询的对象。

  • !(逻辑非)
    此操作符用来排除具有特定属性的对象。假定您需要查找“名”为“John”的对象以外的所有对象。则应使用如下语句:
(!givenName=John)

此语句将查找“名”不为“John”的所有对象。请注意:! 操作符紧邻参数的前面,并且位于参数的圆括号内。由于本语句只有一个参数,因此使用圆括号将其括起以示说明

  • *(通配符)

可使用通配符表示值可以等于任何值。使用它的情况可能是:您希望查找具有职务头衔的所有对象。为此,可以使用:

(title=*)

这会返回“title”属性包含内容的所有对象。另一个例子是:您知道某个对象的“名”属性的开头两个字母是“Jo”。那么,可以使用如下语法进行查找:

(givenName=Jo*)

这会返回“名”以“Jo”开头的所有对象。

高级用法eg:

您需要一个筛选条件,用来查找居住在 Dallas 或 Austin,并且名为“John”的所有对象。使用的语法应当是:

(&(givenName=John)(|(l=Dallas)(l=Austin)))

0x03 LDAP注入

LDAP注入攻击和SQL注入攻击相似,因此接下来的想法是利用用户引入的参数生成LDAP查询。一个安全的Web应用在构造和将查询发送给服务器前应该净化用户传入的参数。在有漏洞的环境中,这些参数没有得到合适的过滤,因而攻击者可以注入任意恶意代码。
使用得最广泛的LDAP:ADAM和OpenLDAP,下面的结论将会致代码注入:

3.1 引入

(attribute=value)

如果过滤器用于构造查询单缺少逻辑操作符,如value)(injected_filter ,瞬间导致产生了两个过滤器,

(attribute=value)(injected\_filter)

通常,在OpenLDAP实施中,第二个过滤器会被忽略,只有第一个会被执行。
而在ADAM中,有两个过滤器的查询是不被允许的,因而这个注入毫无用处。

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

如果第一个用于构造查询的过滤器有逻辑操作符,形如value)(injected_filter)的注入会变成如下过滤器:

(&(attribute=value)(injected_filter)) (second_filter)。

虽然过滤器语法上并不正确,OpenLDAP还是会从左到右进行处理,忽略第一个过滤器闭合后的任何字符。

但是有的浏览器会进行检查,检查过滤器是否正确,这种情况下value)(injected_filter))(&(1=0,于是就出现了下述payload

(&(attribute=value)(injected_filter))(&(1=0)(second_filter))

既然第二个过滤器会被LDAP服务器忽略,有些部分便不允许有两个过滤器的查询。这种情况下,只能构建一个特殊的注入以获得单个过滤器的LDAP查询,如value)(injected_filter得到

(&(attribute=value)(injected_filter)(second_filter))

3.2 AND注入

这种情况,应用会构造由”&”操作符和用户引入的的参数组成的正常查询在LDAP目录中搜索,例如:

(&(parameter1=value1)(parameter2=value2))

这里Value1和value2是在LDAP目录中搜索的值,攻击者可以注入代码,维持正确的过滤器结构但能使用查询实现他自己的目标。

3.2.1 绕过访问控制

一个登陆页有两个文本框用于输入用户名和密码,过滤器如下:

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

如果攻击者输入一个有效地用户名,如r00tgrok,然后再这个名字后面注入恰当的语句,password检查就会被绕过。输入Uname=slisberger)(&)),得到如下

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

LDAP服务器只处理第一个过滤器,即仅查询(&(USER=slidberger)(&))得到了处理。这个查询永真,故成功绕过

3.2.2 权限提升

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

(&(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=*))

结果就是,所有安全等级的可用文档都会列举给攻击者

3.3 OR注入

这种情况,应用会构造由”|”操作符和用户引入的的参数组成的正常查询在LDAP目录中搜索,例如:

(|(parameter1=value1)(parameter2=value2))

这里Value1和value2是在LDAP目录中搜索的值,攻击者可以注入代码,维持正确的过滤器结构但能使用查询实现他自己的目标。

具体的注入方式和AND差不太多,不予详述。

3.4 LDAP盲注

3.4.1 AND盲注

假设一个Web应用想从一个LDAP目录列出所有可用的Epson打印机,错误信息不会返回,应用发送如下的过滤器:

(&(objectClass=printer)(type=Epson*))

正确的过滤器为:

(&(objectClass=printer)(type=Epson*))

而当注入)(objectClass=))(&(objectClass=void时得到

(&(objectClass=*)(objectClass=*))(&(objectClass=void)(type=Epson*))

执行第一个,过滤器objectClass=*总是返回一个对象。当图标被显示时响应为真,否则为假。
这样我们就可以猜第二个括号的objectclass字段有些什么内容了。
LDAP盲注技术让攻击者使用基于TRUE/FALSE的技术访问所有的信息。

3.4.2 OR盲注

这种情况下,用于推测想要的信息的逻辑与AND是相反的,因为使用的是OR逻辑操作符。同样不予详述。

3.4.3 盲注深入

攻击者可以使用字母、数字搜索提取属性的值,这个想法的关键在于将一个复杂的值转化为TRUE/FALSE列表。这个机制,通常称为booleanization,大意是二值化吧,图十二概括了该机制,可用于不同的方式。
假设攻击者想知道department属性的值,处理如下:

(&(idprinter=HPLaserJet2100)(department=a*))(object=printer))
(&(idprinter=HPLaserJet2100)(department=f*))(object=printer))
(&(idprinter=HPLaserJet2100)(department=fa*))(object=printer))

如此根据返回的不同结果猜解是否正确,和MYSQL盲注类似。
同样,攻击者可以使用字符集削减技术减少获得信息所需的请求数,为完成这一点,他使用通配符测试给定的字符在值中是否为anywhere

(&(idprinter=HPLaserJet2100)(department=*b*))(object=printer))
(&(idprinter=HPLaserJet2100)(department=*n*))(object=printer))

这样子可以看department中是否有b和n,巧用可以加速猜解过程,当然一般肯定都是写脚本猜解

0x04 防御LDAP注入

总而言之,我们看到圆括号、星号、逻辑操作符、关系运操作符在应用层都必须过滤。
无论什么时候,只要可能,构造LDAP搜索过滤器的值在发送给LDAP服务器查询之前都要用应用层有效地值列表来核对。正则表达式替换掉就可以了。

0x05 参考

http://drops.wooyun.org/tips/967
http://www.chinaunix.net/old_jh/49/593660.html
http://blog.sina.com.cn/s/blog_6151984a0100ey3z.html

理解LDAP与LDAP注入的更多相关文章

  1. 【LDAP】LDAP注入漏洞与防御

    0x01 前言 前两天爆了一个LDAP漏洞,据说存在了8年现在才被发现,感概一下,不知这8年来有多少站被搞了... 想着复现这个漏洞,就先复习一下LDAP注入的相关知识吧,差了很多资料,记一下笔记. ...

  2. Spring学习-理解IOC和依赖注入

    最近刚买了一本介绍ssm框架的书,里面主要对Mybatis.spring.springmvc和redis做了很多的讲解,个人觉得虽然有的内容我看不懂,但是整体上还是不错的.最近正在学习中,一边学习一边 ...

  3. 如何理解php的依赖注入

    之前写过关于php依赖注入的文章..最近发现有的朋友对这个还是理解模糊,在这里我想写个简单的实例帮助朋友们理解下...传统的思路是应用程序用到一个A类,就会创建A类并调用A类的方法,假如这个方法内需要 ...

  4. LDAP summary-- Python ldap

    A DN is comprised of a series of RDNs (Relative Distinguished Names) found by walking UP the tree (D ...

  5. 【LDAP】LDAP常用命令解析

    ldapadd -x   进行简单认证-D   用来绑定服务器的DN-h   目录服务的地址-w   绑定DN的密码-f   使用ldif文件进行条目添加的文件例子 ldapadd -x -D &qu ...

  6. 【LDAP】ldap目录服务的命名模型

    ldap的命名模型 命名模型规定了在目录中如何组织和表示条目 1.   目录信息树(DIT) 目录信息树有点类似于DNS的结构.每一个条目都有自己的父条目(因为主条目的父条目是top,所以这句话是成立 ...

  7. 【LDAP】LDAP 中 CN, OU, DC 的含义

    1. LDAP的存储规则 区分名(DN,Distinguished Name) 和自然界中的树不同,文件系统/LDAP/电话号码簿目录的每一片枝叶都至少有一个独一无二的属性,这一属性可以帮助我们来区别 ...

  8. 【LDAP】LDAP介绍

    原文:http://ldapman.org/articles/intro_to_ldap.html原文作者:Michael Donnelly 什么是LDAP? LDAP的英文全称是Lightweigh ...

  9. SpringBoot系列: 理解 Spring 的依赖注入(二)

    ==============================Spring 容器中 Bean 的名称==============================声明 bean 有两个方式, 一个是 @B ...

随机推荐

  1. 单页应用(SPA,Single-page-App)和多页应用(MPA,Multi-page App)的区别

    单页应用(SPA,Single-page-App)和多页应用(MPA,Multi-page App)的区别 参考博客:https://www.jianshu.com/p/4c9c29967dd6

  2. iOS9下的Map Kit View下的使用

    最近有个任务是关于地理位置上的标注开发,经过一些资料的查找和对比,现总结一些经验,给读者也是给自己. iOS9下的Map Kit View实际是以前MapKit,只不过换了一个名字,实际是指同一个UI ...

  3. vue路由--动态路由

    前面介绍的路由都是路径和组件一对一映射的 有时候需要多个路径映射到一个组件,这个组件根据参数的不同动态改变,这时候需要用到动态路由 动态路由这样定义路由路径: path: '/foo/:id'--可以 ...

  4. NCE L5

    课文内容 重点单词解析 重点课文解析

  5. MySQL中的幻读,你真的理解吗?

    昨天接到阿里的电话面试,对方问了一个在MySQL当中,什么是幻读.当时一脸懵逼,凭着印象和对方胡扯了几句.面试结束后,赶紧去查资料,才发现之前对幻读的理解完全错误.下面,我们就聊聊幻读. 要说幻读,就 ...

  6. C语言三(2)

    多重 if...else....else 结构 语法: if(条件1) { 语句1; } else if(条件2) { 语句2; } else if(条件3) { 语句3; } else { 语句N; ...

  7. scons自动化构建工具

    方式一 可以官方下载,安装使用 方式二 使用 RT-Thread env工具,其中集成了scons工具 env工具配置 打开设置 添加到右键菜单 使用scons生成mdk5工程 > scons ...

  8. jni和线程

    JNI官方规范中文版——在程序中集成JVM需要注意的JNI特征 翻译 我们已经讨论了JNI在写本地代码和向本地应用程序中集成JVM时的特征.本章接下来的部分分介绍其它的JNI特征. 8.1 JNI和线 ...

  9. nCompass-产品配置基础

    nCompass-产品配置基础 设备上架后,浏览器登陆设备的管理IP,输入用户名和密码, 登入进入视图展示页面 1. 添加许可 新设备上架之后,要添加许可方能使用. 步骤: 系统设置 --- 许可-- ...

  10. 并发编程之J.U.C的第二篇

    并发编程之J.U.C的第二篇 3.2 StampedLock 4. Semaphore Semaphore原理 5. CountdownLatch 6. CyclicBarrier 7.线程安全集合类 ...