[HUBUCTF 2022 新生赛]checkin

true与非零非NULL变量比较

布尔类型True与非零非NULL变量比较都会是True

本题flag.php会将$data_unserialize 之后的变量给替换掉,导致无法比较成功,主要考察了一个特性,布尔类型True与非零非NULL变量比较都会是True。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
show_source(__FILE__);
$username = "this_is_secret";
$password = "this_is_not_known_to_you";
include("flag.php");//here I changed those two
$info = isset($_GET['info'])? $_GET['info']: "" ;
$data_unserialize = unserialize($info);
if ($data_unserialize['username']==$username&&$data_unserialize['password']==$password){
echo $flag;
}else{
echo "username or password error!";

}

?>

[SWPUCTF 2022 新生赛]ez_ez_unserialize

在做一道通过反序列化后动态调用函数的题目时,最后获取flag使用assert和phpinfo() 构成的命令可以执行 但eval和phpinfo()无法执行

区分 evalassert的区别

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

什么是可变函数?

可变函数即变量名加括号,PHP系统会尝试解析成函数,如果有当前变量中的值为命名的函数,就会调用。如果没有就报错。
·
可变函数不能用于例如 echo,print,unset(),isset(),empty(),include,require eval() 以及类似的语言结构。需要使用自己的包装函数来将这些结构用作可变函数。

例:结果输出1

1
2
3
4
5
6
$b = 'get';
function get(){
echo 1;
}
$b();

进一步研究

当我把PHP版本调到7.0时 assert()正常

但PHP版本调到7.1以上后,assert()和eval()都报错

assert报错:

Cannot call assert() with string argument dynamically in -> 无法在中使用字符串参数动态调用assert()

查询文档资料

在PHP7.1版本以后, assert()默认不再可以执行代码

这就是现在大量一句话木马不能使用的罪魁祸首,一般大多的马用assert()来执行代码了,当PHP版本更新后基本就团灭了,一般情况下修改成eval即可正常运行了

结论

(1)eval是语言构造器而不是一个函数,不能被可变函数调用
(2)在php7.1版本之后 assert()默认不再可以执行代码