如何理解php rce中无参数读文件

发布时间:2021-10-18 10:56:48 作者:柒染
来源:亿速云 阅读:178

如何理解php rce中无参数读文件,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

一、什么是无参数?

就是使用函数的时候不能带有参数。

可以是a()、a(b())或a(b(c())),但不能是a('b')或a('b','c'),不能带参数

所以我们要使用无参数的函数进行文件读取或者命令执行。

二、无参数文件读取

  1. 查看当前目录文件名

    通常,可以使用 print_r(scandir('.'))查看当前目录下所有文件,以数组的形式输出。

    如何理解php rce中无参数读文件

但是要怎么构造参数里这个点呢。

如何理解php rce中无参数读文件

利用通配符临时文件
<?php
if(isset($_GET['code'])){
  $code=$_GET['code'];
  if(strlen($code)>35){
      die("Long.");
  }
  if(preg_match("/[A-Za-z0-9_$]+/",$code)){
      die("NO.");
  }
  eval($code);
}else{
  highlight_file(__FILE__);
}

因为$不能使用了,所以我们无法构造PHP中的变量。

如何利用无字母、数字、$的系统命令来getshell?

  1. shell下可以利用.来执行任意脚本

  2. Linux文件名支持用glob通配符代替

.或者叫period,它的作用和source一样,就是用当前的shell执行一个文件中的命令。比如,当前运行的shell是bash,则. file的意思就是用bash执行file文件中的命令。

. file执行文件,是不需要file有x权限的。那么,如果目标服务器上有一个我们可控的文件,那不就可以利用.来执行它了吗?

这个文件也很好得到,我们可以发送一个上传文件的POST包,此时PHP会将我们上传的文件保存在临时文件夹下,默认的文件名是/tmp/phpXXXXXX,文件名最后6个字符是随机的大小写字母。

第二个难题接踵而至,执行. /tmp/phpXXXXXX,也是有字母的。此时就可以用到Linux下的glob通配符:

那么,/tmp/phpXXXXXX就可以表示为/*/?????????/???/?????????

能够匹配上/???/?????????这个通配符的文件有很多.

大部分同学对于通配符,可能知道的都只有*?.

其中,glob支持用[^x]的方法来构造“这个位置不是字符x”。那么,我们用这个姿势干掉一些干扰选项。

就跟正则表达式类似,glob支持利用[0-9]来表示一个范围。

所有文件名都是小写,只有PHP生成的临时文件包含大写字母。那么答案就呼之欲出了,我们只要找到一个可以表示“大写字母”的glob通配符,就能精准找到我们要执行的文件。

翻开ascii码表,可见大写字母位于@[之间:

如何理解php rce中无参数读文件

那么,我们可以利用[@-[]来表示大写字母:

构造 poc ,执行任意命令。

当然,php生成临时文件名是随机的,最后一个字符不一定是大写字母,不过多尝试几次也就行了。

最后,我传入的code为?c=. /???/????????[@-[],发送数据包如下:

#!/bin/sh

ls

如何理解php rce中无参数读文件

三、无参数命令执行(RCE)

我们可以使用无参数函数任意读文件,也可以执行命令。

  <?php
  if(';'===preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {    
      eval($_GET['code']);
  } else{
      show_source(__FILE__);
  }

我们传入一个参数,然后经过正则替换后剩余 分号 ;方可执行我们的payload.

代码非常清晰,首先

preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])

代码会将$_GET['code']中满足正则/\W+((?R)?)/的部分,替换为空,然后查看是否剩下的部分强等于;如果满足,则执行

eval($_GET['code']);

否则什么都不做。那么思路很明确,我们弄清楚正则即可进行RCE

[^\W]+\((?R)?\)

首先是[^\W]对于\W,其意思等价于[^A-Za-z0-9_]。那么我们知道,我们的input必须以此开头然后是括号匹配

\( ...... \)

括号中间为

(?R)?

意思为重复整个模式简单理解,我们可以输入以下类型

a(b(c()))

但我们不能加参数,否则将无法匹配,正则替换掉其他之后,甚于的不是只有分号,所以不强等于 左边的;

a(c,d)

所以正则看完,题目的意思非常明确了:我们只能input函数,但函数中不能使用参数,否则判断句右边经过替换,将不止剩余分号;。

既然传入的code值不能含有参数,那我们可不可以把参数放在别的地方,code用无参数函数来接收参数呢?这样就可以打破无参数函数的限制:

3.1 getenv()

查阅php手册,有非常多的超全局变量

$GLOBALS
$_SERVER
$_GET
$_POST
$_FILES
$_COOKIE
$_SESSION
$_REQUEST
$_ENV

我们可以使用$_ENV,对应函数为getenv()

首先想到headers,因为headers我们用户可控,于是在PHP手册中搜索:headers。

看完上述内容,你们掌握如何理解php rce中无参数读文件的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注亿速云行业资讯频道,感谢各位的阅读!

推荐阅读:
  1. php批量修改文本内容的方法
  2. 如何理解PHP CURL CURLOPT参数

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

php rce

上一篇:Dreamweaver如何定义模板批量制作网页

下一篇:使用golang基本数据结构与算法网页排名/PageRank实现随机游走

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》