RCE(Remote Code Execute)远程代码执行

原理

因为需求设计,后台有时候需要把用户的输入作为代码的一部分进行执行,也就造成了远程代码执行漏洞。不管是使用了代码执行的函数,还是使用了不安全的反序列化等等。

通过代码注入或远程代码执行(RCE),攻击者可以通过注入攻击执行恶意代码、向网站写webshell、控制整个网站甚至服务器。其实际危害性取决于服务器端解释器的限制(例如,PHP,Python等)。在某些情况下,攻击者可能能够从代码注入升级为命令注入。

通常,代码注入容易发生在应用程序执行却不经过验证代码的情况下。

产生条件(敏感函数)

1
2
3
4
5
6
eval()    //把字符串作为PHP代码执行
assert() //检查一个断言是否为 FALSE,可用来执行代码
preg_replace() //执行一个正则表达式的搜索和替换
call_user_func()//把第一个参数作为回调函数调用
call_user_func_array()//调用回调函数,并把一个数组参数作为回调函数的参数
array_map() //为数组的每个元素应用回调函数

动态函数$a($b)

由于PHP 的特性原因,PHP 的函数支持直接由拼接的方式调用,这直接导致了PHP 在安全上的控制有加大了难度。不少知名程序中也用到了动态函数的写法,这种写法跟使用call_user_func()的初衷一样,用来更加方便地调用函数,但是一旦过滤不严格就会造成代码执行漏洞。

举例:不调用eval()

1
2
3
4
5
6
7
8
9
10
<?php
if(isset($_GET['a'])){
$a=$_GET['a'];
$b=$_GET['b'];
$a($b);
}else{
echo "
?a=assert&amp;b=phpinfo()
";
}

危害

执行脚本代码如PHP、Java、Python脚本

检测

检测方法

白盒——代码审计

在白盒测试的过程中,我们可以重点关注危险函数出现的位置(上面所总结的那些)。当存在我们能控制的数据,并且能构造出注入攻击的地方,那么漏洞就是存在的。这类测试可以利用自动化工具来进行。

黑盒

  1. 漏洞扫描工具
  2. 公开漏洞
  3. 手工看参数值及功能点,比如提交参数值中出现了echo等PHP函数

检测位置

无

利用

利用过程

此处以php为例,其它语言也存在这类利用。

(1) preg_replace()函数:

1
mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )

当$pattern处存在e修饰符时,$replacement 会被当做php代码执行。

(2)mixed call_user_func( callable $callbank [ , mixed $parameter [ , mixed $…):

第一个参数为回调函数,第二个参数是回调函数的参数

img

img

(3)eval()和assert():

当assert()的参数为字符串时 可执行PHP代码

【区分】:

1
2
3
4
eval(" phpinfo(); ");【√】 
eval(" phpinfo() ");【X】
assert(" phpinfo(); ");【√】
assert(" phpinfo() ");【√】

RCE(Remote Command Execute)远程命令执行

原理

远程系统命令执行(操作系统命令注入或简称命令注入)是一种注入漏洞。攻击者注入的payload将作为操作系统命令执行。仅当Web应用程序代码包含操作系统调用并且调用中使用了用户输入时,才可能进行OS命令注入攻击。它们不是特定于语言的,命令注入漏洞可能会出现在所有让你调用系统外壳命令的语言中:C,Java,PHP,Perl,Ruby,Python等。

操作系统使用Web服务器的特权执行注入的任意命令。因此,命令注入漏洞本身不会导致整个系统受损。但是,攻击者可能能够使用特权升级和其他漏洞来获得更多访问权限。

产生条件(敏感函数)

1
2
3
4
5
6
7
system()        //执行外部程序,并且显示输出
exec() //执行一个外部程序
shell_exec() //通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回
passthru() //执行外部程序并且显示原始输出
pcntl_exec() //在当前进程空间执行指定程序
popen() //打开进程文件指针
proc_open() //执行一个命令,并且打开用来输入/输出的文件指针

危害

执行系统命令如Windows、Linux命令

检测

检测方法

白盒——代码审计

在白盒测试的过程中,我们可以重点关注危险函数出现的位置(上面所总结的那些)。当存在我们能控制的数据,并且能构造出注入攻击的地方,那么漏洞就是存在的。这类测试可以利用自动化工具来进行。

黑盒

  1. 漏洞扫描工具
  2. 公开漏洞
  3. 手工看参数值及功能点,比如提交参数值中出现了echo等PHP函数

检测位置

无

利用

利用过程

命令执行(注入)常见可控位置情况有下面几种:

  • system("$arg"); //可控点直接是待执行的程序

如果我们能直接控制$arg,那么就能执行执行任意命令了。

  • system("/bin/prog $arg"); //可控点是传入程序的整个参数

我们能够控制的点是程序的整个参数,我们可以直接用&& || 或 | 等等,利用与、或、管道命令来执行其他命令(可以涉及到很多linux命令行技巧)。

  • system("/bin/prog -p $arg"); //可控点是传入程序的某个参数的值(无引号包裹)

我们控制的点是一个参数,我们也同样可以利用与、或、管道来执行其他命令,情境与二无异。

  • system("/bin/prog --p=\"$arg\"");//可控点是传入程序的某个参数的值(有双引号包裹)

这种情况压力大一点,有双引号包裹。如果引号没有被转义,我们可以先闭合引号,成为第三种情况后按照第三种情况来利用,如果引号被转义(addslashes),我们也不必着急。linux shell 环境下双引号中间的变量也是可以被解析的,我们可以在双引号内利用反引号执行任意命令 id

  • system("/bin/prog --p='$arg'"); //可控点是传入程序的某个参数的值(有单引号包裹)

这是最困难的一种情况,因为单引号内只是一个字符串,我们要先闭合单引号才可以执行命令。如:system(“/bin/prog –p=’aaa’ | id”)

在漏洞检测中,除了有回显的命令注入(比如执行dir 命令或者cat 读取系统文件);还可以使用盲打的方式,比如curl远程机器的某个目录(看access.log),或者通过dns解析的方式获取到漏洞机器发出的请求。

当我们确定了OS命令注入漏洞后,通常可以执行一些初始命令来获取有关受到破坏的系统的信息。以下是在Linux和Windows平台上常用的一些命令的摘要:

命令目的 linux windows
当前用户名 whoami whoami
操作系统 uname -a ver
网络配置 ifconfig ipconfig /all
网络连接 netstat -an netstat -an
运行进程 ps -ef tasklist
命令分隔符的使用

在Linux上, ; 可以用 |、|| 代替

1
2
3
4
5
6
7
;前面的执行完执行后面的

|是管道符,显示后面的执行结果

||当前面的执行出错时执行后面的

可用 %0A和 \n 换行执行命令

在Windows上,不能用 ; 可以用&、&&、|、||代替

1
2
3
4
5
6
7
&前面的语句为假则直接执行后面的

&&前面的语句为假则直接出错,后面的也不执行

|直接执行后面的语句

||前面出错执行后面的

PHP 支持一个执行运算符:反引号(“) PHP 将尝试将反引号中的内容作为 shell 命令来执行,并将其输出信息返回

1
<?php echo `whoami`;?>

效果与函数 shell_exec() 相同,都是以字符串的形式返回一个命令的执行结果,可以保存到变量中

RCE防御与安全修复

  • WAF产品

  • 变量过滤或固定:变量过滤即对提交变量内容进行过滤,变量固定即固定允许提交的变量值,后者更加实用

  • 敏感函数禁用

站内搜索

没有找到内容!