[Web] Puzzle - Securinets CTF Quals 2025

2025. 10. 6. 19:45·

Mô tả thử thách


Phân tích

Đầu tiên thử sử dụng Burp Scanner xem có lỗ hổng gì không

Vậy mình sẽ chuyển qua tìm kiếm trong source trước

Nhận thấy trong auth.py có đoạn xác thực user như sau

def confirm_register():
        username = request.form['username']
        email = request.form.get('email', '')
        alphabet = string.ascii_letters + string.digits + '!@#$%^&*'
        password = ''.join(secrets.choice(alphabet) for _ in range(12))
        role = request.form.get('role', '2')

        role_map = {
            '1': 'editor',
            '2': 'user',
        }

        if role == '0':
            return jsonify({'error': 'Admin registration is not allowed.'}), 403

        if role not in role_map:
            return jsonify({'error': 'Invalid role id.'}), 400

        uid = str(uuid4())

        try:
            with sqlite3.connect(DB_FILE) as db:
                db.execute('INSERT INTO users (uuid, username, email, password, role) VALUES (?, ?, ?, ?, ?)',
                           (uid, username, email, password, role))
                db.commit()
        except sqlite3.IntegrityError:
            return jsonify({'error': 'Username already exists.'}), 400

        session['uuid'] = uid
        session['first_login'] = True
        session['first_login_password'] = password

        return jsonify({
            'success': True,
            'redirect': '/home'
        }), 200

Mình thấy nó sẽ tự động cấp cho người dùng mới tạo acc là role user với id là 2, trong code còn role editor với id là 1 và admin với id là 0

Ngoài ra nó còn chấp nhận trường role từ request nhưng lại chặn role với id là 0, tức admin, vậy mình sẽ thử tạo acc với role là 1 tức editor xem sao

Sau đó mình sẽ lấy session web gen cho để đăng nhập

Gửi request /home và Repeater và thay cookies

Vậy là đã có passwd để đăng nhập, thử đăng nhập vào trang web

Tiếp tục tìm kiếm trong source, tại file routes.py có một đoạn lấy dữ liệu người dùng theo uuid như sau

@app.route('/users/<string:target_uuid>')
    def get_user_details(target_uuid):
        current_uuid = session.get('uuid')
        if not current_uuid:
            return jsonify({'error': 'Unauthorized'}), 401
        
        current_user = get_user_by_uuid(current_uuid)
        if not current_user or current_user['role'] not in ('0', '1'):
            return jsonify({'error': 'Invalid user role'}), 403
            
        with sqlite3.connect(DB_FILE) as conn:
            conn.row_factory = sqlite3.Row
            c = conn.cursor()
            c.execute("""
                SELECT uuid, username, email, phone_number, role, password
                FROM users 
                WHERE uuid = ?
            """, (target_uuid,))
            user = c.fetchone()
            
        if not user:
            return jsonify({'error': 'User not found'}), 404
            
        return jsonify({
            'uuid': user['uuid'],
            'username': user['username'],
            'email': user['email'],
            'phone_number': user['phone_number'],
            'role': user['role'],
            'password': user['password']
        })

Dữ liệu lấy ra sẽ được trả về dưới dạng file json và không mã hóa mật khẩu, sẽ là điểm thích hợp để đánh cắp passwd của admin nếu như biết uuid

Tiếp tục tìm kiếm trong source xem có chỗ nào leak được uuid của admin, nhận thấy có 1 endpoint accept collab mà không kiểm tra quyền, cho phép bất kỳ tài khoản nào gọi API để chấp nhận request và gây ra hành vi mà server thực hiện như admin đã accept

@app.route('/collab/accept/<string:request_uuid>', methods=['POST'])
    def accept_collaboration(request_uuid):
        if not session.get('uuid'):
            return jsonify({'error': 'Unauthorized'}), 401
        
        user = get_user_by_uuid(session['uuid'])
        if not user:
            return redirect('/login')
        if user['role'] == '0':
            return jsonify({'error': 'Admins cannot collaborate'}), 403
        
        try:
            with sqlite3.connect(DB_FILE) as conn:
                conn.row_factory = sqlite3.Row
                c = conn.cursor()
                
                c.execute("SELECT * FROM collab_requests WHERE uuid = ?", (request_uuid,))
                request = c.fetchone()
                
                if not request:
                    return jsonify({'error': 'Request not found'}), 404
                
                c.execute("""
                    INSERT INTO articles (uuid, title, content, author_uuid, collaborator_uuid)
                    VALUES (?, ?, ?, ?, ?)
                """, (request['article_uuid'], request['title'], request['content'], 
                      request['from_uuid'], request['to_uuid']))
                
                c.execute("UPDATE collab_requests SET status = 'accepted' WHERE uuid = ?", (request_uuid,))
                conn.commit()
                
                return jsonify({'message': 'Collaboration accepted'})
        except Exception as e:
            return jsonify({'error': str(e)}), 500

Nhập bừa nội dung và chọn người collaborator là admin

Collab request đã được gửi cho admin 

Copy uuid của request từ GET /collaborator

Gửi request này đến Repeater và chuyển method thành POST đồng thời chuyển URL thành /collab/accept/${uuid}

Yêu cầu đã được chấp nhận

Bây giờ chỉ cần quay lại bài viết và lấy ra uuid của admin

Sau đó sử dụng URL tìm kiếm user là /users/<uuid>

Bây giờ mình sẽ đăng nhập vào tài khoản admin

Bây giờ chúng ta sẽ truy cập vào /data như trong routes.py đã để lộ 

Tải secrets.zip về

Nhận thấy cần mật khẩu để giải mã, mình tải tiếp dbconnect.exe về để tìm kiếm mật khẩu

Extrace file zip và lấy flag


Flag

Flag: Securinets{777_P13c3_1T_Up_T0G3Th3R}

'WriteUp > Web' 카테고리의 다른 글

[Web] devtools-sources - Dreamhack  (0) 2025.10.11
[Web] cookie - Dreamhack  (0) 2025.10.11
[Web] Lunar File Invasion (SunshineCTF 2025)  (0) 2025.10.01
[Web] Web Forge (SunshineCTF 2025)  (0) 2025.10.01
[Web] Lunar Shop (SunshineCTF 2025)  (0) 2025.10.01
'WriteUp/Web' Other posts in category
  • [Web] devtools-sources - Dreamhack
  • [Web] cookie - Dreamhack
  • [Web] Lunar File Invasion (SunshineCTF 2025)
  • [Web] Web Forge (SunshineCTF 2025)
longhd
longhd
Longhd's Blog
  • longhd
    Ha Duy Long - InfosecPTIT
    longhd
  • Total
    Today
    Yesterday
  • About me

    • Hello I'm Duy Long 👋🏻
    • View all categories (117) N
      • Certificates (4)
      • CTF (3)
      • WriteUp (94) N
        • Forensics (44) N
        • Steganography (5)
        • RE (9) N
        • OSINT (8)
        • Web (17)
        • MISC (6)
        • Crypto (3)
        • Pwn (2)
      • Love Story (0)
      • Labs (15)
        • Information Gathering (10)
        • Vulnerability Scanning (2)
        • Introduction to Web Applica.. (1)
        • Common Web Application Atta.. (1)
        • SQL Injection Attacks (1)
  • Blog Menu

    • Home
    • Tag
    • GuestBook
  • Popular Posts

  • Tags

    THM
    misc
    writeup
    OSINT
    POCCTF2025
    picoCTF
    V1tCTF2025
    PTITCTF2025
    CTF
    CHH
    SunshineCTF2025
    CSCV2025
    Dreamhack
    BuckeyeCTF2025
    Re
    Steganography
    Web
    EnigmaXplore3.0
    htb
    Forensics
  • Recent Comments

  • Recent Posts

  • hELLO· Designed ByLong.v4.10.4
longhd
[Web] Puzzle - Securinets CTF Quals 2025
Go to Top

티스토리툴바