/GS (Pemeriksaan Keamanan Buffer)

Mendeteksi beberapa buffer overruns yang menimpa alamat pengembalian fungsi, alamat handler pengecualian, atau jenis parameter tertentu. Menyebabkan overrun buffer adalah teknik yang digunakan oleh peretas untuk mengeksploitasi kode yang tidak memberlakukan pembatasan ukuran buffer.

Sintaks

/GS[-]

Keterangan

/GS aktif secara default. Jika Anda mengharapkan aplikasi Anda tidak memiliki paparan keamanan, gunakan /GS-. Untuk informasi selengkapnya tentang menekan deteksi overrun buffer, lihat safebuffer.

Pemeriksaan Keamanan

Pada fungsi yang dikenal kompilator sebagai subjek masalah buffer overrun, pengkompilasi mengalokasikan ruang pada tumpukan sebelum alamat pengembalian. Pada entri fungsi, ruang yang dialokasikan dimuat dengan cookie keamanan yang dihitung sekali pada beban modul. Pada keluar fungsi, dan selama melepas bingkai pada sistem operasi 64-bit, fungsi pembantu dipanggil untuk memastikan bahwa nilai cookie masih sama. Nilai yang berbeda menunjukkan bahwa timpa tumpukan mungkin telah terjadi. Jika nilai yang berbeda terdeteksi, proses dihentikan.

Buffer GS

Pemeriksaan keamanan overrun buffer dilakukan pada buffer GS. Buffer GS dapat berupa salah satu dari berikut:

  • Array yang lebih besar dari 4 byte, memiliki lebih dari dua elemen, dan memiliki jenis elemen yang bukan tipe penunjuk.

  • Struktur data yang ukurannya lebih dari 8 byte dan tidak berisi pointer.

  • Buffer yang dialokasikan dengan menggunakan fungsi _alloca .

  • Kelas atau struktur apa pun yang berisi buffer GS.

Misalnya, pernyataan berikut mendeklarasikan buffer GS.

char buffer[20];
int buffer[20];
struct { int a; int b; int c; int d; } myStruct;
struct { int a; char buf[20]; };

Namun, pernyataan berikut tidak mendeklarasikan buffer GS. Dua deklarasi pertama berisi elemen jenis penunjuk. Pernyataan ketiga dan keempat menyatakan array yang ukurannya terlalu kecil. Pernyataan kelima menyatakan struktur yang ukurannya pada platform x86 tidak lebih dari 8 byte.

char *pBuf[20];
void *pv[20];
char buf[4];
int buf[2];
struct { int a; int b; };

Opsi pengkompilasi /GS mengharuskan cookie keamanan diinisialisasi sebelum fungsi apa pun yang menggunakan cookie dijalankan. Cookie keamanan harus segera diinisialisasi pada entri ke EXE atau DLL. Ini dilakukan secara otomatis jika Anda menggunakan titik masuk VCRuntime default: mainCRTStartup, wmainCRTStartup, WinMainCRTStartup, wWinMainCRTStartup, atau _DllMainCRTStartup. Jika Anda menggunakan titik masuk alternatif, Anda harus menginisialisasi cookie keamanan secara manual dengan memanggil __security_init_cookie.

Apa yang Dilindungi

Opsi pengkompilasi /GS melindungi item berikut:

  • Alamat pengembalian panggilan fungsi.

  • Alamat handler pengecualian untuk fungsi.

  • Parameter fungsi yang rentan.

Pada semua platform, /GS mencoba mendeteksi buffer overruns ke alamat pengembalian. Buffer overruns lebih mudah dieksploitasi pada platform seperti x86 dan x64, yang menggunakan konvensi panggilan yang menyimpan alamat pengembalian panggilan fungsi pada tumpukan.

Pada x86, jika fungsi menggunakan handler pengecualian, pengkompilasi menyuntikkan cookie keamanan untuk melindungi alamat handler pengecualian. Cookie diperiksa selama melepas bingkai.

/GS melindungi parameter rentan yang diteruskan ke dalam fungsi. Parameter yang rentan adalah penunjuk, referensi C++, struktur C (jenis POD C++) yang berisi pointer, atau buffer GS.

Parameter yang rentan dialokasikan sebelum cookie dan variabel lokal. Buffer overrun dapat menimpa parameter ini. Dan kode dalam fungsi yang menggunakan parameter ini dapat menyebabkan serangan sebelum fungsi kembali dan pemeriksaan keamanan dilakukan. Untuk meminimalkan bahaya ini, pengkompilasi membuat salinan parameter yang rentan selama prolog fungsi dan menempatkannya di bawah area penyimpanan untuk buffer apa pun.

Pengkompilasi tidak membuat salinan parameter yang rentan dalam situasi berikut:

  • Fungsi yang tidak berisi buffer GS.

  • Pengoptimalan (opsi/O) tidak diaktifkan.

  • Fungsi yang memiliki daftar argumen variabel (...).

  • Fungsi yang ditandai dengan telanjang.

  • Fungsi yang berisi kode rakitan sebaris dalam pernyataan pertama.

  • Parameter hanya digunakan dengan cara yang cenderung tidak dapat dieksploitasi jika buffer diserbu.

Apa yang Tidak Dilindungi

Opsi pengkompilasi /GS tidak melindungi dari semua serangan keamanan yang diserbu buffer. Misalnya, jika Anda memiliki buffer dan vtable dalam objek, buffer overrun dapat merusak vtable.

Bahkan jika Anda menggunakan /GS, selalu coba tulis kode aman yang tidak memiliki buffer overruns.

Untuk mengatur opsi pengkompilasi ini di Visual Studio

  1. Buka kotak dialog Halaman Properti proyek. Untuk detailnya, lihat Mengatur pengkompilasi C++ dan membuat properti di Visual Studio.

  2. Pilih halaman properti Properti>Konfigurasi C/C++>Code Generation.

  3. Ubah properti Pemeriksaan Keamanan Buffer.

Untuk mengatur opsi pengkompilasi ini secara terprogram

Contoh

Sampel ini menimpa buffer. Ini menyebabkan aplikasi gagal pada runtime.

// compile with: /c /W1
#include <cstring>
#include <stdlib.h>
#pragma warning(disable : 4996)   // for strcpy use

// Vulnerable function
void vulnerable(const char *str) {
   char buffer[10];
   strcpy(buffer, str); // overrun buffer !!!

   // use a secure CRT function to help prevent buffer overruns
   // truncate string to fit a 10 byte buffer
   // strncpy_s(buffer, _countof(buffer), str, _TRUNCATE);
}

int main() {
   // declare buffer that is bigger than expected
   char large_buffer[] = "This string is longer than 10 characters!!";
   vulnerable(large_buffer);
}

Baca juga

Opsi Pengkompilasi MSVC
Sintaks Baris Perintah Pengkompilasi MSVC