eval与assert一句话木马分析
严正声明:本文仅限于技术讨论,严禁用于其他用途。
文章目录
前言
实验环境
服务器环境搭建以及管理工具:PHPstudy 8.1.1.3 版本
数据库: MySQL 5.7.26版本
中间件:Nginx1.15.11版本
PHP版本:5.5.9
一、eval定义和用法
-
eval() 函数把字符串按照 PHP 代码来计算(计算=执行)。
-
该字符串必须是合法的 PHP 代码,且必须以分号结尾。
-
如果没有在代码字符串中调用 return 语句,则返回 NULL。如果代码中存在解析错误,则 eval() 函数返回 false
-
返回语句会立即终止对字符串的计算。
注释:该函数对于在数据库文本字段中供日后计算而进行的代码存储很有用
二、assert的定义与用法
- assert()功能是判断一个表达式是否成立,返回true or false,重点是函数会执行此表达式。如果表达式为函数如assert(“echo(1)”),则会输出1,而如果assert(“echo 1;”)则不会有输出。
- assert把整个字符串参数当php代码执行
- assert在php中被认为是一个函数
三、eval与assert的相同点
- 二者都可以执行PHP语句。(eval规范更加严格一些,必须符合PHP代码要求。而assert则没有那么严格,执行PHP表达式即可。并不是对assert无计可施,可以采用assert_option()来进行对assert的控制)但是在生产环境强烈建议不使用assert函数(哪怕对其限制,也并不安全)。
- 都常被用来写一句话木马
四、eval与assert的不同点
- eval是一个语言构造器(是PHP自身的语言结构)而不是一个函数,不能被 可变函数 调用;assert在php中被认为是一个函数,能被可变函数调用。
- eval规范更加严格一些,必须符合PHP代码要求,assert则没有那么严格,执行PHP表达式即可
问1:什么是可变函数?
- PHP支持变量函数:通过变量保存一个函数的名字,然后在变量后跟上一个小括号就能调用。变量函数可以用来编写webshell绕过。
【示例】下面使用可变函数来调用不同的函数,并输出不同的语句。
<?php
function website(){
echo 'C语言中文网<br>';
}
function url($str = ''){
echo $str.'<br>';
}
function title($string){
echo $string;
}
$funcname = 'website';
$funcname();
$funcname = 'url';
$funcname('http://c.biancheng.net/php/');
$funcname = 'title';
$string = 'PHP 教程';
$funcname($string);
?>
运行结果如下:
C语言中文网
http://c.biancheng.net/php/
PHP 教程
可变函数参考文章:PHP可变函数 (biancheng.net)
问2:为什么eval不能被可变函数调用?
- eval 属于PHP语法构造的一部分,并不是一个函数,所以不能通过 变量函数 的形式来调用(虽然她确实像极了函数原型),这样的语法构造还包括:echo,print,unset(),isset(),empty(),include,require等。换句话说就是echo,
print
,unset(),isset(),empty(),include,require等语言结构不能被可变函数调用。
以代码为例:
案例一:
- print 和 print_r 在PHP中都起打印语句的作用,
print
属于不能被可变函数调用的那一类,print_r
属于能被可变函数调用的那一类。
$a = 'print';
$a('print 不能被可变函数调用 <br>');