Writeup pwn-message-system.7z

 

Kỷ niệm ngày tìm về blog cũ, gaconkhokhao thử sức với 01 challenge pwnable trong đề thi CSCV 2026 😊

Nhận xét chung: Challenge sử dụng những kiến thức cơ bản về memory, nhưng phần khó nằm ở việc phải tận dụng các lỗ hổng về memory như thế nào để khai thác thành ccông. AI là thứ không thể thiếu nếu muốn tăng tốc việc đọc hiểu code và bypass đoạn xác thực ban đầu. Tuy nhiên, tránh viện sử dụng AI quá đà, challenge cũng thêm vào chức năng để đánh lừa các AI Agent. Nếu đem đi so sánh thì đây là một bài không quá khó trong các thử thách pwnable, cho thấy tụi sinh viên bây giờ giỏi phếch.

1. Đề bài cung cấp binary và Dockerfile. Xem Dockerfile thấy rõ challenge dựng trên bản ubuntu:24.04.

2. Biện pháp giảm thiểu binary dùng Canary (bảo vệ khỏi buffer over flow), Nx (không thực thi code trên stack), Pie (Randomize địa chỉ binary)


3. Khởi động chương trình

4. Phân tíchchỗ này:

Nếu chúng ta nhập vào các chuỗi password như “admin123”, “admin”, “guest”,... thử thách sẽ đánh lừa thí sinh và cho FLAG giả (đây là cách thức để đánh lừa các thí sinh sử dụng AI vô tội vạ):.


Do đó, thử thách đầu tiên là phải vượt qua điều kiện để Binary thực thi ở nhánh else ở dưới.


5. Phân tích rõ, nhận thấy điều kiện là phải tìm cách để chương trình thực thi nhánh này:



6. Đến đây, nếu không muốn mất nửa ngày trời thì nhờ AI giải mã giúp. Hóa ra chuỗi để xác thực đó là: “<|eot_id|><|im_end|>pwd=guest”

7. Đến đây, thử thách chính thức bắt đầu. Có hai lỗ hổng được tìm thấy:

7.1. Lỗ hổng “Use of Uninitialized Variable on the Stack” tại chứ năng “Call support”. Vùng giá trị biến local_1038 không nằm trong khu vực bộ nhớ được memset làm sạch.



Lỗ hổng này được tận dụng khi kết hợp với chức năng “Configure priority” để leak được giá trị quan trọng là Binary address.

 

7.2. Lỗ hổng Buffer Overflow trên Stack tại chức năng“Create message”. Lỗ hổng này cho phép ghi đè giá trị của địa chỉ message (địa chỉ message được khởi tạo trỏ về vùng heap thông qua hàm calloc mỗi khi có message mới).


8. Cần đánh giá thêm; mặc dù chương trình có cung cấp cho một hàm để gọi system(“/bin/sh”), nhưng việc ghi đè return address là không thể do Canary và  không có lỗ hổng nào để leak được Canary.

9. Việc leak được “Binary address” và ghi đè được địa chỉ quản lý “message” cho ta ý tưởng tạo các vùng trunk giả một cách hoàn hảo trên vùng .bss. Có thể tận dụng chức năng “Configure size” để tạo một trunk giả có độ lớn (size) giống với size của trunk “message” trong heap. Sau đó, tận dụng buffer over để ghi đè được địa chỉ quản lý “message” sang địa chỉ trunk giả.

Do ta quản lý được vùng .bss nên ta có thể liên tục tạo message và free message để trunk giả lấn chiếm đến nơi quản lý các hàm của các chức năng. Như ở hình phía trên là địa chỉ 0x555555559d50 quản lý 0x55555555a2a0 (nơi quản lý hàm các chức năng); bây giờ  đã bị ghi đè và trỏ về trunk giả được lắp đặt trước; hàm gọi system(“/bin/sh”) được dùng để ghi đè vào các chức năng.


10. Cuối cùng gọi chức năng bất kỳ, system(“/bin/sh”) sẽ được thực thi.