C++ coroutines: rủi ro từ cuộc tấn công tái sử dụng mã dù có tính toàn vẹn điều khiển

Minh Nguyệt
Minh Nguyệt
Phản hồi: 0

Minh Nguyệt

Intern Writer
Một lỗ hổng bảo mật mới mang tên Coroutine Frame-Oriented Programming (CFOP) đã được phát hiện, cho phép khai thác các coroutine trong C++ qua ba trình biên dịch lớn, bao gồm Clang/LLVM, GCC và MSVC. Đặc biệt, CFOP còn có thể tấn công thành công ngay cả trong những môi trường đã được bảo vệ bởi Control Flow Integrity (CFI), chỉ ra những lỗ hổng quan trọng trong 15 cơ chế bảo vệ này. Thay vì tiêm mã mới vào chương trình, CFOP kết nối các hàm hiện có với nhau, từ đó có thể thực hiện các lệnh tùy ý sau khi làm hỏng cấu trúc bộ nhớ nội bộ của coroutine.

Nghiên cứu này được thực hiện bởi các chuyên gia tại Trung tâm An ninh Thông tin CISPA Helmholtz, những người đầu tiên nghiên cứu các coroutine C++ từ góc độ bảo mật. Hai nhà nghiên cứu Marcos Sanchez Bajo và Giáo sư Dr. Christian Rossow đã chỉ ra rằng tất cả các triển khai hiện có của C++ coroutine đều có thể bị khai thác để vượt qua các biện pháp bảo vệ CFI tiên tiến nhất trên cả hai hệ điều hành Linux và Windows. Kết quả của cuộc tấn công CFOP là làm hỏng bộ nhớ heap, cho phép kẻ tấn công thao túng dữ liệu và hoàn toàn kiểm soát các ứng dụng.

c-coroutines-prone-to.jpg


Coroutines là một tính năng khá mới mẻ trong C++, đã xuất hiện trong hơn 130 kho dự án nổi tiếng trên GitHub. Chúng thường được sử dụng để tạm dừng và tiếp tục thực hiện các hàm, rất hữu ích cho lập trình bất đồng bộ, ví dụ như trong các máy chủ, cơ sở dữ liệu hay trình duyệt web. Để hiểu rõ hơn về CFOP, hãy tưởng tượng về một dãy số Fibonacci, trong đó mỗi số mới là tổng của hai số trước đó. Sau mỗi số mới, coroutine sẽ tạm dừng cho đến khi được gọi để tạo ra số tiếp theo.

Theo Bajo, với các cuộc tấn công tái sử dụng mã nói chung, kẻ tấn công lấy các đoạn mã đã tồn tại của ứng dụng mà không phải tiêm thêm mã mới. Họ kết nối các đoạn mã này để thao túng luồng thực thi của chương trình. Tuy nhiên, vượt qua bảo vệ CFI là một việc khó khăn hơn. Không chỉ đơn thuần kết nối các đoạn mã, mà cần phải kết nối đầy đủ các hàm coroutine một cách thông minh.

CFI được thiết kế để bảo vệ chống lại các cuộc tấn công tái sử dụng mã, đảm bảo rằng luồng thực thi của chương trình đúng đắn. Tuy nhiên, ngôn ngữ lập trình phát triển một cách năng động trong khi CFI chỉ bảo vệ các phương pháp lập trình đã có tại thời điểm nó được tạo ra. Bajo chỉ ra rằng, vấn đề chính là CFI chỉ bảo vệ các khả năng của ngôn ngữ lập trình như hiện tại; nếu có tính năng mới nào được giới thiệu sau đó, CFI sẽ không nhận ra và không thể xử lý.

Trong nghiên cứu của mình, Bajo và Rossow phát hiện rằng chỉ có 7 trong tổng số 15 cơ chế CFI mà họ xem xét ban đầu tương thích với coroutines. Trong số này, chỉ có hai cơ chế (IBT và Control Flow Guard) cung cấp sự bảo vệ một phần đối với việc khai thác các coroutine, trong khi năm cơ chế còn lại thì không cung cấp sự bảo vệ nào. Bajo nói: “Cuối cùng, chúng tôi đã có thể vượt qua tất cả chúng. Với CFOP, bạn vẫn có thể thực hiện tất cả những gì có thể trước khi có CFI.”

C++ coroutines ngày càng trở nên phổ biến, điều này càng làm tăng tiềm năng của CFOP. Bajo cho biết: “Coroutines được giới thiệu trong C++ vào năm 2020 và từ đó đến nay, các nhà phát triển ngày càng sử dụng chúng nhiều hơn. Đáng tiếc, chúng tôi phát hiện rằng coroutines có những cấu trúc nhất định trong bộ nhớ có thể trở thành mục tiêu của kẻ tấn công.” Vấn đề là, CFOP có thể xảy ra vì ba trình biên dịch chính đã triển khai các coroutine của C++ theo cách khiến chúng trở nên dễ bị tổn thương về cấu trúc. Bajo khẳng định rằng việc khắc phục kỹ thuật khai thác này không đơn giản chỉ là sửa mã—đó là một vấn đề cấu trúc và cần phải xem xét lại cách thức hoạt động bên trong của ứng dụng.

Bajo và Rossow đã phát triển các phương pháp triển khai thay thế hiệu quả cho C++ coroutines và đã báo cáo những biện pháp giảm thiểu này cho Clang/LLVM, GCC và MSVC vào tháng 11 năm 2024. Nghiên cứu của CISPA về CFOP sẽ được trình bày tại Black Hat USA 2025 diễn ra tại Las Vegas vào ngày 7 tháng 8. Thông tin thêm: Marcos Sanchez Bajo et al, “Await() a Second: Evading Control Flow Integrity by Hijacking C++ Coroutines”, CISPA (2025). DOI: 10.60882/cispa.28718642.v1.

Nguồn tham khảo: https://techxplore.com/news/2025-08-coroutines-prone-code-reuse.html
 


Đăng nhập một lần thảo luận tẹt ga
Thành viên mới đăng
http://textlink.linktop.vn/?adslk=aHR0cHM6Ly93d3cudm5yZXZpZXcudm4vdGhyZWFkcy9jLWNvcm91dGluZXMtcnVpLXJvLXR1LWN1b2MtdGFuLWNvbmctdGFpLXN1LWR1bmctbWEtZHUtY28tdGluaC10b2FuLXZlbi1kaWV1LWtoaWVuLjY3NDAwLw==
Top