忙着毕业论文几天没做题了。
进入页面发现几个api接口,注册登录搜索登出4个。
利用postman访问注册接口注册。
可以看到返回了token,利用token访问login。
尝试search页面传入file参数试试能不能目录穿越。
得到secret-key,这里有个非预期解,访问/proc/1/environ直接得到flag。
预期解:访问/app/app.py得到源码。
点击查看代码
# coding=gbk
import json
from flask import Flask, request, jsonify, send_file, render_template_string
import jwt
import requests
from functools import wraps
from datetime import datetime
import osapp = Flask(__name__)
app.config['TEMPLATES_RELOAD'] = True
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY')
current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')response0 = {'code': 0, 'message': 'failed', 'result': None}
response1 = {'code': 1, 'message': 'success', 'result': current_time}
response2 = {'code': 2, 'message': 'Invalid request parameters', 'result': None}def auth(func):@wraps(func)def decorated(*args, **kwargs):token = request.cookies.get('token')if not token:return 'Invalid token', 401try:payload = jwt.decode(token, app.config['SECRET_KEY'], algorithms=['HS256'])if payload['username'] == User.username and payload['password'] == User.password:return func(*args, **kwargs)else:return 'Invalid token', 401except:return 'Something error?', 500return decorateddef check(func):@wraps(func)def decorated(*args, **kwargs):token = request.cookies.get('token')if not token:return 'Invalid token', 401try:payload = jwt.decode(token, app.config['SECRET_KEY'], algorithms=['HS256'])if payload['username'] == "Plato" and payload['password'] == "ideal_state":return func(*args, **kwargs)else:return 'You are not a sage. You cannot enter the ideal state.', 401except:return 'Something error?', 500return decorated@app.route('/', methods=['GET'])
def index():return send_file('api-docs.json', mimetype='application/json;charset=utf-8')@app.route('/enterIdealState', methods=['GET'])
@check
def getflag():flag = os.popen("/readflag").read()return flag@app.route('/api-base/v0/register', methods=['GET', 'POST'])
def register():if request.method == 'POST':username = request.json['username']if username == "Plato":return 'Your wisdom is not sufficient to be called a sage.', 401password = request.json['password']User.setUser(username, password)token = jwt.encode({'username': username, 'password': password}, app.config['SECRET_KEY'], algorithm='HS256')User.setToken(token)return jsonify(response1)return jsonify(response2), 400@app.route('/api-base/v0/login', methods=['GET', 'POST'])
def login():if request.method == 'POST':username = request.json['username']password = request.json['password']try:token = User.tokenpayload = jwt.decode(token, app.config['SECRET_KEY'], algorithms=['HS256'])if payload['username'] == username and payload['password'] == password:response = jsonify(response1)response.set_cookie('token', token)return responseelse:return jsonify(response0), 401except jwt.ExpiredSignatureError:return 'Invalid token', 401except jwt.InvalidTokenError:return 'Invalid token', 401return jsonify(response2), 400@app.route('/api-base/v0/logout')
def logout():response = jsonify({'message': 'Logout successful!'})response.delete_cookie('token')return response@app.route('/api-base/v0/search', methods=['POST', 'GET'])
@auth
def api():if request.args.get('file'):try:with open(request.args.get('file'), 'r') as file:data = file.read()return render_template_string(data)except FileNotFoundError:return 'File not found', 404except jwt.ExpiredSignatureError:return 'Invalid token', 401except jwt.InvalidTokenError:return 'Invalid token', 401except Exception:return 'something error?', 500else:return jsonify(response2)class MemUser:def setUser(self, username, password):self.username = usernameself.password = passworddef setToken(self, token):self.token = tokendef __init__(self):self.username = "admin"self.password = "password"self.token = jwt.encode({'username': self.username, 'password': self.password}, app.config['SECRET_KEY'], algorithm='HS256')if __name__ == '__main__':User = MemUser()app.run(host='0.0.0.0', port=8080)