📌 Bài viết này thuộc chuỗi write-up quá trình tiếp cận và đáp án cho các bài lab từ Portswigger Web Academy mà mình đã làm trong thời gian thực tập tại NCSC.
Mình không thích lắm cái cách mấy idol viết write-up lab theo kiểu cứ như thể họ đã biết đáp án từ đầu – họ chẳng bao giờ đủ kiên nhẫn để giải thích cặn kẽ tại sao họ lại làm một cái gì đó. Vậy nên, write-up phong cách bạn Tiểu ra đời. Mình mong là bạn có được những câu trả lời thoả đáng qua loạt bài này. Những ý kiến góp ý, thảo luận, báo lỗi – luôn luôn được hoan nghênh dưới mục comment.
Đề bài
Ngữ cảnh: Giao diện quản trị viên của bài lab này có một lỗ hổng xác thực, nhưng chỉ có thể khai thác được nếu bạn biết được một HTTP header tuỳ biến được sử dụng từ bên phía front-end.
Mục tiêu: Lấy được tên header và sử dụng nó để vượt qua bước xác thực của lab. Sau đó truy cập vào giao diện admin và lại thổi bay anh bạn quen thuộc – carlos
xấu số.
Thông tin sẵn có: Tài khoản với username và password quen thuộc wiener:peter
Phân tích
Lại như mọi khi, trước khi đưa bạn gợi ý hay cả đáp án, tôi vẫn mong là bạn nên dành chút thời gian để làm phần việc của mình trước khi giải bài:
- Đi một vòng tham quan, ngắm nghía xem cái web có gì
- Kiểm tra (inspect) các thể loại source code, request qua lại
- Bí thì hỏi các bạn AI hoặc Google theo kiểu “đưa tao hint, đừng đưa tao đáp án”
- Rồi nếu mất nhiều thời gian quá mà chưa giải được thì hẵng vào đọc lời giải
Những thứ này là để bạn học được cái gì đó mỗi khi cái lab header ghi nhận lab đã được giải. Chúng ta đang học chứ không chạy KPI giải lab.
Dưới đây là quá trình của tôi, trong đó bao gồm cả phần tôi bị “bí”, để minh hoạ cho quá trình suy nghĩ của tôi. Bạn đọc có thể lướt xuống cuối xem lời giải luôn nếu muốn.
- Login vào
wiener
. Không thấy gì đặc biệt. Đề bài yêu cầu vào giao diện admin, lại đoán nó ở địa chỉ quen thuộc:/admin
. Mở được cái thì nó báo không cho vào:

2. Thử vài thứ [mà ngẫm lại giờ thấy hơi ngu đần] nhưng không ăn thua [dĩ nhiên rồi]

3. Tôi căng mắt nhìn cái Response mất gần nửa tiếng, không thấy thứ gì là custom header cả. Hỏi anh bạn Song Tử (Gemini) thì nó bảo Referer là custom header (!) Đúng là dăm ba mấy mô hình ngôn ngữ…
4. Sau một hồi, tôi nản quá, lại hỏi bạn Song Tử. Hỏi theo kiểu vô cùng cầu tiến học hỏi nhé. Bạn ấy đưa gợi ý:

Chìa khoá của bài lab này nằm ở mục thứ 2 mà Gemini gợi ý: Những request như GET có thể không làm lộ mọi thứ. Hãy thử đổi nó thành TRACE hay OPTIONS để xem có những tính năng ẩn hay các header sử dụng cho xác thực được dùng hay không.
Thôi, đến đấy là bạn phải tự làm đi nhé.
Nếu bí thì mới đọc tiếp dưới đây.
Lời giải
- Tôi đổi từ GET thành TRACE, và tìm thấy custom header là
X-Custom-IP-Authorization

Lưu ý: Cái IP như trong hình (hoặc cái IP bạn nhận được khi làm như trên) là IP của máy chúng ta, chứ không phải là luật xác thực IP phía server đâu nhé. Tức là cái 104.28.222.74
kia là IP máy tôi, chứ không phải là bài lab sẽ cho IP như vậy được truy cập đến /admin
.
Tôi nói vậy là vì tôi đã lại có một pha xử lý ngớ ngẩn nữa như thế này:

2. Phần việc còn lại là bypass hạn chế này thôi. IP ta muốn là gì?

127.0.0.1
là địa chỉ loopback, hay là địa chỉ trỏ đến localhost
, tức chính máy tính của bạn. Đây là một cách nói với ý rằng “Không nơi nào tốt như là nhà”.Ý tưởng ở đây là nói với máy chủ rằng “yêu cầu của tao thực chất là xuất phát từ chính mày đấy”. Chúng ta không cần biết cái X-Custom-IP-Authorization kia nó cho phép những IP nào được vào, nhưng hẳn là thường thì một cái server sẽ chấp nhận request “trông như” xuất phát từ chính nó.
Kỹ thuật của bài lab này chính là một trong những kỹ thuật kinh điển để “vượt tường” chặn IP mang tên IP Spoofing (Giả mạo IP). Portswigger cũng viết một bài doc về IP Spoofing với chính minh hoạ là bài lab này.
3. Vào cài đặt của mục Proxy, tìm kiếm Match and Replace, để thực hiện thêm header vào mọi truy vấn từ phía chúng ta:

Request gốc:

Ấn vào “Original request” để thấy có thể chọn xem phần request đã được sửa đổi:

4. Tải lại trang và quan sát thấy admin panel đã hiện ra. Vậy là xong việc.