java代码审计-命令执行漏洞

admin 2024年11月13日23:15:44评论25 views字数 3620阅读12分4秒阅读模式

0x01 前言

在Java中可用于执行系统命令常见的方式有两种,API为:java.lang.Runtimejava.lang.ProcessBuilder

0x02 java.lang.Runtime

@GetMapping("/runtime/exec")
public String CommandExec(String cmd) {
Runtime run = Runtime.getRuntime(); //Runtime.getRuntime.exec
StringBuilder sb = new StringBuilder(); //ProcessBuilder.start()

try {
Process p = run.exec(cmd);
//只是调用了对应进程没有回显,需要从流中读取
BufferedInputStream in = new BufferedInputStream(p.getInputStream());
BufferedReader inBr = new BufferedReader(new InputStreamReader(in));
String tmpStr;

while ((tmpStr = inBr.readLine()) != null) {
sb.append(tmpStr);
}

if (p.waitFor() != 0) {
if (p.exitValue() == 1)
return "Command exec failed!!";
}

inBr.close();
in.close();
} catch (Exception e) {
return e.toString();
}
return sb.toString();
}

最基础的Runtime.getRuntime().exec(cmd),直接传入命令即可执行
java代码审计-命令执行漏洞

0x03 java.lang.ProcessBuilder

1. 直接传入参数导致命令执行

 @GetMapping("/ProcessBuilder")
public String processBuilder(String cmd) {

StringBuilder sb = new StringBuilder();

try {
// String[] arrCmd = {"/bin/sh", "-c", cmd}; //linux
String[] arrCmd = {cmd}; //windows,windows下无需指定
ProcessBuilder processBuilder = new ProcessBuilder(arrCmd);
Process p = processBuilder.start();
BufferedInputStream in = new BufferedInputStream(p.getInputStream());
BufferedReader inBr = new BufferedReader(new InputStreamReader(in));
String tmpStr;

while ((tmpStr = inBr.readLine()) != null) {
sb.append(tmpStr);
}
} catch (Exception e) {
return e.toString();
}

return sb.toString();
}

同样也是直接执行命令,不同的是使用的是ProcessBuilder来执行命令。ProcessBuilder传入参数为列表,第一个参数为可执行命令程序,后面的参数为执行的命令程序的参数
java代码审计-命令执行漏洞

2. 传入参数拼接导致命令执行

 @GetMapping("/codeinject")
public String codeInject(String filepath) throws IOException {

String[] cmdList = new String[]{"sh", "-c", "ls -la " + filepath};
//String[] cmdList = new String[]{"cmd.exe", "-c", "dir " + filepath};
ProcessBuilder builder = new ProcessBuilder(cmdList);
builder.redirectErrorStream(true);
Process process = builder.start();
return WebUtils.convertStreamToString(process.getInputStream());
}

获取一个参数filepath,然后通过ProcessBuilder将数组cmdList中 的字符串拼接起来执行命令,由于没有对输入filepath进行过滤,原本用作查看目录下文件的一个功能就会被执行恶意命令。通过Java执行系统命令,与cmd中或者终端上一样执行shell命令,最典型的用法就是使用Runtime.getRuntime().exec(command)new ProcessBuilder(cmdArray).start()
拼接后paylaod:http://localhost/codeinject?filepath=/tmp;%20id
java代码审计-命令执行漏洞

3. Host头未过滤命令执行

    @GetMapping("/codeinject/host")
public String codeInjectHost(HttpServletRequest request) throws IOException {

String host = request.getHeader("host");
logger.info(host);
String[] cmdList = new String[]{"sh", "-c", "curl " + host};
ProcessBuilder builder = new ProcessBuilder(cmdList);
builder.redirectErrorStream(true);
Process process = builder.start();
return WebUtils.convertStreamToString(process.getInputStream());
}

代码中在header中的host中设置参数且未过滤拼接后传入ProcessBuilder导致命令执行
payload:Host: 192.168.1.4;id && pwd
java代码审计-命令执行漏洞
修复方式:
利用SecurityUtil.cmdFilter来对传入的参数进行过滤,严格限制用户输入只能包含a-zA-Z0-9_-.字符

   public static String cmdFilter(String input) {
if (!FILTER_PATTERN.matcher(input).matches()) {
return null;
}

return input;
}

0x04 其它方式

ScriptEngineManager

    @GetMapping("/jscmd")
public void jsEngine(String jsurl) throws Exception{
// js nashorn javascript ecmascript
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);//启动javascript引擎
String cmd = String.format("load("%s")", jsurl);
engine.eval(cmd, bindings);
}

yml

    @GetMapping("/vuln/yarm")
public void yarm(String content) {
Yaml y = new Yaml();
y.load(content);
}

groovy

 @GetMapping("groovy")
public void groovyshell(String content) {
GroovyShell groovyShell = new GroovyShell();
groovyShell.evaluate(content);
}

0x05 总结

注意:java的Runtime.getRuntime.exec和ProcessBuilder.start,都是直接启动传入参数对应的进程,如果只是命令执行的部分参数可控,想在java中通过;、|、&等实现命令注入是行不通的, 例如这样传入id && whoami命令是无法执行的
存在问题的关键词:

Runtime.getRuntime().exec()、new ProcessBuilder().start()、cmd
ScriptEngineManager、Yaml、GroovyShell
原文地址:https://www.cnblogs.com/Ne2o1/p/17179379.html
java代码审计-命令执行漏洞

原文始发于微信公众号(猪猪谈安全):java代码审计-命令执行漏洞

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年11月13日23:15:44
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   java代码审计-命令执行漏洞https://cn-sec.com/archives/1644391.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息