freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

Java ldap协议分析
yaklang 2023-11-07 16:34:02 116254

什么是ldap

LDAP是Lightweight Directory Access Protocol的缩写,顾名思义,它是指轻量级目录访问协议。这个协议是用于访问目录服务的。目录服务和数据库很类似,但又有着很大的不同之处。数据库设计为方便读写,但目录服务专门进行了读优化的设计,因此不太适合于经常有写操作的数据存储。

目录服务会通过树状结构存储数据,如下图,这样存储的优点就是查询效率高。


1699345034_6549f28a555bdedcf4cd4.png!small?1699345034745

上图这种树状结构,称为目录结构树(Directory Information Tree)(DIT),树上的每一个节点(不论是叶子节点还是中间的节点),都可以称为条目(Entry)。每个条目都有很多属性(Attribute),如下图:

1699345130_6549f2ea069acce16da74.png!small?1699345130375

每一个条目都有一个唯一的标识名(distinguished Name ,DN)。如上图的cn=Tux,它的DN就是cn=Tux,ou=devel,dc=example,dc=com,DN由多个RND(Relative Distinguished Name)通过逗号分割,如cn=Tux是RND,ou=devel 也是一个RND。

对象类(ObjectClass)是属性的集合,如图:

1699345146_6549f2fa6fba8758e8310.png!small?1699345146875

常见的dns服务,windows注册表等都是目录服务。

Java连接ldap流程

1699345174_6549f316b378a10ef9448.png!small?1699345175106

通过命名服务,查询ldap,获取到LdapUrlContext,然后继续lookup

1699345196_6549f32c6fc767ac1939a.png!small?1699345196848

supper:GenericUrlContext

1699345215_6549f33f3d31fd2cb8afa.png!small?1699345215562

然后如图

1699345493_6549f4551c213ce3c16e8.png!small?1699345493571

在创建LdapCtx时会认证ldap服务,如果失败,则直接抛异常

通过ldapUrl解析出DN,然后将DN和LdapCtx封装成ResolveResult返回

getResolvedObj获取到的是上一步的LdapCtx,getRemainingName获取到DN

1699345556_6549f494891b584d3ce17.png!small?1699345556875

p_lookup

1699345570_6549f4a23d189c8bca35d.png!small?1699345570722

c_lookup(LdapCtx)获取到对象

1699345624_6549f4d89e8463f73d1a3.png!small?1699345624999

doSearchOnce开始搜索

1699345641_6549f4e91de66a6db8df4.png!small?1699345641599

1699345647_6549f4efbe767f3be3555.png!small?1699345648181

1699345654_6549f4f68d82c9b7279cb.png!small?1699345654850

1699345661_6549f4fda1c824c503d16.png!small?1699345661965

搜索时的filter是(objectClass=*)

搜索数据

1699345684_6549f514bdb81fbb29ba2.png!small?1699345685244

身份认证

1699345732_6549f544f0485b6eb8c3e.png!small?1699345733326

协议使用LdapV3

build the bind request(认证过程就叫做bind,bind request就是认证请求)

1699345800_6549f588adb415837dbdf.png!small?1699345801087

如上图ber是在构造reauthenticate的数据包。可以看见有ASN_xxx,因为LDAP协议使用ASN.1规范进行描述,使用ASN.1 BER编码规范进行传输

身份认证时默认使用ldapv3协议,如果服务端返回状态码不是协议错误,则继续使用ldapv3。认证机制默认使用的是"none"(除此还有anontmous、simple、sasl)

解析Ldap Response

继续看c_lookup

1699345835_6549f5abb2468b8959627.png!small?1699345836088

这里有两个关键点,一是拿出controls数据,存到respCtls(response control),二是,如果有javaClassName属性,则调用decodeObject方法,解析出对象,如图:

1699345860_6549f5c49752e1234c37b.png!small?1699345861018

支持三种情况

  1. javaSerializedData

  2. javaRemoteLocation

  3. javaNamingReference

第三种情况,调用decodeReference方法,生成Reference对象

接着在c_lookup方法中调用DirectoryManager.getObjectInstance,解析Reference对象,,解析时会先从本地加载,如果为null,再通过codebase的地址去加载(需要com.sun.jndi.ldap.object.trustURLCodebase的值为true),导致任意类加载

再看第一种情况,通过helper.getURLClassLoader获取ClassLoader也需要com.sun.jndi.ldap.object.trustURLCodebase的值为true,如图:

1699345887_6549f5dfaf7c506f198b1.png!small?1699345887997

当没有设置url或trustURLCodebase为false时会返回父类加载器(AppClassLoader),然后再用这个加载器,反序列化javaSerializedData中的数据,这里可以作为反序列化利用,来绕过trstURLCodebase的限制

再看第二种情况javaRemoteLocation可以重新指定一个url,可以是ldap、rmi、iiop等协议,加载资源,支持的全部协议如图(似乎iiop协议可以反序列化)

1699345901_6549f5ed2fd402bc76046.png!small?1699345901445

Java ldap利用方式

  1. Reference对象,需要trustURLCodebase

  2. 设置javaSerializedData属性,可以反序列化

  3. 似乎iiop协议也可以反序列化(不确定)

YAK官方资源 :

Yak 语言官方教程:
https://yaklang.com/docs/intro/
Yakit 视频教程:
https://space.bilibili.com/437503777
Github下载地址:
https://github.com/yaklang/yakit
Yakit官网下载地址:
https://yaklang.com/
Yakit安装文档:
https://yaklang.com/products/download_and_install
Yakit使用文档:
https://yaklang.com/products/intro/
常见问题速查:
https://yaklang.com/products/FAQ

# java # LDAP协议
本文为 yaklang 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
yaklang LV.8
做难而正确的事!
  • 153 文章数
  • 106 关注者
独立SyntaxFlow功能?IRify,启动!
2025-03-31
那我问你,MCP是什么?回答我!
2025-03-24
SyntaxFlow实战CVE漏洞?那很好了
2025-03-14
文章目录