浅析Java执行外部命令的几个要点(4)——支持shell的"|","`","*","?"等特殊符号

转贴请注明出处:http://blog.csdn.com/froole

在上一章已经验证了CommandExec可以很好的支持超时功能,通过它可以更方便的执行外部命令。
但是,这里还有一点需要注意——那就是shell(DOS)中的特殊符号。
因为用Java作为后台程序的系统,多运行于Unix/Linux,以下的介绍将基于如何shell来展开讨论。

假设,系统需要通过提取某个命令的标准输出,来进行某项处理。例如,搜索/路径下的xml文件并对结果处理,如下:
find / -name "*.xml" -type f | xargs java 相应程序
如果按照常规的方式,将以上的几个字串直接传递给Runtime.exec的参数,通过CommandExec的实现方法如下:
  1. CommandExec exec = new CommandExec();
  2. Process process = exec.exec(new String(){"find""/""-name""/"*.xml/"""-type""f""|""xargs""java""相应程序"});

但是,实际结果将事与愿违,因为,在解析"|"的时候是以特殊符号来解析,而JVM将把"|"作为普通的字符串来处理。
在通常的处理中,这种功能可以屏蔽命令溢出的漏洞,但是在特殊需求的时候,就不方便了。
当然,在特殊需求下也有解决方法,可以如下执行以下命令:
  1. CommandExec exec = new CommandExec();
  2. Process process = exec.exec(new String(){"shell""-c""/"find / -name '*.xml' -type f | xargs java 相应程序/""});

也就是把要执行的命令作为shell的一个参数让Runtime.exec执行,为shell命令加上-c参数就可以正常执行目标命令了。

细心的读者已经看出,用上面的方法,有一个缺点就是,如果动态生成命令,很容易发生命令溢出的漏洞。
这里有一个解决方法,就是设定一个前提,被执行命令,文字串都必须以单引号包含,那样就比较容易escape了。
escape的方法可以如下定义,并添加到CommandExec当中。
  1.     /**
  2.      *
  3.      * 对shell字串进行escape
  4.      *
  5.      * @param s 对象字串
  6.      * @return 返回escape之后的shell字串
  7.      */
  8.     public static String escapeShellSpecialCharacters(String s) {
  9.         StringBuilder sb = new StringBuilder(s.length() + 128);
  10.         sb.append('/'');
  11.         for (int i = 0; s != null && i < s.length(); i++) {
  12.             char c = s.charAt(i);
  13.             if (c == '/'') {
  14.                 sb.append('//');
  15.             }
  16.             sb.append(c);
  17.         }
  18.         sb.append('/'');
  19.         return sb.toString();
  20.     }
JVM执行外部命令功能的漏洞
到此为止,在Java中执行外部命令的方法以及注意点基本叙述完毕。但是,最后还有一点必须注意的就是JVM本身存在的一个漏洞。

这个漏洞的现象是,当被执行的外部命令,标准输出的量比较大的时候,程序会无故锁死。
特别是在JDK1.3版本尤为明显,在新版本中仍旧存在此漏洞。
不过,通过外部命令的执行方式,可以避免此漏洞的出现——通过重定向避免标准输出。
CommandExec的执行方法如下:
  1. CommandExec exec = new CommandExec();
  2. Process process = exec.exec(new String(){"shell""-c""/"find / -name '*.xml' -type f | xargs java 相应程序 > /dev/null/""});

到此结束,欢迎拍砖!

相关:
-浅析Java执行外部命令的几个要点(1)
-浅析Java执行外部命令的几个要点(2)
-浅析Java执行外部命令的几个要点(3)
-浅析Java执行外部命令的几个要点(4)

<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
转贴请注明出处:http://blog.csdn.net/froole
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章