Super Serial - picoCTF Web Exploitation: Writeup


Giới thiệu
Trong writeup này, mình sẽ chia sẻ cách khai thác challenge Super Serial thuộc mảng Web Exploitation của picoCTF. Đây là một bài lab xoay quanh lỗi PHP Deserialization – một lỗ hổng khá phổ biến và nguy hiểm nếu lập trình viên không xử lý dữ liệu cẩn thận.
Vậy lỗi PHP Deserialization là gì?
Serialization là quá trình chuyển đổi dữ liệu phức tạp từ đối tượng, mảng (object, array) thành chuỗi (string) để lưu trữ hoặc truyền đi, sau đó có thể deserialize (khôi phục) về dạng ban đầu.
Trong PHP, serialization thường được dùng để:
Lưu session.
Truyền object giữa các hệ thống.
Lưu dữ liệu trong file.
Vấn đề xảy ra khi ứng dụng deserialize input không tin cậy từ user. Attacker có thể:
Inject object tùy chỉnh.
Gọi đến các magic method nguy hiểm (
__wakeup()
,__destruct()
,__toString()
…).Thực hiện RCE, leo thang đặc quyền, hoặc đọc dữ liệu nhạy cảm.
.PHP vs .PHPS
.php
→ server sẽ chạy code và trả về output (người dùng sẽ không thấy source code)..phps
→ server sẽ hiển thị source code kèm highlight thay vì thực thi.Điều này hữu ích cho tutorial, demo, nhưng trong môi trường production thì cực kỳ nguy hiểm vì nó vô tình làm lộ source code.
Các bước thực hiện:
1. Khởi động
Link thử thách: http://mercury.picoctf.net:42449/
Challenge đưa ra hint: flag nằm ở
../flag
.Khi truy cập, ta gặp một form đăng nhập.
Trước tiên mình thử check
robots.txt
và thấy một entry gợi ý/admin.phps
.URL này trả về 404, nhưng
.phps
khiến mình nảy ra ý tưởng: thử đổiindex.php
thànhindex.phps
.Kết quả,
index.phps
load thành công và lộ toàn bộ source code.2. Thu thập source code
Bằng cách đổi những trang có đuôi
.php
sang.phps
index.phps
→ tham chiếu đếnauthentication.php
authentication.phps
→ tham chiếu đếncookie.php
Nhờ đó, mình đã lấy được logic xử lý cookie + unserialize.
3. Phân tích code
Tại endpoint authentication.phps
có class:
Class này có một thuộc tính công khai là
$log_file
chúng ta có thể kiểm soát.Hàm
__toString()
sẽ được gọi tự động khi đối tượng được dùng như một chuỗi. Trong trường hợp này nó gọi đến hàmread_log()
.Hàm
read_log()
sẽ đọc nội dung của tệp tin được chỉ định bởi$log_file
.
Trong cookie.phps
, có đoạn:
Ở đây, nếu có cookie là
login
sẽ đượcurldecode
rồi đưa vàobase64_decode
sau đóunserialize
trực tiếp thành một object PHPMột điều đặc biệt là khối
catch
khi có lỗi. Nếu quá trình unserialize thất bại, chương trình sẽ dừng lại và in ra thông báo "Deserialization error." kèm theo giá trị của biến$perm
.
Đây chính là điểm yếu mà chúng ta cần khai thác. Khi một đối tượng được in ra (như trong trường hợp này), PHP sẽ tự động gọi phương thức __toString()
của nó. Nếu chúng ta truyền một đối tượng của class access_log
vào, phương thức này sẽ được kích hoạt, đọc nội dung của tệp tin mà chúng ta đã chỉ định.
4. Xây dựng payload
Thay vì xây dựng chuỗi serialized một cách thủ công, mình quyết định viết một đoạn mã PHP đơn giản để tạo đối tượng và serialize nó một cách chính xác.
Ta có thể dùng https://onlinephp.io/ để chạy code php.
Đầu tiên ta có thể tạo một
class access_log
giống với mã nguồn của thử thách. Sau đó gán giá trị../flag
cho biến$log_file
Ta được biết biến
$perm
giải mã hóa theo formatunserialize(base64_decode(urlencode()))
nên khi mã hóa thì ta phải làm ngược lại làurlencode(base64_encode(serialize()))
. Sau đó in nó ra màn hình.Sau khi thực thi thi đoạn code trên thì ta được đoạn mã dưới đây:
Quay trở lại api
/authentication.php
vào phần cookie trong Storage thêm trườngname
=login
,value
là đoạn mã trên sau đó load lại trang.
Vậy là xong rồi!
Thử thách đã được giải quyết
Ta đã lợi dụng:
.phps leak → xem source code.
PHP unserialize() xử lý input từ cookie không an toàn.
Dùng object injection với
__toString()
để đọc flag.
Bài học rút ra
Không bao giờ dùng
unserialize()
với dữ liệu người dùng gửi lên.Tránh để lộ file
.phps
trên production server.Luôn sanitize/validate dữ liệu và xem xét dùng format an toàn hơn (JSON thay vì serialized object).
Kết luận
Challenge Super Serial minh họa rất rõ sự nguy hiểm của PHP deserialization. Đây là một lỗi nằm trong OWASP Top 10, có thể dẫn tới RCE hoặc lộ dữ liệu quan trọng.
Hy vọng bài writeup này giúp bạn hiểu rõ hơn cách khai thác và phòng tránh deserialization.
Subscribe to my newsletter
Read articles from Bui Thanh Tam directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
