Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu konu, Windows çekirdek sürücü kodunuzun istismarına ve suistimaline yol açabilecek güvensiz geliştirme desenlerini özetlemektedir. Bu konu, ayrıcalıklı davranışı kısıtlamaya yardımcı olmak için geliştirme önerileri ve kod örnekleri sağlar. Bu en iyi yöntemlerin takip etmek, Windows çekirdeğinde ayrıcalıklı davranış gerçekleştirmenin güvenliğini artırmaya yardımcı olur.
Güvenli olmayan sürücü davranışına genel bakış
Windows sürücülerinin çekirdek modunda yüksek ayrıcalıklı davranışlar gerçekleştirmesi beklense de, güvenlik denetimleri yapılmaması ve ayrıcalıklı davranışa kısıtlamalar eklenmemesi kabul edilemez. Eski adı WHQL olan Windows Donanım Uyumluluk Programı (WHCP), bu gereksinime uymak için yeni sürücü gönderimleri gerektirir.
Güvenli olmayan ve tehlikeli davranış örnekleri şunlardır ancak bunlarla sınırlı değildir:
- Rastgele makineye özgü yazmaçlara (MSR) okuma ve yazma olanağı sağlama
- Rastgele işlemleri sonlandırma olanağı sağlama
- Bağlantı noktası giriş ve çıkış okuma ve yazma olanağını sağlama
- Çekirdek, fiziksel veya cihaz belleği okuma ve yazma olanağı sağlama
MSR'leri okuma ve yazma olanağı sağlama
MSR'lerden okuma güvenliğini geliştirme
Bu ReadMsr örneğinde sürücü, __readmsr modelle özelleştirilmiş kayıt iç kullanarak tüm yazmaçların rastgele okunmasına izin veriyor, bu da güvensiz davranışlara yol açıyor. Bu, kullanıcı modunda kötü amaçlı işlemler tarafından kötüye kullanılmasına neden olabilir.
Func ReadMsr(int dwMsrIdx)
{
int value = __readmsr(dwMsrIdx); // Unsafe, can read from any MSR
return value;
}
Senaryonuz MSR'lerden okuma gerektiriyorsa, sürücünün her zaman okunacak kaydın beklenen dizin veya aralıkla kısıtlanmış olup olmadığını denetlemesi gerekir. Güvenli okuma işleminin nasıl uygulandığına ilişkin iki örnek aşağıda verilmiştir.
Func ConstrainedReadMsr(int dwMsrIdx)
{
int value = 0;
if (dwMsrIdx == expected_index) // Blocks from reading anything
{
value = __readmsr(dwMsrIdx); // Can only read the expected MSR
}
else
{
return error;
}
return value;
}
// OR
Func ConstrainedReadMsr(int dwMsrIdx)
{
int value = 0;
if (min_range <= dwMsrIdx <= max_range) // Blocks from reading anything
{
value = __readmsr(dwMsrIdx); // Can only from the expected range of MSRs
}
else
{
return error;
}
return value;
}
MSR'lere yazma güvenliğini geliştirme
İlk WriteMsr örneğinde, sürücü herhangi bir ve tüm yazmaçların rastgele yazılmasına izin vererek güvenli olmayan davranışlara izin verir. Bu, kullanıcı modunda ayrıcalığı yükseltmek ve tüm MSR'lere yazmak için kötü amaçlı işlemlerin kötüye kullanılmasına neden olabilir.
Func WriteMsr(int dwMsrIdx)
{
int value = __writemsr(dwMsrIdx); // Unsafe, can write to any MSR
return value;
}
Senaryonuz MSR'lere yazmayı gerektiriyorsa, sürücünün her zaman yazacak kaydın beklenen dizin veya aralıkla kısıtlanmış olup olmadığını denetlemesi gerekir. Güvenli yazma işleminin nasıl uygulandığına ilişkin iki örnek aşağıda verilmiştir.
Func ConstrainedWriteMsr(int dwMsrIdx)
{
int value = 0;
if (dwMsrIdx == expected_index) // Blocks from reading anything
{
value = __writemsr(dwMsrIdx); // Can only write to the expected constrained MSR
}
else
{
return error;
}
return value;
}
// OR
Func ConstrainedWriteMSR(int dwMsrIdx)
{
int value = 0;
if (min_range <= dwMsrIdx <= max_range) // Blocks from reading anything
{
value = __writemsr(dwMsrIdx); // Can only write to the expected constrained MSR
}
else
{
return error;
}
return value;
}
İşlemleri sonlandırma olanağı sağlama
Sürücünüzde işlemlerin sonlandırılmasına olanak tanıyan işlevler uygulanırken çok dikkatli olunmalıdır. Kötü amaçlı yazılımdan koruma ve virüsten koruma çözümleri tarafından kullanılanlar gibi korumalı işlemler ve korumalı işlem ışığı (PPL) işlemleri sonlandırılmamalıdır. Bu işlevselliğin açığa çıkartılması, saldırganların sistemdeki güvenlik korumalarını sonlandırmasına olanak tanır.
Senaryonuz işlem sonlandırma gerektiriyorsa, PsLookupProcessByProcessId ve
Func ConstrainedProcessTermination(DWORD dwProcessId)
{
// Function to check if a process is a Protected Process Light (PPL)
NTSTATUS status;
BOOLEAN isPPL = FALSE;
PEPROCESS process;
HANDLE hProcess;
// Open the process
status = PsLookupProcessByProcessId(processId, &process);
if (!NT_SUCCESS(status)) {
return FALSE;
}
// Check if the process is a PPL
if (PsIsProtectedProcess(process)) {
isPPL = TRUE;
}
// Dereference the process
ObDereferenceObject(process);
return isPPL;
}
Bağlantı noktası girişi ve çıkışına okuma ve yazma olanağı sağlama
Port Giriş/Çıkış'tan okuma güvenliğini artırma
Bağlantı noktası giriş/çıkışına (G/Ç) okuma özelliği sağlarken dikkatli olunmalıdır. __indword kullanan bu kod örneği güvenli değildir.
Func ArbitraryInputPort(int inPort)
{
dwResult = __indword(inPort); // Unsafe, allows for arbitrary reading from Input Port
return dwResult;
}
Sürücünün istismar edilmesini ve sömürülmesini önlemek için, beklenen giriş bağlantı noktası gerekli kullanım sınırına kısıtlanmalıdır.
Func ConstrainedInputPort(int inPort)
{
// The expected input port must be constrained to the required usage boundary to prevent abuse
if(inPort == expected_InPort)
{
dwResult = __indword(inPort);
}
else
{
return error;
}
return dwResult;
}
Port IO'ya yazma güvenliğini artırma
Bağlantı noktası giriş/çıkışına (G/Ç) yazma imkanı sağlarken dikkatli olunmalıdır. __outword kullanan bu kod örneği güvenli değildir.
Func ArbitraryOutputPort(int outPort, DWORD dwValue)
{
__outdword(OutPort, dwValue); // Unsafe, allows for arbitrary writing to Output Port
}
Sürücünün kötüye kullanımını ve istismarını önlemek için, giriş bağlantı noktasının kullanımı gerekli sınırlarla kısıtlanmalıdır.
Func ConstrainedOutputPort(int outPort, DWORD dwValue)
{
// The expected output port must be constrained to the required usage boundary to prevent abuse
if(outPort == expected_OutputPort)
{
__outdword(OutPort, dwValue); // checks on InputPort
}
else
{
return error;
}
}
Çekirdek, fiziksel veya cihaz belleği okuma ve yazma olanağı sağlama
Memcpy'nin güvenliğini geliştirme
Bu örnek kod, fiziksel belleğin güvenli kullanımının kısıtlanmamış ve güvenli olmayan kullanımını gösterir.
Func ArbitraryMemoryCopy(src, dst, length)
{
memcpy(dst, src, length); // Unsafe, can read and write anything from physical memory
}
Senaryonuz çekirdek, fiziksel veya cihaz belleği okuma ve yazma gerektiriyorsa, sürücünün her zaman kaynak ve hedeflerin beklenen dizinlerle veya aralıklarla kısıtlanıp kısıtlandığını denetlemesi gerekir.
Func ConstrainedMemoryCopy(src, dst, length)
{
// valid_src and valid_dst must be constrained to required usage boundary to prevent abuse
if(src == valid_Src && dst == valid_Dst)
{
memcpy(dst, src, length);
}
else
{
return error;
}
}
ZwMapViewOfSection güvenliğini geliştirme
Aşağıdaki örnekte, ZwOpenSection ve ZwMapViewOfSection API'lerini kullanarak kullanıcı modundan fiziksel belleği okumak ve yazmak için güvenli olmayan ve yanlış yöntem gösterilmektedir.
Func ArbitraryMap(PHYSICAL_ADDRESS Address)
{
ZwOpenSection(&hSection, ... ,"\Device\PhysicalMemory");
ZwMapViewOfSection(hSection, -1, 0, 0, 0, Address, ...);
}
Kötü amaçlı kullanıcı modu işlemleri tarafından sürücünün okuma/yazma davranışının kötüye kullanılmasını ve kötüye kullanılmasını önlemek için, sürücünün giriş adresini doğrulaması ve bellek eşlemesini yalnızca senaryo için gerekli kullanım sınırıyla sınırlaması gerekir.
Func ConstrainedMap(PHYSICAL_ADDRESS paAddress)
{
// expected_Address must be constrained to required usage boundary to prevent abuse
if(paAddress == expected_Address)
{
ZwOpenSection(&hSection, ... ,"\Device\PhysicalMemory");
ZwMapViewOfSection(hSection, -1, 0, 0, 0, paAddress, ...);
}
else
{
return error;
}
}
MmMapLockedPagesSpecifyCache güvenliğini geliştirme
Aşağıdaki örnekte, MmMapIoSpace, IoAllocateMdl ve MmMapLockedPagesSpecifyCache API'lerini kullanarak kullanıcı modundan fiziksel belleği okumak ve yazmak için güvenli olmayan ve yanlış yöntem gösterilmektedir.
Func ArbitraryMap(PHYSICAL_ADDRESS paAddress)
{
lpAddress = MmMapIoSpace(paAddress, qwSize, ...);
pMdl = IoAllocateMdl( lpAddress, ...);
MmMapLockedPagesSpecifyCache(pMdl, UserMode, ... );
}
Kötü amaçlı kullanıcı modu işlemleri tarafından sürücünün okuma/yazma davranışının kötüye kullanılmasını ve kötüye kullanılmasını önlemek için, sürücünün giriş adresini doğrulaması ve bellek eşlemesini yalnızca senaryo için gerekli kullanım sınırıyla sınırlaması gerekir.
Func ConstrainedMap(PHYSICAL_ADDRESS paAddress)
{
// expected_Address must be constrained to required usage boundary to prevent abuse
if(paAddress == expected_Address && qwSize == valid_Size)
{
lpAddress = MmMapIoSpace(paAddress, qwSize, ...);
pMdl = IoAllocateMdl( lpAddress, ...);
MmMapLockedPagesSpecifyCache(pMdl, UserMode, ... );
}
else
{
return error;
}
}
Ayrıca Bkz.
sürücü güvenlik denetim listesi