java代码审计-命令执行
0x01 漏洞挖掘
String cmd = request.getParameter("cmd");
Runtime runtime = Runtime.getRuntime(); //Runtime.getRuntime.exec
ProcessBuilder processBuilder = new ProcessBuilder(cmd); //ProcessBuilder.start()
String result = "";
try {
//Process process = runtime.exec(cmd);
Process process = processBuilder.start();
//只是调用了对应进程没有回显,需要从流中读取
BufferedInputStream bis = new BufferedInputStream(process.getInputStream());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(bis));
String line = "";
while (null != (line = bufferedReader.readLine())) {
result += line + "\n";
}
if (process.waitFor() != 0) {
if (process.exitValue() == 1)
response.getWriter().println("command exec failed");
}
bufferedInputStream.close();
bufferedReader.close();
} catch (Exception e) {
response.getWriter().println("error");
return;
}
response.getWriter().println(result);
java的Runtime.getRuntime.exec
和ProcessBuilder.start
,都是直接启动传入参数对应的进程。以curl为例,php的system
会启动系统shell,然后通过shell来启动curl进程,这个过程中,如果传入的命令带有shell能解析的语法,就会首先解析。
所以,如果只是命令执行的部分参数可控,想在java中通过;、|、&
等实现命令注入,是行不通的。当然不排除程序本身存在漏洞,只需传入参数即可造成漏洞。
如果命令以字符串形式传入Runtime.getRuntime.exec
,程序会将传入的命令用空格来拆分。
Process process = runtime.exec("ping -c 1 " + ip);
//这种传入 127.0.0.1 | id,是无法正常执行的
如果执行命令使用的是ProcessBuilder.start
,那么只能执行无参数的命令。因为ProcessBuilder
不支持以字符串形式传入命令,只能拆分成List或者数组的形式传入,才能执行。
如果参数完全可控,可自行启动shell,然后在执行命令。
Process process = runtime.exec("sh -c whoami");
0x02 漏洞防御
命令执行漏洞的防御需要结合实际场景,没有很通用的防御手段。
- 尽量避免调用shell来执行命令。
- 如果是拼接参数来执行命令,对参数进行严格过滤,比如只允许字母数字。
0x03 参考资料
https://b1ngz.github.io/java-os-command-injection-note/
https://blog.csdn.net/u013256816/article/details/54603910
https://mp.weixin.qq.com/s/zCe_O37rdRqgN-Yvlq1FDg
点击关注,共同学习!
安全狗的自我修养
原文地址:http://www.cnblogs.com/haidragon/p/16885375.html
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,请务用于商业用途!
3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员!
8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载
声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性