Command execution of Java audit

Command execution of Java audit

0x00 Preface

In fact, there are not many classes that can execute commands in Java, unlike various command execution functions like PHP. There are only two classes known in Java that can execute commands, namely runtime and processbuilder.

0x01 runtime execution command analysis

For the specific use of runtime, see this article to call runtime.

Reflection of java learning

@WebServlet("/execServlet")
public class execServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {
    this.doGet(request,response);
    }

    protected void doGet(HttpServletRequest request,IOException {
        String exec = request.getParameter("exec");
        Process res = Runtime.getRuntime().exec(exec);

        InputStream inputStream = res.getInputStream();
        ServletOutputStream outputStream = response.getOutputStream();

        int len;
        byte[] bytes = new byte[1024];
        while ((len = inputStream.read(bytes))!=-1){
            outputStream.write(bytes,len);


        }

Here to run, pass in a command to see if it can run normally.

http://localhost:8080/untitled9_war_exploded/execServlet?exec=ipconfig

Let's take a look at his specific implementation. First, trace the getruntime () method.

When you see the calling method, you directly return the currentruntime object without any processing. You can see that the currentruntime is an instance object of the runtime. That is, each time the getruntime () method is called, a new runtime object will be created.

Official document description:

每个Java应用程序都有一个Runtime类的Runtime ,允许应用程序与运行应用程序的环境进行接口。 当前运行时可以从getRuntime方法获得。 
应用程序无法创建自己的此类的实例。

Let's trace the exec method and see the concrete implementation of the exec method

There are multiple overloaded methods in exec, which track the return value of exec

Or his overloaded method, and then track

You'll find something different here. It's back

return new ProcessBuilder(cmdarray)
            .environment(envp)
            .directory(dir)
            .start();

During tracking, we will find that the ipconfig we passed in will be passed in the cmdarray variable, and other values are null. In other words, the bottom layer of this class is actually implemented by processbuilder.

Previous process res = runtime getRuntime(). exec(exec); The return type is process, which is returned through new processbuilder, passing in the command, and then calling the start method.

But the res.getinputstream();, which follows us;, getInputStream(); How did you get here? Process is an abstract class that contains six abstract methods.

abstract public OutputStream getOutputStream();


abstract public InputStream getInputStream();


abstract public InputStream getErrorStream();


abstract public int waitFor() throws InterruptedException;


abstract public int exitValue();


abstract public void destroy();

Follow up. These methods, the methods called, except the start method, set values for other methods. I won't demonstrate them one by one here.

return new ProcessBuilder(cmdarray)
            .environment(envp)
            .directory(dir)
            .start();

Trace start method

You can see that in the start method, the implementation class of process is called.

0x02 command execution in processbuilder

package com.test;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;

@WebServlet("/exec2Servlet")
public class exec2Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request,IOException {

    }

    protected void doGet(HttpServletRequest request,IOException {
        String exec = request.getParameter("exec");
        ServletOutputStream outputStream = response.getOutputStream();
        ProcessBuilder processBuilder = new ProcessBuilder(exec);

        Process res = processBuilder.start();
        InputStream inputStream = res.getInputStream();
        int len ;
        byte[] bytes =new byte[1024];
        while ((len = inputStream.read(bytes))!=-1){
            outputStream.write(bytes,len);
        }

    }
}

You can also execute commands by using processbuilder.

0x03 content supplement

There is a special title in the back to supplement the previous knowledge.

Process class

Process class method:

destroy()

杀掉子进程。

exitValue()

返回子进程的出口值。

InputStream getErrorStream()

获得子进程的错误流。

InputStream getInputStream()

获得子进程的输入流。

OutputStream getOutputStream()

获得子进程的输出流。

waitFor()

导致当前线程等待,如果必要,一直要等到由该 Process 对象表示的进程已经终止。

A problem that will be found earlier is solved here. Since process is an abstract class, can't you get its instance class from the new object?

When debugging the code earlier, we found that the start method of processbuilder can be used to return. The second method is the exec method of runtime, but the bottom layer of the exec method of runtime is still implemented by the start method of processbuilder.

There is another problem that needs to be mentioned here, processbuilder and runtime What is the difference between exec()?

After consulting some ideas on the Internet, we draw the following conclusions.

ProcessBuilder.start() 和 Runtime.exec() 方法都被用来创建一个操作系统进程(执行命令行操作),并返回 Process 子类的一个实例,该实例可用来控制进程状态并获得相关信息。

ProcessBuilder.start() 和 Runtime.exec()传递的参数有所不同,Runtime.exec()可接受一个单独的字符串,这个字符串是通过空格来分隔可执行命令程序和参数的;也可以接受字符串数组参数。而ProcessBuilder的构造函数是一个字符串列表或者数组。列表中第一个参数是可执行命令程序,其他的是命令行执行是需要的参数。

Reference articles

https://honeypps.com/java/process-builder-quick-start/

0x04 end

When encountering some problems, it is also a good choice to debug more. More debugging can clearly analyze the problem. For example, when debugging code, you can debug and analyze it layer by layer, and you will find some interesting things.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>