一、简介
Flask是由python实现的一个web微框架,让我们可以使用Python语言快速实现一个网站或Web服务
二、目录结构
flask-demo/
├ run.py # 应用启动程序
├ config.py # 环境配置
├ requirements.txt # 列出应用程序依赖的所有Python包
├ tests/ # 测试代码包
│ ├ __init__.py
│ └ test_*.py # 测试用例
└ myapp/
├ admin/ # 蓝图目录
├ static/
│ ├ css/ # css文件目录
│ ├ img/ # 图片文件目录
│ └ js/ # js文件目录
├ templates/ # 模板文件目录
├ __init__.py
├ forms.py # 存放所有表单,如果多,将其变为一个包
├ models.py # 存放所有数据模型,如果多,将其变为一个包
└ views.py # 存放所有视图函数,如果多,将其变为一个包
三、示例
from flask import Flask #引入Flask类
app = Flask(__name__) #为这个类创建一个实例,当前模块的`__name__`为`main`
@app.route('/') #用route()这个修饰器定义了一个路由,告诉flask如何访问该函数
def index():
return 'Hello World'
if __name__ == '__main__':
app.debug = True # 设置调试模式,生产模式的时候要关掉debug
app.run() #最后用run()函数使这个应用在服务器上运行起来
1、什么是路由(route)
https://blog.csdn.net/weixin_39862716/article/details/111791304
(1) 我的理解
简单来说路由就是一个映射器,利用一个给定的参数来映射到对应的指定路径或者执行函数等等
例如上面的示例,我们在浏览器中输入 http://localhost:5000/
浏览器中就会显示Hello World
(2) 动态路由
from flask import Flask
app1 = Flask('first_flask_demo')
@app1.route('/user/') # 指定了格式
def demo1(username): # username是用户从地址上的输入
return 'Welcome %s' % username
if __name__ == '__main__':
app1.run(debug=True, host='0.0.0.0', port=8080)
#运行后在浏览器中输入地址 http://localhost:8080/user/alex,可以看到输出为 Welcome alex
四、函数
1、urllib.unquote()
https://www.cnblogs.com/dplearning/p/5834938.html
用来处理提交的url,并解码
s = "url=%2F&email=imtesting%40tempmail.com&password=hereispassword"
print urllib.unquote(s)
>>> url=/&email=imtesting@tempmail.com&password=hereispassword
2、os.urandom()
https://www.pynote.net/archives/2215
os.urandom函数用来获取一个指定长度的随机bytes对象,python的这个函数实际上是在读取OS操作系统提供的随机源。
>>> os.urandom(1)
b'\x03'
>>> os.urandom(2)
b'\t['
>>> os.urandom(3)
b'\xdb\x8a\x7f'
>>> os.urandom(4)
b'Q\xeal\xf4'
>>> len(os.urandom(4))
4
3.request.cookies.get(“action”) 和 request.args.get(“param”, “”)
(1)args只获取地址栏中参数 ,不分get请求方式还是post请求方式
这里应该是指定了获取param
的值
(2)cookies 就是获取cookie中action的值
五、CTF原题
https://buuoj.cn/challenges#[De1CTF%202019]SSRF%20Me
1、源码
对现在的我来说有点多,一部分一部分的了解
可以看到,这个路由输出了源码
其他两个路由
2、解析
(1)大体思路
进入/De1ta
传参,先通过waf()
,再进入task.Exec()
在task.Exec()
中需要绕过checkSign()
中的getSign()
在getSign()
中我们需要知道它的secret_key
继续看task.Exec()
,它的 if 判断是个 in
,而不是==
,那就比较好绕过了
只需要action
包含read
就行了
还有最后一个路由,/geneSign
,在这个路由中,我们就可以获得我们想要的secret_key
在geneSign()
中的字符串,action
中的scan
是固定死的,但是param
是可控的
由于getSign()
和geneSion()
一样,其中param
是放在前面的:param
+action
那么我们构造param
为flag.txtread
param
+action
=flag.txtreadscan
在/geneSign
中传入 param=flag.txt
获得flag.txtreadscan
的secret_key=912a422c93150ba5df01396d193022ce
在路由/De1ta
中传入 param=flag.txt
action=flag.txt
secret_key=912a422c93150ba5df01396d193022ce
六、总结
1、简要的了解了一下Flask框架的构造和一些基本语法
2、这道CTF题并不算难,主要还是为了熟悉Flask框架
3、记录这道题的目的,还是为了能够更加熟悉Python的一些函数以及语法
为后面写Python的脚本打下一些基础
- 本文链接:http://siii0.github.io/CTF%E4%B9%8BFlask%E6%A1%86%E6%9E%B6%E7%AE%80%E8%A6%81%E4%BA%86%E8%A7%A3/
- 版权声明:本博客所有文章除特别声明外,均默认采用 许可协议。