前言:命令执行的几种方法
反射利用Runtime.getRuntime().exec或java.lang.ProcessBuilder执行
JNDI远程调用
Templates执行字节码
EL表达式
其他可执行命令的接口
一.os命令执行
1.java常用执行系统命令函数
Runtime.exec
Process
GroovyShell.evaluate
ProcessBuilder.start()
2.补充知识点
Process类方法:
1.destroy()
杀掉子进程。
2.exitValue()
返回子进程的出口值。
3.InputStream getErrorStream()
获得子进程的错误流。
4.InputStream getInputStream()
获得子进程的输入流。
5.OutputStream getOutputStream()
获得子进程的输出流。
6.waitFor()
导致当前线程等待,如果必要,一直要等到由该 Process 对象表示的进程已经终止。
3.注意点
核心其实就是三类 完全可控,非shell参数可控,shell参数可控
①如果命令执行的可控参数只是参数可控,那么想通过;、|、&等实现命令注入是不可的
原因:
1.Runtime.exec允许传入字符串但是传入的字符串会被拆分掉
如
Process process = runtime.exec("ping -c 1 " + ip);
//这种传入 127.0.0.1 | id,是无法正常执行的
2.ProcessBuilder.start 不允许直接传字符串进去,只能拆分为List或者数组的形式才可以执行。
4.漏洞实例
//cmd直接拼接在参数中的 导致肯定造成漏洞
String cmd = request.getParameter("cmd");
Runtime runtime = Runtime.getRuntime(); //Runtime.getRuntime.exec
ProcessBuilder processBuilder = new ProcessBuilder(cmd);
Process process = processBuilder.start();