Megosztás:


/GS (Puffer biztonsági ellenőrzése)

Észlel néhány puffertúllépést, amely felülírja a függvény visszatérési címét, a kivételkezelő címét vagy bizonyos típusú paramétereket. A puffertúlcsordulást a támadók olyan kód kihasználására használják, amely nem kényszeríti ki a pufferméret korlátozásait.

Szemantika

/GS[-]

Megjegyzések

A /GS alapértelmezés szerint be van kapcsolva. Ha arra számít, hogy az alkalmazás nem rendelkezik biztonsági kockázatokkal, használja a /GS-t. A puffertúlcsordulás észlelésének letiltásáról további információt a biztonságos tárolókban talál.

Biztonsági ellenőrzések

Azon függvények esetében, amelyeket a fordító puffertúlcsordulási problémáknak ismer fel, a fordító helyet foglal le a veremen a visszatérési cím előtt. A függvénybejegyzéskor a lefoglalt terület betöltődik egy biztonsági cookie-val , amely a modul betöltésekor egyszer lesz kiszámítva. A függvény kilépésekor és a keret 64 bites operációs rendszereken történő letekerése során a rendszer egy segédfüggvényt hív meg annak érdekében, hogy a cookie értéke továbbra is ugyanaz legyen. Egy másik érték azt jelzi, hogy a verem felülírása történt. Ha egy másik értéket észlel, a folyamat leáll.

GS-pufferek

A puffertúlcsordulás biztonsági ellenőrzése GS-pufferen történik. A GS-puffer a következők egyike lehet:

  • A 4 bájtnál nagyobb tömb több mint két elemből áll, és olyan elemtípussal rendelkezik, amely nem mutató típusú.
  • Olyan adatstruktúra, amelynek mérete meghaladja a 8 bájtot, és nem tartalmaz mutatót.
  • A függvény használatával _alloca lefoglalt puffer.
  • Minden olyan osztály vagy struktúra, amely GS-puffert tartalmaz.

Az alábbi utasítások például GS-puffereket deklarálnak.

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

Az alábbi utasítások azonban nem deklarálják a GS-puffereket. Az első két deklaráció mutató típusú elemeket tartalmaz. A harmadik és negyedik utasítás olyan tömböket deklarál, amelyek mérete túl kicsi. Az ötödik utasítás egy olyan struktúrát deklarál, amelynek mérete x86 platformon legfeljebb 8 bájt.

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

A /GS-fordító beállításhoz a biztonsági cookie inicializálását kell elvégezni a cookie-t használó függvények futtatása előtt. A biztonsági cookie-t azonnal inicializálni kell az EXE-be vagy DLL-be való belépéskor. Ez automatikusan megtörténik, ha az alapértelmezett VCRuntime belépési pontokat használja: mainCRTStartup, wmainCRTStartup, , WinMainCRTStartupwWinMainCRTStartupvagy _DllMainCRTStartup. Alternatív belépési pont használata esetén manuálisan kell inicializálnia a biztonsági cookie-t a hívással __security_init_cookie.

Mi a védett?

A /GS-fordító beállítás a következő elemeket védi:

  • Függvényhívás visszatérési címe.
  • Egy függvény kivételkezelőjének címe.
  • Sebezhető függvényparaméterek.

A /GS minden platformon megpróbálja észlelni a puffertúllépéseket a visszatérési címben. A puffertúllépések könnyebben kihasználhatók olyan platformokon, mint az x86 és az x64, amelyek olyan hívási konvenciók használatával tárolják a függvényhívások visszatérési címét a veremen.

X86 esetén, ha egy függvény kivételkezelőt használ, a fordító egy biztonsági cookie-t injektál a kivételkezelő címének védelme érdekében. A cookie-t a keret feloldása során ellenőrzi a rendszer.

A /GS védi a függvénybe átadott sebezhető paramétereket . A sebezhető paraméter egy mutató, egy C++ referencia, egy mutatót tartalmazó C-struktúra (C++ POD-típus) vagy egy GS-puffer.

A rendszer egy sebezhető paramétert foglal le a cookie és a helyi változók előtt. A puffertúllépés felülírhatja ezeket a paramétereket. Az ezen paramétereket használó függvény kódja pedig támadást okozhat a függvény visszatérése és a biztonsági ellenőrzés végrehajtása előtt. A veszély minimalizálása érdekében a fordító másolatot készít a sebezhető paraméterekről a függvény prologja során, és a pufferek tárolási területe alá helyezi őket.

A fordító nem készít másolatot a sebezhető paraméterekről a következő helyzetekben:

  • A GS-puffert nem tartalmazó függvények.
  • Az optimalizálás (/O beállítások) nincsenek engedélyezve.
  • Változó argumentumlistával (...) rendelkező függvények.
  • Meztelenül megjelölt függvények.
  • Az első utasításban beágyazott szerelvénykódot tartalmazó függvények.
  • A paramétert csak olyan módokon használják, amelyek kevésbé valószínűek kihasználhatóak puffertúllépés esetén.

Mi nem védett?

A /GS-fordító nem nyújt védelmet az összes puffertúllépési biztonsági támadás ellen. Ha például van egy puffere és egy virtuális táblája egy objektumban, a puffer túlfuttatása megsérülhet a virtuális táblában.

A /GS használata esetén is mindig próbáljon meg olyan biztonságos kódot írni, amely nem rendelkezik puffertúllépésekkel.

A fordító beállításának beállítása a Visual Studióban

  1. Nyissa meg a projekt Tulajdonságlapok párbeszédpanelt. További információ: C++ fordító és buildtulajdonságok beállítása a Visual Studio.
  2. Válassza a Konfiguráció tulajdonságai>C/C++>Kódgenerálás tulajdonságlapját.
  3. Módosítsa a Puffer biztonsági ellenőrzése tulajdonságot.

A fordítóprogram programozott beállítása

példa

Ez a minta túllép egy puffert. Emiatt az alkalmazás futásidőben meghiúsul.

// 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);
}

Lásd még

MSVC-fordító beállításai
MSVC Fordító Command-Line Szintaxis