从getter到jndi之LdapAttribute反序列化链
1174735059082055 WEB安全 448浏览 · 2025-04-08 05:17

从getter到jndi之LdapAttribute反序列化链

前言

如果现在可以调用 getter 方法但是在 jdk 高版本中 TransformerImpl 因为模块化无法使用我们还能有什么 sink 点呢,这就不得不提今天的主角 jdk 原生类 LdapAttribute 了,这个类存在 getter 方法可以打 jndi 注入。

调试分析

定位到 LdapAttribute#getAttributeDefinition() 方法,漏洞触发点在 getSchema 方法中,跟进



继续跟进 PartialCompositeDirContext.getSchema 方法,



一直到 c_resolveIntermediate_nns 方法,在这里调用了 LdapCtx.c_lookup 方法,



还记得 jndi 注入中 ldap 的调用栈

只要是调用这些方法中的任意一个都能触发 jndi 注入,这里就是 LdapCtx.c_lookup(),继续跟进就来到了我们熟悉的 decodeObject 方法,可以打 ldap 反序列化来绕过 jdk 高版本下的 jndi 注入,不过需要有 gadget。



简单写一个 cb 到 jndi 的 poc

JDBCParty

这是一道软件攻防初赛的 java 题,jdk 版本为17,在 /dbtest 路由存在反序列化和 jdbc 连接,



但是 jdbc 连接没法控制 url 所以我们的目光还是主要集中在反序列化上,看看依赖,存在 jackson,fastjson2,tomcat10.1.31 等

没有直接能用的反序列化链子,不过这里 fj 和 jackson 可以调用任意 getter 方法,TransformerImpl 因为模块化机制没法使用了,这时就可以考虑上面提到的 LdapAttribute 类了,把反序列化转换为 jndi 注入,

构造 poc

那么现在就变为了打 jdk 高版本下的 jndi 了,这里是 tomcat 10,自然没法使用 Beanfactory 了,不过在 tomcat 中还有个工程类可以利用那就是 MemoryUserDatabaseFactory,这个工程类可以实现 xxe 和写文件,

其 getObjectInstance 方法,判断 ResourceRef 是不是为 org.apache.catalina.UserDatabase



接着先实例化一个 MemoryUserDatabase 对象然后从 Reference 中取出 pathname、readonly 这两个最主要的参数并调用 setter 方法赋值。



赋值完成会先调用 open() 方法,如果 readonly=false 那就会调用 save() 方法。



跟进 open() 方法,连接给的 pathName 地址然后解析返回的 xml,



最后构造 ldap 服务端

test.xml

test.dtd

同样存在 jackson 不稳定性,多打几次,最后成功读取 E:/tmp/flag.txt 内容



虽然 java 中 file 协议的话还有列目录功能,但是外带貌似仅限于目录下只存在一个文件,尝试解决但是没有解决,至于写文件这里就不分析了。



其实参考 https://xz.aliyun.com/news/16917 发现还可以进行 rce。

参考:https://xz.aliyun.com/news/8630

参考:https://xz.aliyun.com/news/16904

参考:https://gsbp0.github.io/post/jdk17打jackson+ldapattruibute反序列化/

0 条评论
某人
表情
可输入 255