Thursday. September 27, 2018
– 6 mins
0x01 简介
Java 执行系统命令的方法
易导致命令注入的危险写法以及如何避免
0x02 注意点
首先要注意的是,通过 Java 来执行系统命令时,并不是通过 shell 来执行 (Linux下),因此如果需要用到如 pipeline ( |
)、 ;
、 &&
、 ||
等 shell 特性时,需要创建 shell 来执行命令,如:
/bin/sh -c "ls -lh; pwd"
具体可参考 https://alvinalexander.com/java/java-exec-system-command-pipeline-pipe
0x03 执行方式
ProcessBuilder
java.lang.ProcessBuilder
中 start()
方法可以执行系统命令,命令和参数可以通过构造方法的 String List 或 String 数组来传入
ProcessBuilder(List command)
ProcessBuilder(String... command)
如执行 ls -lh /home/www
的例子
String[] cmdList = new String[]{"ls", "-lh", "/home/www"};
ProcessBuilder builder = new ProcessBuilder(cmdList);
builder.redirectErrorStream(true);
Process process = builder.start();
因为 Java 中执行命令不是通过 shell,若没有手动创建 shell 来执行命令,命令非完全可控时,正常的情况下是无法使用 ;
、 &&
等来实现命令注入的,例如
命令的某个参数可控
// String dir = "xx";
String[] cmdList = new String[]{"ls", "-lh", dir};
ProcessBuilder builder = new ProcessBuilder(cmdList);
builder.redirectErrorStream(true);
Process process = builder.start();
printOutput(process.getInputStream());
dir
参数用户可控,如想通过传入 /home/www;id
, 来执行 id 命令,是无法成功的,程序的输出为
<