Trong bài này mình sẽ giới thiệu qua về TOCTOU (time of check - time of use), một hướng khai thác trong race condition cũng như cách setup đơn giản để khai thác và giải một số bài minh hoạ.
Race condition là một lỗi xảy ra khi thực hiện một loạt các context switch giữa một process này với một process khác nhưng các process đấy lại xảy ra mâu thuẫn với nhau. TOCTOU là một dạng trong số các mâu thuẫn đấy và xảy ra khi chương trình check một điều kiện nào đó trước khi thực hiện công việc bất kỳ nhưng khi thực hiện context switch thì điều kiện đấy sẽ không còn đúng nữa và sẽ cho phép dẫn tới privilege escalation hoặc đọc ghi file ngoài ý muốn.
Nguyên nhân chính của việc dẫn đến race condition là do máy tính cho phép thực hiện multitask. Điều này giống như việc đang mở một task Discord và một task Chrome. Máy tính sẽ gây cho ta một ngộ nhận là các task này hoạt động song song với nhau nhưng thực chất là từng process trong task của Discord sẽ đan xen với từng process trong task của Chrome. Nhưng do tốc độ hoạt động của CPU quá nhanh nên ta nhầm tưởng chúng hoạt động song song. Điều này "khá tương tự" cách mắt bạn thấy ánh sáng từ đèn huỳnh quang. Về bản chất là nó chớp rồi tắt nhưng do dòng điện xoay chiều có tần số lớn nên mình tưởng nó luôn sáng.
Hình 1 : Việc một process thực hiện đơn lẽ
Hình 2 : Lầm tưởng chạy 2 process song song
Hình 3 : Thực chất việc máy tính xử lý. Việc chuyển từ công việc của một process này sang công việc của một process khác được gọi là context switch
Đây là một số khả năng khi ta chạy đa luồng 2 process cùng access vào 1 file:
Một trong số các khả năng đấy sẽ có tìm ẩn nguy hiểm. Ta thấy khả năng đầu tiên như sau
P1 và P2 cùng check_input
trong cùng một môi trường sau đó P1 do_action
với môi trường đó rồi sau đấy P2 lại do_action
với môi trường đã bị P1 thay đổi => có bug
Trong khả năng thứ 2 thì lại an toàn do thực hiện xong process này mới tới process khác
Trong các trường hợp còn lại thì process sau đều thực hiện do_action
mà không check_input
lại sau khi các process trước đó đã có tác động tới môi trường => có bug
Đầu tiên tạo file cần test và combile nó. Ở đây mình tạo file vuln.c
Code này sẽ ghi bash script vào file đến từ argument đầu của ta và thực thi nó
Tiếp theo tạo thêm flag, file để test exploit :
Ở đây ta chia hướng hoạt động của chương trình thành 3 việc nhỏ:
Ta có nhận xét là chương trình không check việc file đang thực thi có đúng là file ta đã mở không nên có có thể tấn công bằng TOCTOU nhờ vào file catflag
cho sẵn.
Ta có hướng tấn công như sau : tạo một process chạy song song để ghi đè cat flag
vào sau khi process gốc thực hiện xong việc "ghi file". Để thực hiện được điều đó ta cần timing hợp lý (tuỳ vào nhân phẩm).
Do đó ta viết shell script để spam việc copy content của file catflag
sang file test
tạo ra từ chương trình
Sau đó ta mở tab khác để chạy chương trình gốc.
Ta có nhận xét là không phải cứ chạy là rà flag mà tuỳ vào thời cơ.
Đề bài cho ta 3 file gồm: flag.txt, src.cpp và file binary txtreader.
File source như sau:
Ta cũng có thể chia cách hoạt động của chương trình thành 3 hướng như sau:
Do ở đây không có sẵn file nào giúp "thay thế" như trên nên ta sẽ lợi dụng bằng linking (ln) qua một file thứ 3.
Ta chia công việc linking thành 2 phần như sau
test
với file src.c
bằng ln -sf test src.c
test
với file flag.txt
bằng ln -sf test flag.txt
Mục đích của ta là chạy 2 chương trình cùng lúc để trigger context giống ảnh
Do file src.cpp
khá dài nên mình ln
qua file thứ 3 tên lmao
, về bản chất thì logic không thay đổi .
Tiếp theo mình chạy lệnh này để thực hiện việc spam ln
liên tiếp. Trong đó dấu &
cuối cho phép ta thực hiện tiếp mà không phải đợi lệnh này xong.
Cuối cùng chạy lệnh này để trigger toctou bằng cách spam tiếp chương trình gốc
Và hên là ta đã có flag