HCMUS-CTF 2023 Warm-up
Giải này chỉ private cho sinh viên trong trường chơi, nên mình có đi xin đề và source từ một người bạn tham gia giải. Chủ yếu là để luyện thêm CTF từ các trường khác.
Category |
Challenge Name |
Difficulty |
Web |
Polluted Web |
Easy |
Web |
Have I Been Pwned |
Medium |
Web |
8990 |
Easy |
Web |
Cute Page 2 |
Hard |
Polluted Web
- Preview
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
– Trang web viết bằng nodejs và có 2 chỗ input là Name và Opinion
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
Thử gửi lên và bắt request qua Burp thì mình thấy sau khi gửi web sẽ set một JWT lên, và nó sẽ parse ra để lấy Opinion.
– Tiếp theo đến với source code của bài:
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
Dòng 28 có gọi đến hàm validate
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
Và ta có thể thấy thêm được từ hàm validate có gọi đến hàm merge
(Mà thường thì khi sử dụng hàm này có thể bị prototype pollution)
Từ các điều kiện trên chúng ta cần gửi userOpinions && flag = true và temp.flag = false thì mới có thể lấy được flag
Và sửa Content-Type: application/json
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
Have I Been Pwned
- Preview
– Nhìn qua code thì cũng đoán được là SQL blind.
– Và có một ít filter.
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
Ở đây đầu vào là pw
sau khi đi qua hàm filter
Black list như sau:
-
Idea
– Vì ở bài này chỉ replaceAll khi mà gặp từ trong blacklist nên mình có thể sử dụng cách như sau:
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
Như vậy thì mình có thể dùng được Or mà không bị filter nữa.
– Tuy nhiên cách mình làm lại tránh đi sử dụng các từ này :v , vì 2 cách comment đều bị xoá nên mình làm như sau:
' || '1' = '1
Câu query sẽ trở thành:
SELECT id, password FROM pwned WHERE password='' || '1' = '1'
Và như thế là mình thành công trong việc inject.
Tiếp theo là chỉ cần lấy flag, vì trong file db tác giải đã hint Flag ở id = 1337 (Chứ mà ngồi brute từng dòng thì lâu mới xong :v)
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
-
Payload:
8990
- Preview
– Bài này có bị lộ flag khi chỉ cần truy cập vào file Docker, nhưng cái hay của bài là hướng RCE.
– Mình chia chall này thành 2 phần:
Đầu tiên là cần bypass login:
– Nếu chỉ login với account guest thì chúng ta không làm được gì, thế nhưng password admin đã bị hashmd5 mà không thể crack được.
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
- Idea
– Nếu username = debug , thì cần điều kiện từ ip local, chỗ này thì cũng không thể bypass được.
– Ở dòng 13 sử dụng extract để parse những cái mình input vào. -> Mình có thể exploit ở đây để login với admin, vì hàm này khá là nguy hiểm. Nói nôm na là extract sẽ đưa các biến input vào một mảng (Mình sẽ ghi đè lại password hash của admin).

Như vậy là login thành công, lấy PHPSESSID để vào bên trong trang web.
Tiếp đến đây là phần 2 của chall:

Một phần là vì thiếu file mà tác giả cung cấp, và lỗi font hay sao cái content nó bị ** như thế :v
– Chỉ có một chức năng duy nhất là search content. Chúng ta sẽ review qua source.
– Lại một lần nữa sử dụng hàm extract, và có thêm một câu query (Tuy nhiên ở đây theo cách viết này thì không bị lỗi sqli được).

Lướt xuống một chút thì có thể thấy filter_content được gọi đến từ file filter.php
Kết hợp với extract ở trên thì mình có thể control được ở đây, nhưng mà control vào hàm preg_replace thì làm được gì :v .

Tác giả lại đi sử dụng php 5.5 :/
Các bạn có thể tham khảo ở đây để biết thêm (Link)
Đọc qua về modifier e ở phiên bản 5.5 thì chút nào mọi người cũng hiểu được là nó sẽ chạy php bên trong hàm luôn.
Thế nên mình sẽ control cả 3 tham số truyền vào hàm và để RCE đọc flag.


- Payload:
/admin.php?q=o&mask=system('cat+/flag.txt');&filter=/o/e