原生的Java自带命令执行
1、Runtime.exec
一个标准的Runtime.exec的代码demo
import java.io.*;
public class Main {
public static void main(String[] arg) throws IOException {
String command="cmd /c whoami";
Process proc = Runtime.getRuntime().exec(command);
InputStream in = proc.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF8"));
String line = null;
while((line=br.readLine())!=null) {
System.out.println(line);
}
}
}
其中exec存在两种方式的传参,分别为字符串和数组
数组形式
String[] command={"cmd","/c"," whoami|dir"};
Runtime.getRuntime().exec(cmommand);
Runtime.getRuntime().exec(new String[]{"cmd", "/c", "whoami"});
也可以直接字符串形式
String command="cmd /c whoami|dir";
Runtime.getRuntime().exec(cmommand);
Runtime.exec的底层是调用了ProccessBuilder.start。
2、ProccessBuilder.start
ProcessBuilder pb = new ProcessBuilder("whoami");
pb.start();
3、ProcessImpl
Runtime和ProcessBuilder执行命令实际上调用了也是ProcessImpl类
可以通过反射调用来进行命令执行
Class clazz = Class.forName("java.lang.ProcessImpl");
Method method = clazz.getDeclaredMethod("start", String[].class, Map.class, String.class, Redirect[].class, boolean.class);
method.setAccessible(true);
Process e = (Process) method.invoke(null, new String[]{"calc"}, null, ".", null, true);
值得注意的反射命令执行
我们可以看到图一是一个使用反射普通调用了addCommand,然后str为传入的参数,假设这个反射类的Servlet
CommandServlet,那么如果没有进行严格对类进行控制的话,我们就可以调用Java.lang.Runtime.exec来执行任意命令。
如下代码显示,可以看到非常明显的Java反射调用类,传入参数执行命令。
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.*;
import java.io.*;
public class exec {
public static void main(String args[]) {
try {
String name="java.lang.Runtime";
String method="exec";
String str="calc";
Class getCommandClass = Class.forName(name);
Constructor constructor = getCommandClass.getDeclaredConstructor();
constructor.setAccessible(true);
Object getInstance = constructor.newInstance();
// 获取类⽅法
Method getCommandMethod = getCommandClass.getDeclaredMethod(method, String.class);
getCommandMethod.setAccessible(true);
// 调⽤类⽅法
Object mes = getCommandMethod.invoke(getInstance, str);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
如何修复呢,严格设置权限即可
例如把强制反射给删了就好了。
constructor.setAccessible(true);
EL表达式
EL表达式之前学过了
第三方组件
最终也是需要一个runtime或者processbuild等Java原始命令执行命令
JS第三方执行命令
可执行js
Java-ScriptEngineManager
groovy第三方执行命令
需要groovy-all的pom.xml依赖包
groovyshell.evaluate
我们在平时代码审计里遇到的话就找这个POM或者相关的jar就好了,这个遇到的不多