特殊符号&、&&、|、||
特殊符号 |
描述 |
& |
表示与,a&b,条件a和条件b都执行了 |
| |
表示或,a|b,条件a和条件b都执行了 |
&& |
表示与,短路与,a&&b当条件a错误不会执行条件b |
|| |
表示或,短路或,a||b当条件a正确不会执行条件b |
在Windows或者Linux下执行命令时,会将|
作为管道符,将两个应用程序连接在一起,把第一个应用程序的输出作为第二个应用程序的输入。
另外Linux执行命令还有一个特殊符号;
,多个命令顺序执行,命令之间无任何逻辑关系:
有一个坑点需要提示:
用|
连接两个命令,前后命令都会执行,只不过不会再控制台显示第一个命令执行的结果,比如dir|echo 123
或者ls|echo 123
,所以导致有人认为第一个命令没有被执行,可以用touch file|echo 111
来证实,执行命令后会创建文件123
。
Java命令执行
Java关键字:
1 2 3 4 5
| Runtime.exec Process ProcessBuilder.start ProcessImpl ...
|
在Java中命令执行最常用的有两个Runtime.exec
和ProcessBuilder.start
。
Runtime执行命令示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| public class RuntimeCmdInject { public static void main(String[] args) { RuntimeCmdInject runtimeCmdInject = new RuntimeCmdInject();
runtimeCmdInject.cmdNoFix_1("127.0.0.1&echo 123321"); }
private void cmdNoFix(String cmd) { try { Process exec = Runtime.getRuntime().exec(cmd); BufferedInputStream bufferedInputStream = new BufferedInputStream(exec.getInputStream()); byte[] bytes = new byte[1024]; int len; while ((len = bufferedInputStream.read(bytes)) != -1) { System.out.write(bytes, 0, len); } bufferedInputStream.close(); } catch (IOException e) { e.printStackTrace(); }
}
private void cmdNoFix_1(String ip) { try { Process exec = Runtime.getRuntime().exec(new String[]{"cmd", "/k", "ping " + ip}); BufferedInputStream bufferedInputStream = new BufferedInputStream(exec.getInputStream()); byte[] bytes = new byte[1024]; int len; while ((len = bufferedInputStream.read(bytes)) != -1) { System.out.write(bytes, 0, len); } bufferedInputStream.close(); } catch (IOException e) { e.printStackTrace(); }
}
private void cmdWithFix(String ip) { try { String[] blackChar = {"&", "|", ";"}; for (String s : blackChar) { if (ip.contains(s)) { return; } } String pattern = "(^\\d+(\\.\\d+){2}\\.\\d+$)|([a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\\.?)"; boolean ismatch = Pattern.matches(pattern, ip); if(!ismatch){ return; } Process exec = Runtime.getRuntime().exec(new String[]{"ping", ip}); BufferedInputStream bufferedInputStream = new BufferedInputStream(exec.getInputStream()); byte[] bytes = new byte[1024]; int len; while ((len = bufferedInputStream.read(bytes)) != -1) { System.out.write(bytes, 0, len); } bufferedInputStream.close(); } catch (IOException e) { e.printStackTrace(); }
} }
|
ProcessBuilder执行命令示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| public class ProcessCmdInject { public static void main(String[] args) { ProcessCmdInject processCmdInject = new ProcessCmdInject(); processCmdInject.cmdNoFix_1("127.0.0.1|echo 123"); }
private void cmdNoFix(String[] cmd) { try { Process process = new ProcessBuilder(cmd).start(); InputStream inputStream = process.getInputStream(); BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream); byte[] bytes = new byte[1024]; int len; while ((len = bufferedInputStream.read(bytes)) != -1) { System.out.write(bytes, 0, len); } bufferedInputStream.close();
} catch (IOException e) { e.printStackTrace(); } }
private void cmdNoFix_1(String ip) { try { Process process = new ProcessBuilder(new String[]{"cmd","/K", "ping " + ip}).start(); InputStream inputStream = process.getInputStream(); BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream); byte[] bytes = new byte[1024]; int len; while ((len = bufferedInputStream.read(bytes)) != -1) { System.out.write(bytes, 0, len); } bufferedInputStream.close();
} catch (IOException e) { e.printStackTrace(); } }
private void cmdWithFix(String ip) { try { String[] blackChar = {"&", "|", ";"}; for (String s : blackChar) { if (ip.contains(s)) { return; } } String pattern = "(^\\d+(\\.\\d+){2}\\.\\d+$)|([a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\\.?)"; boolean ismatch = Pattern.matches(pattern, ip); if(!ismatch){ return; } Process process = new ProcessBuilder(new String[]{"ping " + ip}).start(); InputStream inputStream = process.getInputStream(); BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream); byte[] bytes = new byte[1024]; int len; while ((len = bufferedInputStream.read(bytes)) != -1) { System.out.write(bytes, 0, len); } bufferedInputStream.close(); } catch (IOException e) { e.printStackTrace(); }
} }
|
:warning:需要注意:
一些单纯的拼接并不能造成我们预期的命令执行效果,可以参考大佬文章Java下奇怪的命令执行。如果不是以bin/bash
或者cmd.exe
这类支持特殊命令参数的命令开始,那么一般情况下不会造成严重的命令执行漏洞。
参考链接:
1 2 3
| https://blog.zeddyu.info/2019/01/17/%E5%91%BD%E4%BB%A4%E6%89%A7%E8%A1%8C/ http://www.lmxspace.com/2019/10/08/Java%E4%B8%8B%E5%A5%87%E6%80%AA%E7%9A%84%E5%91%BD%E4%BB%A4%E6%89%A7%E8%A1%8C/ https://xz.aliyun.com/t/7046
|