RCE大合集
无参RCE
无参rce,就是说在无法传入参数的情况下,仅仅依靠传入没有参数的函数套娃就可以达到命令执行的效果,这在ctf中也算是一个比较常见的考点,接下来就来详细总结总结它的利用姿势
1.getallheaders()
这个函数的作用是获取http
所有的头部信息,也就是headers
,然后我们可以用var_dump
把它打印出来,但这个有个限制条件就是必须在apache
的环境下可以使用,其它环境都是用不了的
可以看到,所有的头部信息都已经作为了一个数组打印了出来,在实际的运用中,我们肯定不需要这么多条,不然它到底执行哪一条呢?所以我们需要选择一条出来然后就执行它,这里就需要用到php
中操纵数组的函数了,这里常见的是利用end()
函数取出最后一位,这里的效果如下图所示,而且它只会以字符串的形式取出值而不会取出键,所以说键名随便取就行:
解释下, 键名就是:前面得东西
那我们把最前面的var_dump
改成eval
,不就可以执行phpinfo
了吗,换言之,就可以实现任意php代码的代码执行了,那在没有过滤的情况下执行命令也就轻而易举了,具体效果如下图所示:
2.get_defined_vars()
getallheaders()
是有局限性的,因为如果中间件不是apache
的话,它就用不了了,那我们就介绍一种更为普遍的方法get_defined_vars()
,这种方法其实和上面那种方法原理是差不多的:
他获取的不是headers 是几个全局变量
返回值是一个二维数组,要用函数将他转换为一维数组,用到的是current函数,这个函数的作用是返回数组中的当前单元,而它的默认是第一个单元,也就是我们GET方式传入的参数。
这里首先声明,
pos()
函数是current()
函数的别名,他们俩是完全一样的哈这个函数我们前面已经用的很多了,它的作用就是输出数组中当前元素的值,只输出值而忽略掉键,默认是数组中的第一个值,如果要移动可以用下列方法进行移动
我这个题的current好像被过滤了 就用pos了
就是这样子的
然后``反引号命令执行了
总结一下,这种方法和第一种方法几乎是一样的,就多了一步,就是利用current()
函数将二维数组转换为一维数组,如果大家还是不了解current()
函数的用法,可以接着往下看
3.session_id()
这种方法和前面的也差不太多,这种方法简单来说就是把恶意代码写到COOKIE
的PHPSESSID
中,然后利用session_id()
这个函数去读取它,返回一个字符串,然后我们就可以用eval
去直接执行了,这里有一点要注意的就是session_id()
要开启session
才能用,所以说要先session_start()
,这里我们先试着把PHPSESSID
的值取出来:
直接出来就是字符串,那就非常完美,我们就不用去做任何的转换了,但这里要注意的是,PHPSESSIID
中只能有A-Z a-z 0-9
,-
,所以说我们要先将恶意代码16进制编码以后再插入进去,而在php中,将16进制转换为字符串的函数为hex2bin
那我们就可以开始构造了,首先把PHPSESSID
的值替换成这个,然后在前面把var_dump
换成eval
就可以成功执行了,如图:
成功出现phpinfo
,稳稳当当,这种方法我认为是最好的一种方法,很容易理解,只是记得要将恶意代码先16进制编码一下哦
4.php函数直接读取文件
1.localeconv
这个函数其实之前我一直搞不懂它是干什么的,为什么在这里有用,但实践出真知,我们在测试代码中将localeconv()
的返回结果输出出来,这里很神奇的事就发生了,它返回的是一个二维数组,而它的第一位居然是一个点.
,那按照我们上面讲的,是可以利用current()
函数将这个点取出来的,但这个点有什么用呢?点代表的是当前目录!那就很好理解了,我们可以利用这个点完成遍历目录的操作!相当于就是linux
中的ls
2.scandir
这个函数很好理解,就是列出目录中的文件和目录
3.current(pos)
这里首先声明,pos()
函数是current()
函数的别名,他们俩是完全一样的哈
这个函数我们前面已经用的很多了,它的作用就是输出数组中当前元素的值,只输出值而忽略掉键,默认是数组中的第一个值,如果要移动可以用下列方法进行移动:
4.chdir()
这个函数是用来跳目录的,有时想读的文件不在当前目录下就用这个来切换,因为scandir()
会将这个目录下的文件和目录都列出来,那么利用操作数组的函数将内部指针移到我们想要的目录上然后直接用chdir
切就好了,如果要向上跳就要构造chdir('..')
5.array_reverse()
将整个数组倒过来,有的时候当我们想读的文件比较靠后时,就可以用这个函数把它倒过来,就可以少用几个next()
6.highlight_file()
打印输出或者返回 filename 文件中语法高亮版本的代码,相当于就是用来读取文件的
简单绕过cat,tac命令,绕过空格
<?php
$rce = $_GET['rce'];
if (isset($rce)) {
if (!preg_match("/cat|more|less|head|tac|tail|nl|od|vi|vim|sort|flag| |\;|[0-9]|\*|\`|\%|\>|\<|\'|\"/i", $rce)) {
system($rce);
}else {
echo "hhhhhhacker!!!"."\n";
}
} else {
highlight_file(__FILE__);
}
所被过滤的:
cat、more、less、head、tac、tail、nl、od、vi、vim、sort,空格字符,分号 ,0-9,特殊字符: ` % > < ‘ “
payload:
?rce=ls${IFS}/
?rce=paste${IFS}/fla?
小结:
paste命令在Linux系统中主要用于将多个文件按行合并在一起。它的主要功能和用法包括:
合并文件:基本用法是
paste file1 file2
,这会把file1和file2的内容合并显示,两文件相邻的行会并在一起。指定分隔符:可以用
-d
参数指定合并时的分隔符,例如paste -d ":" file1 file2
会使用冒号分隔。串行合并:
-s
参数可以将多个文件串行合并,一个接一个,不并排显示。从标准输入读取:可以用
-
参数从标准输入读取内容合并,例如paste - -
。输出到文件:可以通过重定向将合并结果输出到文件,例如
paste file1 file2 > merged.txt
。绕过过滤:在安全测试中,paste命令可以用来绕过对空格或分号的过滤,合并多个命令。
总结:paste的用途主要是合并文本文件,指定分隔符,可以串行合并或输出到文件。也可以从标准输入读取。在安全测试中可以用来构造绕过过滤的命令。
未完待续……