(Write-up) mCTF - Brawl: The Quest for Gems

(Write-up) mCTF - Brawl: The Quest for Gems

💻Problem

Leyang has run out of gems to buy new brawlers! He is desperate as flexing on other kids with his 2 trophies in Brawl Stars is his only form of entertainment. Being a broke student, he has tasked you with obtaining gems through unethical means so that he can join the cool kids' club.

🤔 Start

Truy cập vào trang web, ta thấy được có 2 liên kết tới 2 trang đăng nhập /loginvà đăng ký /register
notion image
Mình thử truy cập vào Register và đăng ký một tài khoản mới với userid 1 (userid chỉ có thể là số) và password 1
Tiếp theo, mình thử đăng nhập với userid 1 nhưng không nhập mật khẩu để xem có thông báo gì trả về —> Trang web điều hướng sang 1 video troll 😵 chứ không có thông báo gì hehe.
Tiếp tục đăng nhập vào bằng đúng mật khẩu thì xuất hiện giao diện như dưới:
notion image
picture1
Trong source trang này cũng không có gì nữa nên mình tải source code được cung cấp về để khám phá.
Đầu tiên mình đọc file schema.sql để biết cấu trúc dữ liệu của nó như thế nào. Qua file này ta biết được có 2 table là usersgemdata liên kết với khau bằng khoá ngoại userid
Tiếp đến mình phần tích file index.js, đây là file xử lý phía back-end của trang.
Sau một thời gian phân tích thì mình rút ra được kết luận: khi user đăng ký một tài khoản mới, đoạn query ở route /register sẽ sinh ra ngẫu nhiên một số gem ngẫu nhiên trong khoảng 0 đến 1000 sau đó lưu vào table gemdata .
let queryres = execQuery(`INSERT INTO users VALUES(${parseInt(req.body.userid)}, "${req.body.password}"); INSERT INTO gemdata VALUES(${Math.floor(1000 * Math.random())}, ${parseInt(req.body.userid)});`);
Bên cạnh đó, lập trình viên cũng đã lọc đi một số ký tự để chống SQLi như \n, \r, —. Việc filter đi để chống việc comment, tuy nhiên dev vẫn bỏ sót ký tự # có chức năng tương tự. Đồng thời, việc không filter đi các ký tự trong input người dùng đã tạo ra untrusted data để hacker có thể tấn công SQLi.
Cuối cùng, dựa vào đề bài và source code thì mình đoán là để bypass bài này thì phải làm sao đó để germ của user vượt ra khỏi con số 1000.
Vậy là đã xong phần phân tích mã nguồn. Bắt tay vào ‘hack’ thôi 🧑‍💻

🚩LET’S GO

Dựa vào việc ta có thể tấn công SQLi như đã phân tích ở trên, mình tìm ra nơi có thể inject mã vào query ở đoạn code này, cụ thể là input password được nhập vào form đăng ký tài khoản.
${req.body.password}"); INSERT INTO gemdata VALUES(${Math.floor(1000 * Math.random())}, ${parseInt(req.body.userid)});
Mình inject đoạn này bằng đoạn payload đăng ký user mới với userid là 100 và password như sau 1"); INSERT INTO gemdata VALUES(1001, 100);
Tuy response trả về trang đăng ký không thành công nhưng khi ra trang login và nhập userid 100 và password là 1 thì …
Bùm!!! Flag hiện ra trước mắt 😁😁
Tự làm để biết nhé ! Không có flag chay cho mà nhập đâu =))))
 

Loading Comments...