命令执行基础知识

 

    1. 思维导图

 

    1. 命令执行含义

 

当应用需要调用一些外部程序去处理内容情况下,就会用到一些执行系统命令的函数,比如php中的system、exec、shell_exec、passthru、popen、popc_popen等,当用户调用这些函数时,将恶意系统命令注入到正常命令中,造成命令执行漏洞;

PHP可动态执行PHP代码的有eval,

jsp有Runtime、getruntime()、exec();

Asp/aspx有eval等

本质:程序设计违背了”数据与代码分离”的原则;

 

    1. 命令执行漏洞成因

成因

    1. 代码层过滤不严

一些商业应用需要执行命令,商业应用的一-些核心代码可能封装在二进制文件中,在web应用中通过system函数来调用之:eg:system("/bin/program --arg $arg");

    1. 系统漏洞造成的命令注入

bash破壳漏洞(CVE-2014-6271),如果我们能够控制执行的bash的环境变量就可以通过破壳漏洞来执行任意代码;

    1. 调用第三方组件存在代码执行漏洞

典型的就是WordPress中,可以选择使用lmageMagick这个常用的图片处理组件,对用户. 上传的图片进行处理(默认是lmageMagick库)造成命令执行。

另外JAVA中的命令执行漏洞(struts2/ElasticsearchGroovy等)很常见。

    1. 漏洞危害
    2. 继承权限,执行系统命名,读写文件
    3. 反弹shell
    4. 控制整个服务器

 

 

 

    1. 漏洞分类
    2. 命令直接注入执行漏洞

命令注入:应用程序直接使用了危险的可执行系统命令的函数,比如php的system 、exec函数等,并且这些函数的运行参数是用户可控的,若过滤不严格,就会增大命令执行漏洞的概率。命令本地包含执行漏洞。

eg:(CGI)系统命令注入执行漏洞示例,就比如去年很火的Bash漏洞,就属于这类漏洞,用户可直接更改HTTP头User-Agent的值,就可引发命令注入,如下图(命令执行结果将从myvps.org服务器上下载一个php文件到本地):

    1. 命令包含执行漏洞

命令本地/远程包含漏洞:应用程序直接包含或执行了用户可控的上传脚本文件或远程文件(URL引用文件),就会触发此漏洞。

(360安全卫士) 360安全卫士有个“360电脑专家”功能,可以聊天,在聊天窗口中输入如下图内容,就会触发本地包含漏洞。这个漏洞的原理是360会将聊天内容写入到文件中去,然后显示的时候去读取文件,执行了包含的命令。

 

    1. 命令反序列化执行漏洞

有些动态脚本语言,如php支持实例对象的序列化传输,然后服务端将实例对象反序列化出来并执行解析后实例的构造函数、析构函数或__wakeup()函数,若这些函数利用了用户可控的参数,则会触发命令/代码注入执行漏洞,原理和之前的直接注入一样。

若服务端代码文件中有个php文件的内容包含有类似如下图代码片段,就存在反序列化的漏洞。

 

 

    1. 命令动态变量执行漏洞

有些动态脚本语言,如php,支持变量或函数的动态定义,即运行时可通过参数名来动态组装变量、变量值或函数。若代码中包含有类似如图中类似代码片段,就会存在动态变量/函数的执行漏洞。

当用户在浏览器中输入:

 

127.0.0.1/dynamic.php?dyn_func=system&argument=ipconfig,就相当于执行了系统命令ipconfig,如下图

    1. 漏洞利用

常见的漏洞利用函数

System:system函数可以用来执行一个外部的应用程序并将相应的执行结果输出

 

Exec:exec函数可以用来执行一个外部的应用程序,

 

Passthru:passthru函数可以用来执行一个UNIX系统命令并显示原始的输出,当UNIX系统

命令的输出是二进制的数据,并且需要直接返回值给浏览器时,需要使用passthru函数来替

代system与exec函数。

 

Shell_exec:执行shell命令并返回输出的字符串

 

``运算符:与shell_exec功能相同,执行shell命令并返回输出的字符串。

 

Eval函数会将参数字符串作为PHP程序代码来执行,用户可以将PHP代码保存成字符串的形

式,然后传递给eval函数执行。

<?php @eval($_POST['pass']);?>

 

典型漏洞代码

<?php

$cmd=$_GET["name"];

echo shell_exec($cmd);

?>

127.0.0.1/cmd_eval.php?name=netstat%20-ano http://127.0.0.1/cmd_eval.php?name=ipconfig

 

 

<?php

system($_GET['cmd']);

?>

127.0.0.1/1.php?cmd=id

 

 

preg_replace() 函数是用来执行一个正则表达式的搜索和替换的。PHP 4.0 开始支持这个函数。

upreg_replace 的语法

mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject);函数搜索 subject 中匹配 pattern 的部分, 以 replacement 进行替换。

pattern要搜索的内容,可以使用一些正则表达式修饰符。

e (PREG_REPLACE_EVAL)

preg_replace() 在进行了对替换字符串的 后向引用替换之后, 将替换后的字符串作为php 代码执行(eval 函数方式)

<?php

$string = 'hello hack';

  $pattern = '/hack/e';

$replacement = $_GET["name"];

  echo preg_replace($pattern, $replacement, $string);

?>

127.0.0.1/1.php??name=tom

127.0.0.1/1.php??name=phpinfo()

 

 

 

 

过滤绕过

&、||、|符号同样也可以作为命令连接符使用。

例如:

net user || ipconfig

net user | ipconfig

net user & ipconfig

如果web应用程序没有过滤好输入,就变得相当危险,在权限足够大的情况下服务器可被攻击者直接攻陷

linux:;、| 、 || 代替

; —> 前后都执行

| —> 执行后面的

| | —> 当前面执行出错时,执行后面

windows & 、 &&

& —> 前面为假执行后面的

& & —> 前面为假直接出错,不执行后面的

 

 

windows支持:

| 直接执行后面的语句 ping 127.0.0.1|whoami

|| 前面出错执行后面的 ,前面为假 ping 2 || whoami

& 前面的语句为假则直接执行后面的,前面可真可假,都会执行后面的 ping 127.0.0.1&whoami

&&前面的语句为假则直接出错,后面的也不执行,前面只能为真 ping 127.0.0.1&&whoami

 

Linux支持:

; 前面的执行完执行后面的 ping 127.0.0.1;whoami

| 管道符,显示后面的执行结果 ping 127.0.0.1|whoami

|| 当前面的执行出错时执行后面的 ping 1||whoami

& 前面的语句为假则直接执行后面的,前面可真可假 ping 127.0.0.1&whoami

&&前面的语句为假则直接出错,后面的也不执行,前面只能为真 ping 127.0.0.1&&whoami

 

 

    1. 修复方案

PHP内置的两个函数可以有效防止命令执行:

1.escapeshellarg() 将给字符串增加一个单引号并且能引用或者转码任何已经存在的单引号,这样以确保能够直接将一个字符串传入 shell 函数,并且还是确保安全的。对于用户输入的部分参数就应该使用这个函数。

2. escapeshellcmd() 对字符串中可能会欺骗 shell 命令执行任意命令的字符进行转义。此函数保证用户输入的数据在传送到 exec() 或 system() 函数,或者 执行操作符 之前进行转义。

3.php中禁止disable_functions(禁用一些危险函数)

4.参数值尽量使用引用号包裹,并在拼接前调用addslashes进行转义

5.   能使用脚本解决的工作,不要利用其他程序处理。尽量少用执行命令的函数,并在disable_functions 中禁用

6.   对于可控点是程序参数的情况,使用 escapeshellcmd 函数进行过滤 //

escapeshellcmd() 除去字符串中的特殊符号

 

猜你喜欢

转载自blog.csdn.net/u012991692/article/details/82953222