Mengontrol Flow Guard untuk keamanan platform

Apa itu Control Flow Guard?

Control Flow Guard (CFG) adalah fitur keamanan platform yang sangat dioptimalkan yang dibuat untuk memerangi kerentanan kerusakan memori. Dengan menempatkan pembatasan ketat di mana aplikasi dapat mengeksekusi kode, itu membuatnya jauh lebih sulit bagi eksploitasi untuk mengeksekusi kode sewenang-wenang melalui kerentanan seperti luapan buffer. CFG memperluas teknologi mitigasi eksploitasi sebelumnya seperti /GS, DEP, dan ASLR.

  • Mencegah kerusakan memori dan serangan ransomware.
  • Batasi kemampuan server ke apa pun yang diperlukan pada titik waktu tertentu untuk mengurangi permukaan serangan.
  • Jadikan lebih sulit untuk mengeksploitasi kode arbitrer melalui kerentanan seperti luapan buffer.

Fitur ini tersedia di Microsoft Visual Studio 2015, dan berjalan pada versi Windows "CFG-Aware"—rilis x86 dan x64 untuk Desktop dan Server Windows 10 dan Windows 8.1 Update (KB3000850).

Kami sangat mendorong pengembang untuk mengaktifkan CFG untuk aplikasi mereka. Anda tidak perlu mengaktifkan CFG untuk setiap bagian kode Anda, karena campuran kode yang diaktifkan CFG dan non-CFG akan dijalankan dengan baik. Tetapi gagal mengaktifkan CFG untuk semua kode dapat membuka celah dalam perlindungan. Selain itu, kode yang diaktifkan CFG berfungsi dengan baik pada versi "CFG-Unaware" dari Windows dan karenanya sepenuhnya kompatibel dengan mereka.

Bagaimana cara mengaktifkan CFG?

Dalam kebanyakan kasus, tidak perlu mengubah kode sumber. Yang harus Anda lakukan adalah menambahkan opsi ke proyek Visual Studio 2015 Anda, dan compiler dan linker akan mengaktifkan CFG.

Metode paling sederhana adalah menavigasi ke Project | Properti | Properti Konfigurasi | C/C++ | Pembuatan Kode dan pilih Ya (/guard:cf) untuk Kontrol Flow Guard.

cfg property in visual studio

Atau, tambahkan /guard:cf ke Project | Properti | Properti Konfigurasi | C/C++ | | Baris Perintah Opsi Tambahan (untuk pengkompilasi) dan /guard:cf untuk Project | Properti | Properti Konfigurasi | | Linker | Baris Perintah Opsi Tambahan (untuk linker).

cfg property for compilercfg property for linker

Lihat /guard (Aktifkan Control Flow Guard) untuk informasi tambahan.

Jika Anda membangun proyek dari baris perintah, Anda dapat menambahkan opsi yang sama. Misalnya, jika Anda mengkompilasi proyek yang disebut test.cpp, gunakan cl /guard:cf test.cpp /link /guard:cf.

Anda juga memiliki opsi untuk mengontrol set alamat target icall secara dinamis yang dianggap valid oleh CFG menggunakan SetProcessValidCallTargets dari MEMORY Management API. API yang sama dapat digunakan untuk menentukan apakah halaman tidak valid atau target yang valid untuk CFG. Fungsi VirtualProtect dan VirtualAlloc secara default akan memperlakukan wilayah tertentu dari halaman yang dapat dieksekusi dan diterapkan sebagai target panggilan tidak langsung yang valid. Dimungkinkan untuk mengambil alih perilaku ini, seperti saat menerapkan kompilator Just-in-Time, dengan menentukan PAGE_TARGETS_INVALID saat memanggil VirtualAlloc atau PAGE_TARGETS_NO_UPDATE saat memanggil VirtualProtect sebagaimana dirinci di bawah Konstanta Perlindungan Memori.

Bagaimana Cara Memberi Tahu Bahwa Biner berada di bawah Kontrol Flow Guard?

Jalankan alat dumpbin (termasuk dalam penginstalan Visual Studio 2015) dari prompt perintah Visual Studio dengan opsi /headers dan /loadconfig: dumpbin /headers /loadconfig test.exe. Output untuk biner di bawah CFG harus menunjukkan bahwa nilai header menyertakan "Guard", dan bahwa nilai konfigurasi beban menyertakan "CF Instrumented" dan "tabel FID ada".

output from dumpbin /headers

output from dumpbin /loadconfig

Bagaimana cara kerja CFG?

Kerentanan perangkat lunak sering dieksploitasi dengan memberikan data yang tidak mungkin, tidak biasa, atau ekstrem ke program yang sedang berjalan. Misalnya, penyerang dapat mengeksploitasi kerentanan luapan buffer dengan memberikan lebih banyak input ke program daripada yang diharapkan, sehingga menjalankan lebih banyak area yang disediakan oleh program untuk memegang respons. Ini dapat merusak memori yang berdekatan yang mungkin menyimpan penunjuk fungsi. Ketika program memanggil melalui fungsi ini, program dapat melompat ke lokasi yang tidak diinginkan yang ditentukan oleh penyerang.

Namun, kombinasi kuat dari dukungan kompilasi dan run-time dari CFG menerapkan integritas alur kontrol yang membatasi dengan ketat di mana instruksi panggilan tidak langsung dapat dijalankan.

Pengkompilasi melakukan hal berikut:

  1. Menambahkan pemeriksaan keamanan ringan ke kode yang dikompilasi.
  2. Mengidentifikasi kumpulan fungsi dalam aplikasi yang merupakan target yang valid untuk panggilan tidak langsung.

Dukungan runtime, disediakan oleh kernel Windows:

  1. Secara efisien mempertahankan status yang mengidentifikasi target panggilan tidak langsung yang valid.
  2. Menerapkan logika yang memverifikasi bahwa target panggilan tidak langsung valid.

Untuk mengilustrasikan:

cfg pseudocode

Ketika pemeriksaan CFG gagal pada runtime, Windows segera menghentikan program, sehingga melanggar eksploitasi apa pun yang mencoba untuk secara tidak langsung memanggil alamat yang tidak valid.