奇奇怪怪的问题

奇奇怪怪的问题
FLYFISHeval 和system的纠纷
问题:
系统执行语句eval($cmd)时
当输入$cmd=system(cat flag.php)无法执行 ,输入$cmd=system("cat flag.php")正常执行
系统执行语句system($cmd)时
当输入$cmd=cat flag.php正常执行,输入$cmd="cat flag.php"无法执行
原因:
根本区别:eval() vs system()
eval():要求参数是合法的PHP代码字符串。
system():要求参数是合法的Shell命令字符串。
eval()
- 执行的是 PHP 代码
- PHP 解析逻辑
cat和flag.php会被 PHP 视为 常量(未定义则报错)。system(cat flag.php)会被解析为system('cat', 'flag.php'),导致参数数量错误。- 输入
$cmd=system(cat flag.php)失败原因:eval()会将字符串作为PHP代码执行。此时参数cat flag.php未用引号包裹,PHP会尝试将其解析为常量。- 若未定义名为
cat或flag.php的常量,PHP会将其隐式转换为字符串(触发Notice级错误),但可能因错误配置导致执行中断。 - 等效代码:
eval('system(cat flag.php)')→ 语法不合法。
- 输入
$cmd=system("cat flag.php")成功原因:- 参数
"cat flag.php"是合法的字符串,符合PHP语法。 - 等效代码:
eval('system("cat flag.php")')→ 直接执行系统命令。
- 参数
system()
- 执行的是 Shell 命令
- Shell 解析逻辑
- 按空格分割命令和参数:
cat是命令,flag.php是参数。 - 输入
$cmd=cat flag.php执行/bin/cat flag.php,成功输出文件内容。 - 输入
$cmd=cat flag.php成功原因:system()直接将字符串参数传递给系统Shell。- 等效命令:
sh -c "cat flag.php"→ 正常执行cat命令。
- 输入
$cmd="cat flag.php"失败原因:- 参数
"cat flag.php"被包裹在双引号中,Shell会尝试将其视为完整命令名(包含空格)。 - 等效命令:
sh -c "\"cat flag.php\""→ 寻找名为cat flag.php的命令(不存在)。
- 参数
- 按空格分割命令和参数:
没搞懂
算了,先记住吧。(好像又懂了,见下)
1 | 执行eval()如果要输入system(),system()的括号里面要加''或者"" 例如$cmd=system("cat flag.php") |
目前理解是eval()函数传入的命令要经过PHP解析(解析会将传入system()括号中命令的'' ""引号去除掉)之后再传递给shell,而system()直接传递给shell,所以不需要引号包裹括号里面的内容
结合场景的深度分析
场景一:eval($cmd)中的system()
输入
system(cat flag.php):eval()会将$cmd作为PHP代码解析。在PHP语法中,
1
system(cat flag.php)
会被解析为:
1
system(constant('cat'), constant('flag.php'));
若未定义常量
cat和flag.php,PHP会将其视为未定义常量,并抛出一个Notice错误(但可能继续执行,将cat和flag.php当作字符串处理)。最终可能得到一个语法错误(如参数数量不匹配),导致执行失败。
输入
system("cat flag.php"):- 字符串
"cat flag.php"在PHP中是合法参数。 - 等效于直接调用系统命令
cat flag.php,因此成功。
- 字符串
场景二:直接调用system($cmd)
- 输入
cat flag.php:system()直接将cat flag.php传递给Shell。- Shell会按空格分割参数,执行
cat命令并传入flag.php作为参数,因此成功。
- 输入
"cat flag.php":- Shell会将整个字符串
"cat flag.php"视为一个命令名(包含空格),尝试寻找名为cat flag.php的可执行文件(显然不存在),因此失败。
- Shell会将整个字符串
关键区别总结
| 场景 | 执行环境 | 输入要求 | 底层逻辑 |
|---|---|---|---|
eval($cmd) |
PHP解释器 | 必须是合法PHP代码 | 解析为PHP代码执行 |
system($cmd) |
操作系统Shell | 必须是合法Shell命令 | 将字符串原样传递给Shell解析 |
类比验证
假设在PHP中直接写以下代码:
1 | // 场景一(eval环境) |














