1.本地命令执行函数
在服务器中时常会调用命令执行的代码,以完善或加强系统的功能需求,一旦这些调用命令执行的接口被攻击者恶意利用,就会导致服务器沦陷。
在Java中可用于执行系统命令的方式有API有:java.lang.Runtime、java.lang.ProcessBuilder、java.lang.UNIXProcess/ProcessImpl。这几种API又存在如下对应关系:
1.1 Runtime、ProcessBuilder、ProcessImpl的关系
Runtime构造器为私有,类的对象无法通过Runtime runtime = new Runtime();
创建,只能通过静态方法Runtime r = Runtime.getRuntime();
获取
跟进Runtime.getRuntime().exec()
函数
调用了ProcessBuilder的start函数
继续跟进ProcessBuilder的start函数,发现调用ProcessImpl的start函数
1.2 Runtime类
请求访问http://127.0.0.1:8080/runtime?cmd=calc
1.3 ProcessBuilder类
请求访问http://127.0.0.1:8080/processBuilder?cmd=calc
1.4 ProcessImpl类
因为ProcessImpl类的构造器和Runtime类一样都是private
类型,无法直接new
一个对象,但可以通过反射的方式调用。
//http://127.0.0.1:8080/processImpl?cmd=calc
@RequestMapping("/processImpl")
@ResponseBody
public void processImpl(@RequestParam(name = "cmd") String[] cmd) throws IOException {try {Class claszz = Class.forName("java.lang.ProcessImpl");Method method = claszz.getDeclaredMethod("start",new String[]{}.getClass(),Map.class,String.class,ProcessBuilder.Redirect[].class,boolean.class);method.setAccessible(true);method.invoke(null, cmd,null,".",null,true);} catch (ClassNotFoundException | NoSuchMethodException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}
请求访问http://127.0.0.1:8080/processImpl?cmd=calc