LDAP注入原理及防御

admin 2026-02-02 00:46:46 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 文章深入解析LDAP注入原理,涵盖树形结构、查询语法及AND/OR/盲注攻击手法。通过PentesterLab靶场演示利用通配符与过滤器闭合绕过认证的具体过程。强调防御需严格进行输入验证,对特殊字符进行转义处理,以有效防止注入风险。 综合评分: 85 文章分类: WEB安全,漏洞分析,渗透测试,漏洞POC,安全开发


cover_image

LDAP注入原理及防御

原创

dcnb dcnb

Web安全基础与实践

2026年1月29日 21:30 广东

LDAP,全称为轻量目录访问协议(Lightweight Directory Access Protocol),是一种基于X.500标准的轻量级目录服务协议,用于用于集中存储、查询、管理分布式环境中的结构化目录数据(如用户账号、设备信息、权限配置等),广泛应用于企业级身份认证、资源访问控制等场景。

1LDAP简介

LDAP是一种通讯协议,支持TCP/IP,其默认端口为389,加密端口为636。与MySQL等关系型数据库将数据按记录一条条记录在表中不同,LDAP数据库的结构是树型的,数据是存储在叶子节点上的。这种存储结构十分有利于数据的查询,但无法支持频繁的写操作,因此LDAP适用于需要静态存储大量数据且快速查找的场景。

LDAP目录中的数据结构类似于文件系统的目录树。树的顶端是根(Root),向下扩展出多个分支,每个分支可以包含更多的分支或叶子节点,也就是最终的条目。目录中的信息包括:

(1)dn:一条记录的位置;

(2)dc:一条记录所属的区域;

(3)ou:一条记录所属的组织;

(4)cn/uid:一条记录的名字/ID。

目录信息树(DIT)是LDAP中的数据组织方式。在查询时,首先说明数据位于哪一棵树(dc),然后从树根到目标所经过的所有分叉(ou),最后得到数据的名字(cn/uid),具体结构如图1所示。

图1  DIT结构示意

在LDAP中,条目(entry)是目录中存储的基本信息单元,图1中每一个方框就代表一个条目。每个条目有若干个属性和若干个值,有些条目还可以包含子条目。下面是一个用户条目的示例:

dn: cn=websec,ou=people,dc=example,dc=comcn: websecsn: websecmail: [email protected]: inetOrgPerson

其中mail等数据就是条目中的属性,存储条目的具体信息。objectClass就是条目中的对象类,用于定义条目的属性集合,每个条目必须关联至少一个对象类(如inetOrgPerson,通用用户类)。

2、LDAP注入漏洞原理

2.1 LDAP查询语法

在介绍LDAP注入之前,我们首先对LDAP的查询语法进行简单的介绍。

LDAP查询使用一种类似于布尔逻辑表达式的过滤器语法,基本的LDAP查询语法如下:

(1)基本结构(属性=值)

cn=websec

这条查询语句用于查找所有属性cn的值等于websec的条目。

(2)逻辑AND运算

(&(objectClass=inetOrgPerson)(cn=websec))

这条查询语句用于查找所有objectClass属性为inetOrgPerson且cn为websec的条目。

(3)逻辑OR运算

(|(cn=websec1)(cn=websec2))

这条查询语句用于查找cn为websec1或websec2的条目。

(4)逻辑NOT运算

(!(cn=websec))

这条查询语句用于查找所有cn不为websec的条目。

2.2 LDAP注入漏洞

(1)AND注入

对于这种攻击方式,应用会构造由“&”操作符和和用户引入的参数组成的正常查询在LDAP目录中搜索,如上文逻辑AND运算所示。此时攻击者可以注入代码,维持正常的过滤器结构但能使用查询实现恶意攻击。

对于一个需要输入用户名和密码的登陆界面,UserName和Passwd分别对应用户名和密码,如果攻击者输入一个有效的用户名(假设为websec),再构造一个合法的过滤器结构,Passwd检查就会被绕过。Payload如下所示:

(&(UserName=websec(&))(Passwd=pwd))

LDAP服务器只处理第一个过滤器,即(&(UserName=websec(&)),该查询永真。因此攻击者无需密码即可访问系统。

(2)OR注入

对于这种攻击方式,应用会构造由“|”操作符和和用户引入的参数组成的正常查询在LDAP目录中搜索,如上文逻辑OR运算所示。此时攻击者可以注入代码,维持正常的过滤器结构但能使用查询实现恶意攻击。

对于一个资源管理器,其允许用户访问系统中的打印机、扫描机等资源。在该场景下就可以使用OR注入。

我们假设Rsc1=Printer表示系统中可用的打印机,Rsc2=Scanner为系统中可用的扫描机。如果攻击者构造如下Payload,LDAP服务器会响应所有的打印机和用户对象:

(|(type=Printer)(uid=*))(type=Scanner)

(3)LDAP盲注

假设攻击者可以从服务器响应中推测出一些内容,尽管应用没有报出错信息,LDAP过滤器中注入的代码却生成了有效的响应或错误。攻击者可以利用这一行为向服务器询问正确的或错误的问题,这种攻击称之为盲注攻击。

我们假设对象类为class,其对应一类数据,其中包含cn等于websec的一组数据,错误信息不会返回。如果用户想要从LDAP目录中获取所有的websec数据,可以构造如下过滤器:

(&(objectClass=class)(cn=websec*))

该查询会回显所有对象类为class,cn等于websec的数据。这是一个合法的查询语句。

如果攻击者进行LDAP盲注,可以构造如下Payload:

(&(objectClass=*)(objectClass=*))(&(objectClass=void)(cn=websec*))

此时仅第一个LDAP过滤器会被处理,这样cn等于websec的数据一定会回显。

这种代码注入方式允许攻击者推测可能存在于LDAP目录服务中不同对象类的值。当响应页面至少包含一个数据时,对象类的值就是存在的,如果对象类的值不存在或没有对它的访问,就不会有回显。

除了利用AND进行盲注外,还可以使用OR进行盲注。此时用于推测想要的信息的逻辑与AND相反。对于上述例子,我们可以构造如下Payload:

(|(objectClass=void)(objectClass=class))(&(objectClass=void)(cn=websec*))

该LDAP查询可以从目录中获取对象为class,cn等于websec的数据,从而收集信息。

3、LDAP注入实例

本文在Windows10攻击机中进行LDAP注入演示。

3.1靶场搭建

本文利用PentesterLab提供的靶场进行实例演示(iso镜像文件下载链接https://pentesterlab.com/exercises/web_for_pentester/attachments)。

在安装并设置完虚拟机配置后,打开虚拟机,如图2所示。

图2  靶场虚拟机界面

接着,输入sudo su切换至管理员权限,并输入ifconfig查看靶场ip地址,如图3所示。

图3  靶场ip地址查看

根据在虚拟机中查询到的ip地址,直接在win10攻击机中访问该地址,进入靶场,如图4所示。

图4  靶场界面

3.2 LDAP attacks – Example1

进入Example1后,发现界面显示未认证,如图5所示。

图5  Example1未认证界面

我们首先查看后端php代码:

<?php&nbsp;&nbsp;require&nbsp;"../header.php"&nbsp;;&nbsp;&nbsp;&nbsp;$ld&nbsp;=&nbsp;ldap_connect("localhost")&nbsp;or&nbsp;die("Could not connect to LDAP server");&nbsp;&nbsp;ldap_set_option($ld, LDAP_OPT_PROTOCOL_VERSION,&nbsp;3);&nbsp;&nbsp;&nbsp;ldap_set_option($ld, LDAP_OPT_REFERRALS,&nbsp;0);&nbsp;&nbsp;if&nbsp;($ld) {&nbsp; &nbsp;if&nbsp;(isset($_GET["username"])) {&nbsp;&nbsp; &nbsp; &nbsp;$user&nbsp;=&nbsp;"uid=".$_GET["username"]."ou=people,dc=pentesterlab,dc=com";&nbsp; &nbsp;}&nbsp; &nbsp;$lb&nbsp;= @ldap_bind($ld,&nbsp;$user,$_GET["password"]);&nbsp;&nbsp; &nbsp;&nbsp;if&nbsp;($lb) {&nbsp; &nbsp; &nbsp; &nbsp;echo&nbsp;"AUTHENTICATED";&nbsp; &nbsp; }&nbsp; &nbsp;&nbsp;else&nbsp;{&nbsp; &nbsp; &nbsp; &nbsp;echo&nbsp;"NOT AUTHENTICATED";&nbsp; &nbsp; }&nbsp; }&nbsp;&nbsp;require&nbsp;"../footer.php"&nbsp;;&nbsp;?>

其中关键函数为ldap_bind(),它使用指定的RDN($bind_rdn)和密码($bind_password)绑定到LDAP目录,如果未指定则使用匿名认证。因此我们可以利用不提交用户名和密码的方式实现匿名登录访问。可以构造如下Payload:

http://192.168.1.129/ldap/example1.php

提交后发现认证成功,如图6所示。

图6  Example1认证成功

3.3 LDAP attacks – Example2

初始界面为以hacker身份认证,被认为不合法,如图7所示。

图7  Example2不合法认证界面

我们查看后端php代码:

<?php&nbsp;&nbsp;require&nbsp;"../header.php"&nbsp;;&nbsp;&nbsp;&nbsp;$ld&nbsp;=&nbsp;ldap_connect("localhost")&nbsp;or&nbsp;die("Could not connect to LDAP server");&nbsp;&nbsp;ldap_set_option($ld, LDAP_OPT_PROTOCOL_VERSION,&nbsp;3);&nbsp;&nbsp;&nbsp;ldap_set_option($ld, LDAP_OPT_REFERRALS,&nbsp;0);&nbsp;&nbsp;if&nbsp;($ld) {&nbsp; &nbsp;$lb&nbsp;= @ldap_bind($ld,&nbsp;"cn=admin,dc=pentesterlab,dc=com",&nbsp;"pentesterlab");&nbsp; &nbsp;&nbsp;if&nbsp;($lb) {&nbsp; &nbsp; &nbsp;&nbsp;$pass&nbsp;=&nbsp;"{MD5}".base64_encode(pack("H*",md5($_GET['password'])));&nbsp; &nbsp; &nbsp;&nbsp;$filter&nbsp;=&nbsp;"(&(cn=".$_GET['name'].")(userPassword=".$pass."))";&nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(!($search=@ldap_search($ld,&nbsp;"ou=people,dc=pentesterlab,dc=com",&nbsp;$filter))) {&nbsp; &nbsp; &nbsp;&nbsp;echo("Unable to search ldap server<br>");&nbsp; &nbsp; &nbsp;&nbsp;echo("msg:'".ldap_error($ld)."'</br>");&nbsp; &nbsp; }&nbsp;else&nbsp;{&nbsp; &nbsp; &nbsp;&nbsp;$number_returned&nbsp;=&nbsp;ldap_count_entries($ld,$search);&nbsp; &nbsp; &nbsp;&nbsp;$info&nbsp;=&nbsp;ldap_get_entries($ld,&nbsp;$search);&nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;($info["count"] <&nbsp;1) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//NOK&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;echo&nbsp;"UNAUTHENTICATED";&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp;&nbsp;else&nbsp;{&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;echo&nbsp;"AUTHENTICATED as";&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;echo(" ".htmlentities($info[0]['uid'][0]));&nbsp; &nbsp; &nbsp; } &nbsp; &nbsp;&nbsp; &nbsp; }&nbsp; &nbsp;}&nbsp; }&nbsp;&nbsp;require&nbsp;"../footer.php"&nbsp;;&nbsp;?>

分析代码,其中关键为filter,也就是LDAP过滤器,其形式为$filter = “(&(cn=”.$_GET[‘name’].”)(userPassword=”.$pass.”))”。此时我们可以使用上文介绍的AND注入攻击方式实现无需密码登录。由于我们目前还不知道用户名是什么,而AND注入的前提是有有效的用户名,我们可以使用通配符*进行模糊匹配。根据上述思路,构造如下Payload:

http://192.168.1.129/ldap/example2.php?name=a*)(cn=*))%00password=pwd

其中a*代表以a开头的单词,这是尝试获取用户名的信息。此时LDAP服务器只处理第一个过滤器,也就是&(name=a*)(cn=*),可以使用任意密码登录,回显界面如图8所示。

图8  Example2正确回显

可以发现已经以admin身份认证。

此外,我们还可以尝试获取其他用户名信息,构造如下payload获取以b开头的用户名:

http://192.168.1.129/ldap/example2.php?name=b*)(cn=*))%00password=pwd

可以发现回显显示认证失败,可知没有满足条件的用户名,如图9所示。

图9  Example2尝试获取其他用户名

想要获取其他条件的用户名信息构造方式相似,使用通配符技巧查找用户。

4、LDAP注入防御

LDAP注入的防御方式与SQL注入类似,主要是要对用户的输入进行合法性验证,做好过滤工作,就可以实现有效防御。

我们给出了LDAP涉及的特殊字符及需要转义处理的字符,如图10所示。

图10  LDAP涉及的特殊字符及需要转义处理的字符

本文由刘嘉奕同学投稿。

  • END –

免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:Web安全基础与实践 dcnb dcnb《LDAP注入原理及防御》

LDAP注入原理及防御 网络安全文章

LDAP注入原理及防御

文章总结: 文章深入解析LDAP注入原理,涵盖树形结构、查询语法及AND/OR/盲注攻击手法。通过PentesterLab靶场演示利用通配符与过滤器闭合绕过认证
Snort安装及基本用法 网络安全文章

Snort安装及基本用法

文章总结: 本文档详述了在CentOS7环境下安装与配置开源入侵检测系统Snort的过程。内容包括前置准备、组件安装、配置文件修改、自定义ICMP规则编写及功能
Apifox安装及基本用法 网络安全文章

Apifox安装及基本用法

文章总结: 本文介绍Apifox的安装与用法,强调其集API文档、调试、Mock及自动化测试于一体的特性。虽非漏洞扫描器,但能辅助接口重放、参数篡改和逻辑分析。
Ncrack安装及基本用法 网络安全文章

Ncrack安装及基本用法

文章总结: 本文详细介绍了网络认证爆破工具Ncrack的安装流程与基础操作,包括在Windows环境下的部署及字典文件准备。文章通过实战演示,说明了如何利用Nc
评论:0   参与:  0