随意输入个号上去,发现存在upload功能,点击后提示:Permission denied!。
掏出bp,在登录的时候抓包,可以看到可疑的session:
在login页面看到了源码提示:
<!-- 404 not found -->
随便访问个不存在的目录,在响应头看到了hint:
Swpuctf_csrf_token: U0VDUkVUX0tFWTprZXlxcXF3d3dlZWUhQCMkJV4mKg==
base64解码得:SECRET_KEY:keyqqqwwweee!@#$%^&*
根据网页标题的flask,结合session不难看出是flask session伪造。已经有key了。这里我用了flask-session-cookie-manager工具,首先解个码查看格式,然后照葫芦画瓢生产一个伪造的session。
成功获取到了权限。源代码发现注释:
@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"
真的又臭又长,不过搜索flag能找到它的位置在./flag/flag.jpg
,但是不知道其绝对路径。涉及几个知识点:
- 在 linux 中,
/proc/self/cwd/
会指向进程的当前目录,在不知道 flask 工作目录时,我们可以用/proc/self/cwd/flag/flag.jpg
来访问 flag.jpg。 - ln -s是Linux的软连接命令,其类似与windows的快捷方式。比如
ln -s /etc/passwd shawroot
这会出现一个名为shawroot的文件,其内容为/etc/passwd的内容。
所以最后思路是利用ln -s
命令,软连接到/proc/self/cwd/flag/flag.jpg
。
- ln -s /proc/self/cwd/flag/flag.jpg shaw
- zip -ry root.zip shaw
其中zip命令的参数含义如下:
-r:将指定的目录下的所有子目录以及文件一起处理
-y:直接保存符号连接,而非该连接所指向的文件,本参数仅在UNIX之类的系统下有效。
抓包上传root.zip,换下session得到flag。
⚪参考:
https://blog.csdn.net/mochu7777777/article/details/105666388