Command Injection(命令注入)

Abstract

执行不可信赖资源中的命令,或在不可信赖的环境中执行命令,都会导致程序以攻击者的名义执行恶意命令。

Explanation

Command Injection 漏洞主要表现为以下两种形式:

- 攻击者能够篡改程序执行的命令: 攻击者直接控制了所执行的命令。

- 攻击者能够篡改命令的执行环境: 攻击者间接地控制了所执行的命令。

在这种情况下,我们着重关注第一种情况,即攻击者控制所执行命令的可能性。 这种形式的 Command Injection 漏洞在以下情况下发生:

  1. 数据从不可信赖的数据源进入应用程序。
  2. 数据被用作代表应用程序所执行命令的字符串,或字符串的一部分。
  3. 通过命令的执行,应用程序会授予攻击者一种原本不该拥有的特权或能力。

    例 1: 下面这段来自系统实用程序的代码根据系统属性 APPHOME 来决定其安装目录,然后根据指定目录的相对路径执行一个初始化脚本。
...
String home = System.getProperty("APPHOME");
String cmd = home + INITCMD;
java.lang.Runtime.getRuntime().exec(cmd);
...

例 1 中的代码使得攻击者可通过修改系统属性 APPHOME 而指向一个包含恶意版本 INITCMD 的其他路径,从而提高自己在应用程序中的权限,继而随心所欲地执行命令。 由于程序不会验证从环境中读取的值,所以如果攻击者能够控制系统属性 APPHOME 的值,他们就能欺骗应用程序去运行恶意代码从而取得系统控制权。例 2: 以下代码来自一个管理 Web 应用程序,该程序旨在允许用户通过使用围绕 rman 实用程序的批处理文件包启动 Oracle 数据库备份,然后运行 cleanup.bat 脚本删除一些临时文件。 脚本文件 rmanDB.bat 接受一个命令行参数,其中指明了需要执行的备份类型。 由于访问数据库受限,所以应用程序执行备份需要具有较高权限的用户。

...
String btype = request.getParameter("backuptype");
String cmd = new String("cmd.exe /K
\"c:\\util\\rmanDB.bat "+btype+"&&c:\\utl\\cleanup.bat\"")
System.Runtime.getRuntime().exec(cmd);
...

这里的问题是:程序没有对读取自用户的 backuptype 参数做任何验证。 通常情况下,一次调用Runtime.exec() 函数并不会执行多条命令,但是在本例中,程序首先运行了 cmd.exe 指令,进而在一次

调用 Runtime.exec() 后便可以运行多条命令了。 一旦调用了该 shell,它即会心甘情愿地执行用两个与号分隔的多条命令。 如果攻击者传递了一个形式为 "&& del c:\dbms\." 的字符串,那么应用程序将会在执行其他程序指定的命令时执行这些命令。 由于该应用程序的特性,运行该应用程序需要具备与数据库进行交互所需的权限,这就意味着攻击者注入的任何命令都将通过这些权限得以运行。 例 3: 以下代码来自一个 Web 应用程序。通过该应用程序,用户可以访问能够更新其系统密码的接口。 在特定的网络环境中更新密码时,其中的一个步骤就是在 /var/yp 目录中运行 make 命令,下面显示了此步骤的代码。

...
System.Runtime.getRuntime().exec("make");
...

这里的问题在于程序没有在它的构造中指定一个绝对路径,并且没能在执行Runtime.exec() 调用前清除它的环境变量。 如果攻击者能够修改 $PATH 变量,把它指向名为 make 恶意二进制代码,程序就会在其指定的环境下执行,然后加载该恶意二进制代码,而非原本期望的代码。 由于应用程序自身的特性,运行该应用程序需要具备执行系统操作所需的权限,这意味着攻击者会利用这些权限执行自己的 make,从而可能导致攻击者完全控制系统。 此种类来源于 Cigital Java Rulepack。 http://www.cigital.com/securitypack/

Recommendation

应当禁止用户直接控制由程序执行的命令。 在用户的输入会影响命令执行的情况下,应将用户输入限制为从预定的安全命令集合中进行选择。 如果输入中出现了恶意的内容,传递到命令执行函数的值将默认从安全命令集合中选择,或者程序将拒绝执行任何命令。 在需要将用户的输入用作程序命令中的参数时,由于合法的参数集合实在很大,或是难以跟踪,使得这个方法通常都不切实际。 开发者通常的做法是使用黑名单。 在输入之前,黑名单会有选择地拒绝或避免潜在的危险字符。 但是,任何一个定义不安全内容的列表都很可能是不完整的,并且会严重地依赖于执行命令的环境。 较好的方法是创建一份白名单,允许其中的字符出现在输入中,并且只接受完全由这些经认可的字符组成的输入。 攻击者可以通过修改程序运行命令的环境来间接控制这些命令的执行。 我们不应当完全信赖环境,还需采取预防措施,防止攻击者利用某些控制环境的手段进行攻击。 无论何时,只要有可能,都应由应用程序来控制命令,并使用绝对路径执行命令。 如果编译时尚不了解路径(如在跨平台应用程序中),应该在执行过程中利用可信赖的值构建一个绝对路径。 应对照一系列定义有效值的常量,仔细地检查从配置文件或者环境中读取的命令值和路径。 有时还可以执行其他检验,以检查这些来源是否已被恶意篡改。 例如,如果一个配置文件为可写,程序可能会拒绝运行。 如果能够预先得知有关要执行的二进制代码的信息,程序就会进行检测,以检验这个二进制代码的合法性。 如果一个二进制代码始终属于某个特定的用户,或者被指定了一组特定的访问权限,这些属性就会在执行二进制代码前通过程序进行检验。 尽管可能无法完全阻止强大的攻击者为了控制程序执行的命令而对系统进行的攻击,但只要程序执行外部命令,就务必使用最小授权原则: 不给予超过执行该命令所必需的权限。

Fortify Audit Workbench 笔记 Command Injection(命令注入)的更多相关文章

  1. Fortify Audit Workbench 笔记 SQL Injection SQL注入

    SQL Injection SQL注入 Abstract 通过不可信来源的输入构建动态 SQL 指令,攻击者就能够修改指令的含义或者执行任意 SQL 命令. Explanation SQL injec ...

  2. Fortify Audit Workbench 笔记索引

    Password Management: Password in Configuration File(明文存储密码) https://www.cnblogs.com/mahongbiao/p/124 ...

  3. DVWA靶场练习-Command Injection命令注入

    Command Injection 原理 攻击者通过构造恶意参数,破坏命令的语句结构,从而达到执行恶意命令的目的.

  4. command injection命令注入

    命令注入 是指程序中有调用系统命令的部分,例如输入ip,程序调用系统命令ping这个ip.如果在ip后面加一个&&.&.|.||命令拼接符号再跟上自己需要执行的系统命令 在pi ...

  5. Fortify Audit Workbench 笔记 Dynamic Code Evaluation: Code Injection

    Dynamic Code Evaluation: Code Injection Abstract 在运行时中解析用户控制的指令,会让攻击者有机会执行恶意代码. Explanation 许多现代编程语言 ...

  6. Fortify Audit Workbench 笔记 Cross-Site Scripting-Persistent

    Cross-Site Scripting: Persistent Abstract 向 Web 浏览器发送非法数据会导致浏览器执行恶意代码. Explanation Cross-Site Script ...

  7. Fortify Audit Workbench 笔记 Access Control: Database

    Abstract 如果没有适当的 access control,就会执行一个包含用户控制主键的 SQL 指令,从而允许攻击者访问未经授权的记录. Explanation Database access ...

  8. Fortify Audit Workbench 笔记 Header Manipulation

    Header Manipulation Abstract HTTP 响应头文件中包含未验证的数据会引发 cache-poisoning. cross-site scripting. cross-use ...

  9. Fortify Audit Workbench 笔记 File Disclosure: Spring 文件泄露(Spring框架)

    File Disclosure: Spring 文件泄露(Spring框架) Abstract 若通过用户输入构造服务器端重定向路径,攻击者便能够下载应用程序二进制码(包括应用程序的类或 jar 文件 ...

随机推荐

  1. Linux--容器命令

    ***执行:yum install lrzsz 然后sz和rz命令就可以使用了 1.查找文件的命令:find / -name [文件名:override.xml] eg:  find / -name ...

  2. 机器学习之KNN算法(分类)

    KNN算法是解决分类问题的最简单的算法.同时也是最常用的算法.KNN算法也可以称作k近邻算法,是指K个最近的数据集,属于监督学习算法. 开发流程: 1.加载数据,加载成特征矩阵X与目标向量Y. 2.给 ...

  3. ORA-04063: package body "DBSNMP.BSLN_INTERNAL" has errors

    ORA-04063: package body "DBSNMP.BSLN_INTERNAL" has errors 问题描述: 警告日志出现报错: Sun Jun 21 00:00 ...

  4. 在 Visual Studio 市场中发布项目扩展

    比较不错的开源项目中,尤其是类似于AbpNext这种级别的项目,我们都想要快速的尝试,如何提供快速给开发者提供模板是我们的一大难题.不过在VisualStudio中并没有这么难. 一.本地发布插件 就 ...

  5. JavaGUI练习 - 正交测试用例生成小工具

    正交表生成小工具 说明 小工具的适用对象主要是测试人员,他们日常工作中手动设计大量测试用例,工作繁杂甚至还存在覆盖不全面等问题. 为了提高他们的测试效率,该小工具可以通过输入一组多因素多水平的数据,然 ...

  6. 性能测试之jmeter逻辑控制种类详解一

    逻辑控制器介绍 Jmeter逻辑控制可以对元件的执行逻辑进行控制,除Once only Controller仅一次控制器以外,其他控制器都可以可以嵌套其他种类的控制器,下面是jmeter5.3支持的控 ...

  7. #pragma comment(linker,"/SECTION:shared,RWS")

    Windows在一个Win32程序的地址空间周围筑了一道墙.通常,一个程序的地址空间中的数据是私有的,对别的程序而言是不可见的.但是执行多个执行实体表示了程序的所有执行实体之间共享数据是毫无问题的.当 ...

  8. postman 进阶技巧

    cookie 清除缓存 code 生成接口自动化测试脚本 响应部分 pretty 响应以json或xml显示 raw 响应以文本显示 preview 以HTML网页行驶显示 断言 断言:用于判断接口请 ...

  9. JVM 专题十:运行时数据区(五)堆

    1. 核心概述 1.1 堆概述 一个进程对应一个jvm实例,一个运行时数据区,又包含多个线程,这些线程共享了方法区和堆,每个线程包含了程序计数器.本地方法栈和虚拟机栈. 一个jvm实例只存在一个堆内存 ...

  10. 关于Haskell计算斐波那契数列的思考

    背景 众所周知,Haskell语言是一门函数式编程语言.函数式编程语言的一大特点就是数值和对象都是不可变的,而这与经常需要对状态目前的值进行修改的动态规划算法似乎有些"格格不入", ...