Aracılığıyla paylaş


Müşteri Kimliğine Bürünme

Kullanıcı uygulaması bir WMI sağlayıcısı aracılığıyla sistemdeki nesnelerden veri istediğinde, kimliğe bürünme, sağlayıcının sağlayıcının değil istemcinin güvenlik düzeyini temsil eden kimlik bilgilerini sunduğu anlamına gelir. Kimliğe bürünme, bir istemcinin sistemdeki bilgilere yetkisiz erişim elde etmesini engeller.

Bu konuda aşağıdaki bölümler ele alınmıştır:

WMI genellikle LocalServer güvenlik bağlamını kullanarak yüksek güvenlik düzeyinde bir yönetim hizmeti olarak çalışır. Yönetim hizmeti kullanmak, WMI'ye ayrıcalıklı bilgilere erişme araçları sağlar. Bilgi için bir sağlayıcıyı çağırırken WMI, sağlayıcıya güvenlik tanımlayıcısını (SID) geçirerek sağlayıcının aynı yüksek güvenlik düzeyindeki bilgilere erişmesini sağlar.

WMI uygulaması başlatma işlemi sırasında, Windows işletim sistemi WMI uygulamasına işlemi başlatan kullanıcının güvenlik bağlamını verir. Kullanıcının güvenlik bağlamı genellikle LocalServer'dan daha düşük bir güvenlik düzeyidir, bu nedenle kullanıcının WMI tarafından sağlanan tüm bilgilere erişme izni olmayabilir. Kullanıcı uygulaması dinamik bilgi istediğinde WMI, kullanıcının SID'sini ilgili sağlayıcıya geçirir. Uygun şekilde yazılırsa, sağlayıcı SID yerine kullanıcı SID'siyle bilgilere erişmeye çalışır.

Sağlayıcının istemci uygulamasının kimliğine başarıyla bürünebilmesi için istemci uygulamasının ve sağlayıcının aşağıdaki ölçütleri karşılaması gerekir:

Kimliğe Bürünme için Sağlayıcı Kaydetme

WMI, istemci uygulamasının SID'sini yalnızca kimliğe bürünme sağlayıcısı olarak kaydolan sağlayıcılara geçirir. Bir sağlayıcının kimliğe bürünme gerçekleştirmesini sağlamak için sağlayıcı kayıt işlemini değiştirmeniz gerekir.

Aşağıdaki yordamda bir sağlayıcının taklit için nasıl kaydedileceği açıklanmaktadır. Yordam, kayıt işlemini zaten anladığınızı varsayar. Kayıt işlemi hakkında daha fazla bilgi için bkz. Sağlayıcı kaydetme.

Kimliğe bürünme için sağlayıcı kaydetmek için

  1. Sağlayıcınızı temsil eden __Win32Provider sınıfının ImpersonationLevel özelliğini 1 olarak ayarlayın.

    ImpersonationLevel, sağlayıcının kimliğe bürünmeyi destekleyip desteklemediğini belgeleyen özelliğidir. ImpersonationLevel 0 olarak ayarlanması, sağlayıcının istemcinin kimliğine bürünmediğini ve tüm istenen işlemleri WMI ile aynı kullanıcı bağlamında gerçekleştirdiğini gösterir. ImpersonationLevel ayarının 1 olarak ayarlanması, sağlayıcının istemci adına gerçekleştirilen işlemleri kontrol etmek için kimliğe bürünme çağrıları kullandığını gösterir.

  2. Aynı __Win32Provider sınıfının PerUserInitialization özelliğini TRUE olarak ayarlayın.

Not

__Win32Provider özelliği InitializeAsAdminFirst TRUEolarak ayarlanmış bir sağlayıcı kaydederseniz, sağlayıcı yalnızca başlatma aşamasında yönetim düzeyi iş parçacığı güvenlik belirtecini kullanır. CoImpersonateClient çağrısı başarısız olmasa da, sağlayıcı istemcinin değil WMI'nin güvenlik bağlamını kullanır.

 

Aşağıdaki kod örneği, bir sağlayıcının kimlik taklidi için nasıl kaydedileceğini göstermektedir.

instance of __Win32Provider
{
    CLSID = "{FD4F53E0-65DC-11d1-AB64-00C04FD9159E}";
    ImpersonationLevel = 1;
    Name = "MS_NT_EVENTLOG_PROVIDER";
    PerUserInitialization = TRUE;
};

Sağlayıcı İçinde Kimliğe Bürünme Düzeylerini Ayarlama

ImpersonationLevel1 olarak ayarlanmış __Win32Provider sınıf özelliğine sahip bir sağlayıcı kaydederseniz, WMI çeşitli istemcilerin kimliğine bürünmek için sağlayıcınızı çağırır. Bu çağrıları işlemek için, uygulamanızda CoImpersonateClient ve CoRevertToSelf COM işlevlerini, IWbemServices arabirimi aracılığıyla kullanın.

CoImpersonateClient işlevi, sunucunun çağrıyı yapan istemcinin kimliğine bürünmesini sağlar. coImpersonateClient çağrısını IWbemServicesuygulamanıza ekleyerek, sağlayıcınızın iş parçacığı belirtecini istemcinin iş parçacığı belirteciyle eşleştirmesine ve böylece istemcinin kimliğine bürünmesine olanak tanırsınız. CoImpersonateClientçağrısı yapmazsanız, sağlayıcınız kodu yönetici düzeyinde yürüterek olası bir güvenlik açığı oluşturur. Sağlayıcınızın geçici olarak yönetici olarak davranması veya erişim denetimini el ile gerçekleştirmesi gerekiyorsa CoRevertToSelfçağrısı yapın.

CoImpersonateClientaksine, CoRevertToSelf, iş parçacığı kimlik taklit düzeylerini işleyen bir COM işlevidir. Bu durumda, CoRevertToSelf kimliğe bürünme düzeyini özgün kimliğe bürünme ayarına geri değiştirir. Genel olarak, sağlayıcı başlangıçta bir yöneticidir ve çağıranı veya kendi çağrılarını temsil eden bir çağrı yapıp yapmadığına bağlı olarak CoImpersonateClient ile CoRevertToSelf arasında geçiş yapıyor. Son kullanıcıya bir güvenlik deliği sunmamak için bu çağrıları doğru bir şekilde yerleştirmek sağlayıcının sorumluluğundadır. Örneğin, sağlayıcının yalnızca kimliğine bürünülen kod dizisinde yerel Windows işlevlerini çağırması gerekir.

Not

CoImpersonateClient ve CoRevertToSelf 'ın amacı, bir sağlayıcı için güvenlik ayarlamaktır. Kimliğe bürünmenizin başarısız olduğunu belirlerseniz, IWbemObjectSink::SetStatusaracılığıyla WMI'ye uygun bir tamamlama kodu döndürmelisiniz. Daha fazla bilgi için bkz. Sağlayıcıda Erişim Reddedilen İletileri İşleme.

 

Sağlayıcıda Güvenlik Düzeylerini Koruma

Sağlayıcılar, IWbemServices uygulamasında CoImpersonateClient bir kez çağıramaz ve sağlayıcı süresi boyunca kimliğe bürünme kimlik bilgilerinin yerinde kaldığını varsayar. Bunun yerine, WMI'nin kimlik bilgilerini değiştirmesini durdurmak için uygulama sırasında CoImpersonateClient birden çok kez çağırın.

Sağlayıcı için kimliğe bürünme ayarlamalarıyla ilgili en önemli konu yeniden giriş yapılabilirliktir. Bu bağlamda yeniden girişim, sağlayıcının bilgi için WMI'yi araması ve WMI'nin sağlayıcıyı geri aramasını beklemesidir. Özünde, yürütme iş parçacığı sağlayıcı kodundan çıkar ve daha sonra yeniden koda girer. Reentry, COM tasarımının bir parçasıdır ve genellikle bir sorun değildir. Ancak, yürütme iş parçacığı WMI'ye girdiğinde, iş parçacığı WMI'nin kimliğe bürünme düzeylerini alır. İş parçacığı sağlayıcıya geri döndüğünde, CoImpersonateClientiçin başka bir çağrıyla kimliğe bürünme düzeylerini sıfırlamanız gerekir.

Sağlayıcınızdaki güvenlik açıklarından korunmak için, yalnızca istemcinin kimliğine bürünerken WMI'ye yeniden giriş çağrıları yapmanız gerekir. Başka bir ifadeyle, WMI çağrısı, CoImpersonateClient'ü çağırdıktan sonra ve CoRevertToSelfçağrısı yapılmadan önce gerçekleştirilmelidir. CoRevertToSelf, kimliğe bürünme özelliğinin, WMI'nin çalıştığı kullanıcı düzeyine ayarlanmasına neden olur. Genellikle bu düzey LocalSystem'dir. CoRevertToSelf çağrıldıktan sonra WMI'ye yapılan yeniden girişimler, kullanıcıya ve çağrılan tüm sağlayıcılara sahip olmaları gerekenden çok daha fazla yetenek verebilir.

Not

Bir sistem işlevini veya başka bir arabirim yöntemini çağırırsanız, çağrı bağlamı korunacağı garanti edilmez.

 

Sağlayıcıda Erişim Reddedilen İletileri İşleme

Çoğu Erişim Reddedildi hata iletisi, istemci erişimi olmayan bir sınıf veya bilgi istediğinde görüntülenir. Sağlayıcı WMI'ye Erişim Reddedildi hata iletisi döndürürse ve WMI bunu istemciye geçirirse, istemci bilgilerin mevcut olduğunu çıkarsayabilir. Bazı durumlarda bu bir güvenlik ihlali olabilir. Bu nedenle, sağlayıcınız iletiyi istemciye yaymamalıdır. Bunun yerine, sağlayıcının sağladığı sınıf kümesinin kullanıma sunulmaması gerekir. Benzer şekilde, bir dinamik örnek sağlayıcısı, Erişim Reddedildi iletileriyle nasıl başa çıkılması gerektiğini belirlemek için temel alınan veri kaynağına çağrı yapmalıdır. Bu felsefeyi WMI ortamına çoğaltmak sağlayıcının sorumluluğundadır. Daha fazla bilgi için bkz. Kısmi Örnekleri Raporlama ve Kısmi Numaralandırmaları Raporlama.

Sağlayıcınızın Erişim Reddedildi iletilerini nasıl işlemesi gerektiğini saptadığınızda, kodunuzu yazmanız ve hatalarını ayıklamanız gerekir. Hata ayıklama sırasında, genellikle düşük kimlik taklidi nedeniyle bir reddetme ile kodunuzdaki bir hata nedeniyle bir reddetme arasında ayrım yapmak kolay olur. Farkı belirlemek için kodunuzda basit bir test kullanabilirsiniz. Daha fazla bilgi için bkz. Erişim Reddedilen Kodunuzda Hata Ayıklama.

Kısmi Örnekleri Raporlama

Erişim Reddedildi iletisinin yaygın olarak karşılaşılan örneklerden biri, WMI'nin bir örneği doldurmak için tüm bilgileri sağlayamamasıdır. Örneğin, bir istemci sabit disk sürücüsü nesnesini görüntüleme yetkisine sahip olabilir, ancak sabit disk sürücüsünde ne kadar alan olduğunu görme yetkisine sahip olmayabilir. Sağlayıcınız, erişim ihlali nedeniyle bir örneği özelliklerle tamamen dolduramadığı durumlarda meydana gelen durumları nasıl yönetmesi gerektiğini belirlemelidir.

WMI, bir örneğe kısmi erişimi olan istemcilere tek bir yanıt gerektirmez. Bunun yerine WMI sürüm 1.x, sağlayıcıya aşağıdaki seçeneklerden birini sağlar:

  • Tüm işlemi WBEM_E_ACCESS_DENIED ile başarısız kılın ve hiçbir örnek döndürülmemeli.

    Reddetmenin nedenini açıklamak için WBEM_E_ACCESS_DENIEDile birlikte bir hata nesnesi döndürür.

  • Kullanılabilir tüm özellikleri döndür ve kullanılamayan özellikleri NULLile doldurun.

Not

WBEM_E_ACCESS_DENIED döndürmenin kuruluşunuzda bir güvenlik açığı oluşturmadığından emin olun.

 

Kısmi Sayımları Raporlama

Erişim ihlalinin bir diğer yaygın örneği de WMI'nin bir numaralandırmanın tümünü döndürememesidir. Örneğin, istemcinin tüm yerel ağ bilgisayar nesnelerini görüntüleme erişimi olabilir, ancak etki alanı dışındaki bilgisayar nesnelerini görüntüleme erişimi olmayabilir. Bir erişim ihlali nedeniyle numaralandırma tamamlanamadığında sağlayıcınızın herhangi bir durumun nasıl işleneceğini belirlemesi gerekir.

Örnek sağlayıcı sınıfında olduğu gibi, WMI kısmi bir listeleme için tek bir yanıt gerektirmez. Bunun yerine WMI sürüm 1.x, sağlayıcıya aşağıdaki seçeneklerden birini sağlar:

  • Sağlayıcının erişebileceği tüm örnekler için WBEM_S_NO_ERROR döndürü.

    Bu seçeneği kullanırsanız, kullanıcı bazı örneklerin kullanılabilir olmadığının farkında değildir. Satır düzeyi güvenlikle Yapılandırılmış Sorgu Dili (SQL) kullanan sağlayıcılar gibi bir dizi sağlayıcı, sonuç kümesini tanımlamak için çağıranın güvenlik düzeyini kullanarak başarılı kısmi sonuçlar döndürür.

  • tüm işlem WBEM_E_ACCESS_DENIED ile başarısız sayılmalı ve örnek döndürülmesin.

    Sağlayıcı isteğe bağlı olarak istemciye durumu açıklayan bir hata nesnesi içerebilir. Bazı sağlayıcıların veri kaynaklarına seri olarak erişebileceğini ve numaralandırmadan geçene kadar reddetmelerle karşılaşmayabileceğini unutmayın.

  • Erişilebilen tüm örnekleri döndürün, ancak aynı zamanda hata olmayan durum kodu WBEM_S_ACCESS_DENIEDkodunu da döndürün.

    Sağlayıcı, numaralandırma sırasında red durumunu not almalıdır ve hata olmayan durum kodu ile işlemi tamamlayarak örnekler sağlamaya devam edebilir. Sağlayıcı ayrıca ilk reddetmede numaralandırmayı sonlandırmayı seçebilir. Bu seçeneğin gerekçesi, farklı sağlayıcıların farklı alma paradigmalarına sahip olmasıdır. Bir sağlayıcı erişim ihlalini bulmadan önce örnekleri zaten teslim etmiş olabilir. Bazı sağlayıcılar diğer örnekleri sağlamaya devam edebilir ve diğerleri sonlandırmak isteyebilir.

COM'un yapısı nedeniyle, hata nesnesi dışında bir hata sırasında hiçbir bilgiyi geri sıralayamazsınız. Bu nedenle, hem bilgileri hem de hata kodunu döndüremezsiniz. Bilgi döndürmeyi seçerseniz, bunun yerine bir hata içermeyen durum kodu kullanmanız gerekir.

Erişim Reddedilen Kodunuzda Hata Ayıklama

RPC_C_IMP_LEVEL_IMPERSONATEdüzeyinden daha düşük kimliğe bürünme düzeyleri bazı uygulamalar tarafından kullanılabilir. Bu durumda, istemci uygulaması için sağlayıcı tarafından yapılan kimliğe bürünme çağrılarının çoğu başarısız olur. Bir sağlayıcıyı başarıyla tasarlamak ve uygulamak için bu fikri aklınızda bulundurmanız gerekir.

Varsayılan olarak, bir sağlayıcıya erişebilen tek başka kimlik taklidi düzeyi RPC_C_IMP_LEVEL_IDENTIFY. İstemci uygulamasının RPC_C_IMP_LEVEL_IDENTIFYkullandığı durumlarda CoImpersonateClient bir hata kodu döndürmez. Bunun yerine, sağlayıcı yalnızca tanımlama amacıyla istemcinin kimliğine bürüner. Bu nedenle, sağlayıcı tarafından çağrılan çoğu Windows yöntemi erişim reddedildi iletisi döndürür. Bu, kullanıcıların uygunsuz bir şey yapmalarına izin verilmeyeceği için pratikte zararsızdır. Ancak, sağlayıcı geliştirme sırasında istemcinin kimliğine gerçekten bürünülmüş olup olmadığını bilmek yararlı olabilir.

Kodun doğru şekilde derlenebilmesi için aşağıdaki referanslar ve #include deyimleri gerekir.

#define _WIN32_DCOM
#include <iostream>
using namespace std;
#include <wbemidl.h>

Aşağıdaki kod örneği, bir sağlayıcının bir istemci uygulamasının kimliğine başarıyla bürünmüş olup olmadığının nasıl belirleneceğini gösterir.

DWORD dwImp = 0;
HANDLE hThreadTok;
DWORD dwBytesReturned;
BOOL bRes;

// You must call this before trying to open a thread token!
CoImpersonateClient();

bRes = OpenThreadToken(
    GetCurrentThread(),
    TOKEN_QUERY,
    TRUE,
    &hThreadTok
);

if (bRes == FALSE)
{
    printf("Unable to read thread token (%d)\n", GetLastError());
    return 0;
}

bRes = GetTokenInformation(
    hThreadTok,
    TokenImpersonationLevel, 
    &dwImp,
    sizeof(DWORD),
    &dwBytesReturned
);

if (!bRes)
{
    printf("Unable to read impersonation level\n");
    CloseHandle(hThreadTok);
    return 0;
}

switch (dwImp)
{
case SecurityAnonymous:
    printf("SecurityAnonymous\n");
    break;

case SecurityIdentification:
    printf("SecurityIdentification\n");
    break;

case SecurityImpersonation:
    printf("SecurityImpersonation\n");
    break;

case SecurityDelegation:
    printf("SecurityDelegation\n");
    break;

default:
    printf("Error. Unable to determine impersonation level\n");
    break;
}

CloseHandle(hThreadTok);

WMI Sağlayıcısı geliştirme

Ad Alanı Güvenlik Tanımlayıcılarını Ayarlama

Sağlayıcınızın Güvenliğini