SV.EXEC.LOCAL
进程注入。本地参数。
将未检查的应用程序参数用于全部或部分由应用程序执行的操作系统命令时,将报告此错误。此检查器不同于其他 SV.EXEC 检查器,它将“本地”参数指定到应用程序,这需要攻击者能够修改运行 Java 应用程序的计算机上的设置。
此检查器适用的应用程序参数包括:命令行参数、环境变量或 Java 系统属性。
漏洞与风险
应用程序接受输入,用于充分选择要运行的程序,以及要使用哪些命令。应用程序只需将整个命令重定向至操作系统。
程序员并不打算让不受信任的各方访问命令,但他们可能没有考虑到一些恶意攻击者可提供输入的替代方法。
缓解与预防
考虑将设置存储在具有已知路径的属性文件中,而不是使用主要参数、系统属性或环境变量。用适当的权限保护属性文件。在已签名的 jar 中包含属性或使用校验和验证文件的完整性。
不要通过 Runtime.exec() 或 ProcessBuilder() 调用 shell。
以下是从 .properties 文件读取设置的示例:
Properties props =
getClass().getClassLoader().getResourceAsStream("config.properties");
String toolsHome = props.getProperty("tools.path");
漏洞代码示例 1
在此示例中,如果攻击者控制“TOOLS_PATH”环境变量,则可修改属性以指向危险的程序(位于“$TOOLS_PATH/bin/jmap”中)。
public static void generateHeapDump() {
Long processId = getProcessId();
String jmapPath = getJmapPath();
String[] dumpCommands = new String[] {jmapCommand,
"-dump:format=b,file=" + dumpPath,
processId.toString()};
try {
Runtime.getRuntime().exec(dumpCommands);
} catch (IOException e) {
logger.error("The heap dump could not be generated due to the following error: ", e);
}
}
private static String getJmapPath() {
String toolsPath = System.getenv("TOOLS_PATH");
if (toolsPath == null)
return null;
File binDirectory = new File(toolsPath, "bin");
File[] files = binDirectory.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.startsWith("jmap");
}
});
return ArrayUtils.isEmpty(files) ? null : files[0].getPath();
}
漏洞代码示例 2
此示例中的问题是程序不在 backuptype 系统属性中执行任何验证。通常情况下,Runtime.exec() 函数不会执行多个命令,但在此情况下程序首先运行 cmd.exe shell,以通过对 Runtime.exec() 的单个调用运行多个命令。调用 shell 之后,它将执行由两个和号 (&) 分隔的多个命令。如果攻击者传递“&& del c:\\dbms\\*.*”形式的字符串,则应用程序将执行此命令以及程序指定的其他命令。由于应用程序的性质,运行时需具有与数据库交互所必需的权限,这意味着无论攻击者注入何种命令,运行时都需要具有这些权限。
...
String btype = System.getProperty("backuptype");
String cmd = new String("cmd.exe /K \"
c:\\util\\rmanDB.bat "
+btype+
"&&c:\\utl\\cleanup.bat\"")
System.Runtime.getRuntime().exec(cmd);
...