Bagikan melalui


Moniker Elevasi COM

Moniker elevasi COM memungkinkan aplikasi yang berjalan di bawah kontrol akun pengguna (UAC) untuk mengaktifkan kelas COM dengan hak istimewa yang ditinggikan. Untuk informasi selengkapnya, lihat Fokus pada Hak Istimewa Terkecil.

Kapan Menggunakan Moniker Elevasi

Moniker elevasi digunakan untuk mengaktifkan kelas COM untuk mencapai fungsi tertentu dan terbatas yang memerlukan hak istimewa yang ditinggikan, seperti mengubah tanggal dan waktu sistem.

Elevasi memerlukan partisipasi dari kelas COM dan kliennya. Kelas COM harus dikonfigurasi untuk mendukung elevasi dengan menganotasi entri registrinya, seperti yang dijelaskan di bagian Persyaratan. Klien COM harus meminta elevasi dengan menggunakan moniker elevasi.

Moniker elevasi tidak dimaksudkan untuk memberikan kompatibilitas aplikasi. Misalnya, jika Anda ingin menjalankan aplikasi COM warisan seperti WinWord sebagai server yang ditinggikan, Anda harus mengonfigurasi klien COM yang dapat dieksekusi untuk memerlukan elevasi, daripada mengaktifkan kelas aplikasi warisan dengan moniker elevasi. Ketika klien COM yang ditingkatkan memanggil CoCreateInstance menggunakan CLSID aplikasi warisan , status klien yang ditingkatkan akan mengalir ke proses server.

Tidak semua fungsionalitas COM kompatibel dengan elevasi. Fungsionalitas yang tidak akan berfungsi meliputi:

  • Elevasi tidak mengalir dari klien ke server COM jarak jauh. Jika klien mengaktifkan server COM jarak jauh dengan moniker elevasi, server tidak akan ditinggikan, bahkan jika mendukung elevasi.
  • Jika kelas COM yang ditinggikan menggunakan peniruan selama panggilan COM, kelas tersebut mungkin kehilangan hak istimewa yang ditinggikan selama peniruan.
  • Jika server COM yang ditinggikan mendaftarkan kelas dalam tabel objek yang sedang berjalan (ROT), kelas tidak akan tersedia untuk klien yang tidak ditinggikan.
  • Proses yang ditinggikan dengan menggunakan mekanisme UAC tidak memuat kelas per pengguna selama aktivasi COM. Untuk aplikasi COM, ini berarti bahwa kelas COM aplikasi harus diinstal di sarang registri HKEY_LOCAL_MACHINE jika aplikasi akan digunakan oleh akun yang tidak istimewa dan istimewa. Kelas COM aplikasi hanya perlu diinstal di sarang HKEY_USERS jika aplikasi tidak pernah digunakan oleh akun istimewa.
  • Seret dan letakkan tidak diizinkan dari aplikasi yang tidak ditingkatkan ke yang ditingkatkan.

Persyaratan

Untuk menggunakan moniker elevasi untuk mengaktifkan kelas COM, kelas harus dikonfigurasi untuk berjalan sebagai pengguna peluncuran atau identitas aplikasi 'Aktifkan sebagai Aktivator'. Jika kelas dikonfigurasi untuk berjalan di bawah identitas lain, aktivasi mengembalikan kesalahan CO_E_RUNAS_VALUE_MUST_BE_AAA.

Kelas juga harus diannotasi dengan nama tampilan "ramah" yang kompatibel dengan antarmuka pengguna multibahasa (MUI). Ini memerlukan entri registri berikut:

HKEY_LOCAL_MACHINE\Software\Classes\CLSID
   {CLSID}
      LocalizedString = displayName

Jika entri ini hilang, aktivasi mengembalikan kesalahan CO_E_MISSING_DISPLAYNAME. Jika file MUI hilang, kode kesalahan dari fungsi RegLoadMUIStringW dikembalikan.

Secara opsional, untuk menentukan ikon aplikasi yang akan ditampilkan oleh antarmuka pengguna UAC, tambahkan kunci registri berikut:

HKEY_LOCAL_MACHINE\Software\Classes\CLSID
   {CLSID}
      Elevation
         IconReference = applicationIcon

IconReference menggunakan format yang sama dengan LocalizedString:

@pathtobinary,-resourcenumber

Selain itu, komponen COM harus ditandatangani agar ikon ditampilkan.

Kelas COM juga harus diannotasi sebagai LUA-Enabled. Ini memerlukan entri registri berikut:

HKEY_LOCAL_MACHINE\Software\Classes\CLSID
   {CLSID}
      Elevation
         Enabled = 1

Jika entri ini hilang, maka aktivasi mengembalikan kesalahan CO_E_ELEVATION_DISABLED.

Perhatikan bahwa entri ini harus ada di sarang HKEY_LOCAL_MACHINE, bukan sarang HKEY_CURRENT_USER atau HKEY_USERS. Ini mencegah pengguna meningkatkan kelas COM yang mereka tidak juga memiliki hak istimewa untuk mendaftar.

Moniker Elevasi dan UI Elevasi

Jika klien sudah ditinggikan, menggunakan moniker elevasi tidak akan menyebabkan UI Elevasi ditampilkan.

Cara Menggunakan Moniker Elevasi

Moniker elevasi adalah moniker COM standar, mirip dengan moniker sesi, partisi, atau antrean. Ini mengarahkan permintaan aktivasi ke server tertentu dengan tingkat elevasi yang ditentukan. CLSID yang akan diaktifkan muncul dalam string moniker.

Moniker elevasi mendukung token Tingkat Eksekusi berikut:

  1. Administrator
  2. Tertinggi

Sintaks untuk ini adalah sebagai berikut:

Elevation:Administrator!new:{guid}
Elevation:Highest!new:{guid}

Sintaks sebelumnya menggunakan moniker "baru" untuk mengembalikan instans kelas COM yang ditentukan oleh guid. Perhatikan bahwa moniker "baru" secara internal menggunakan antarmuka IClassFactory untuk mendapatkan objek kelas dan kemudian memanggil IClassFactory::CreateInstance di atasnya.

Moniker elevasi juga dapat digunakan untuk mendapatkan objek kelas, yang mengimplementasikan IClassFactory. Pemanggil kemudian memanggil CreateInstance untuk mendapatkan instans objek. Sintaks untuk ini adalah sebagai berikut:

Elevation:Administrator!clsid:{guid}

Kode Sampel

Contoh kode berikut menunjukkan cara menggunakan moniker elevasi. Ini mengasumsikan bahwa Anda telah menginisialisasi COM pada utas saat ini.

HRESULT CoCreateInstanceAsAdmin(HWND hwnd, REFCLSID rclsid, REFIID riid, __out void ** ppv)
{
    BIND_OPTS3 bo;
    WCHAR  wszCLSID[50];
    WCHAR  wszMonikerName[300];

    StringFromGUID2(rclsid, wszCLSID, sizeof(wszCLSID)/sizeof(wszCLSID[0])); 
    HRESULT hr = StringCchPrintf(wszMonikerName, sizeof(wszMonikerName)/sizeof(wszMonikerName[0]), L"Elevation:Administrator!new:%s", wszCLSID);
    if (FAILED(hr))
        return hr;
    memset(&bo, 0, sizeof(bo));
    bo.cbStruct = sizeof(bo);
    bo.hwnd = hwnd;
    bo.dwClassContext  = CLSCTX_LOCAL_SERVER;
    return CoGetObject(wszMonikerName, &bo, riid, ppv);
}

BIND_OPTS3 baru di Windows Vista. Ini berasal dari BIND_OPTS2.

Satu-satunya penambahan adalah bidang HWND , hwnd. Handel ini mewakili jendela yang menjadi pemilik UI Elevasi, jika berlaku.

Jika hwnd NULL, COM akan memanggil GetActiveWindow untuk menemukan handel jendela yang terkait dengan utas saat ini. Kasus ini mungkin terjadi jika klien adalah skrip, yang tidak dapat mengisi struktur BIND_OPTS3. Dalam hal ini, COM akan mencoba menggunakan jendela yang terkait dengan utas skrip.

Elevasi Over-the-Shoulder (OTS)

Elevasi over-the-shoulder (OTS) mengacu pada skenario di mana klien menjalankan server COM dengan kredensial administrator daripada miliknya sendiri. (Istilah "over the shoulder" berarti bahwa administrator mengawasi bahu klien saat klien menjalankan server.)

Skenario ini dapat menyebabkan masalah untuk panggilan COM ke server, karena server mungkin tidak memanggil CoInitializeSecurity baik secara eksplisit (yaitu, secara terprogram) atau implisit (yaitu, secara deklaratif, menggunakan registri). Untuk server tersebut, COM menghitung deskriptor keamanan yang hanya memungkinkan SELF, SYSTEM, dan Builtin\Administrators untuk melakukan panggilan COM ke server. Pengaturan ini tidak akan berfungsi dalam skenario OTS. Sebagai gantinya, server harus memanggil CoInitializeSecurity, baik secara eksplisit atau implisit, dan menentukan ACL yang mencakup SID dan SISTEM grup INTERAKTIF.

Contoh kode berikut menunjukkan cara membuat deskriptor keamanan (SD) dengan SID grup INTERAKTIF.

BOOL GetAccessPermissionsForLUAServer(SECURITY_DESCRIPTOR **ppSD)
{
// Local call permissions to IU, SY
    LPWSTR lpszSDDL = L"O:BAG:BAD:(A;;0x3;;;IU)(A;;0x3;;;SY)";
    SECURITY_DESCRIPTOR *pSD;
    *ppSD = NULL;

    if (ConvertStringSecurityDescriptorToSecurityDescriptorW(lpszSDDL, SDDL_REVISION_1, (PSECURITY_DESCRIPTOR *)&pSD, NULL))
    {
        *ppSD = pSD;
        return TRUE;
    }

    return FALSE;
}

Contoh kode berikut menunjukkan cara memanggil CoInitializeSecurity secara implisit dengan SD dari contoh kode sebelumnya:

// hKey is the HKCR\AppID\{GUID} key
BOOL SetAccessPermissions(HKEY hkey, PSECURITY_DESCRIPTOR pSD)
{
    BOOL bResult = FALSE;
    DWORD dwLen = GetSecurityDescriptorLength(pSD);
    LONG lResult;
    lResult = RegSetValueExA(hkey, 
        "AccessPermission",
        0,
        REG_BINARY,
        (BYTE*)pSD,
        dwLen);
    if (lResult != ERROR_SUCCESS) goto done;
    bResult = TRUE;
done:
    return bResult;
}

Contoh kode berikut menunjukkan cara memanggil CoInitializeSecurity secara eksplisit dengan SD di atas:

// Absolute SD values
PSECURITY_DESCRIPTOR pAbsSD = NULL;
DWORD AbsSdSize = 0;
PACL  pAbsAcl = NULL;
DWORD AbsAclSize = 0;
PACL  pAbsSacl = NULL;
DWORD AbsSaclSize = 0;
PSID  pAbsOwner = NULL;
DWORD AbsOwnerSize = 0;
PSID  pAbsGroup = NULL;
DWORD AbsGroupSize = 0;

MakeAbsoluteSD (
    pSD,
    pAbsSD,
    &AbsSdSize,
    pAbsAcl,
    &AbsAclSize,
    pAbsSacl,
    &AbsSaclSize,
    pAbsOwner,
    &AbsOwnerSize,
    pAbsGroup,
    &AbsGroupSize
);

if (ERROR_INSUFFICIENT_BUFFER == GetLastError())
{
    pAbsSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LMEM_FIXED, AbsSdSize);
    pAbsAcl = (PACL)LocalAlloc(LMEM_FIXED, AbsAclSize);
    pAbsSacl = (PACL)LocalAlloc(LMEM_FIXED, AbsSaclSize);
    pAbsOwner = (PSID)LocalAlloc(LMEM_FIXED, AbsOwnerSize);
    pAbsGroup = (PSID)LocalAlloc(LMEM_FIXED, AbsGroupSize);

    if ( ! (pAbsSD && pAbsAcl && pAbsSacl && pAbsOwner && pAbsGroup))
    {
        hr = E_OUTOFMEMORY;
        goto Cleanup;
    }
    if ( ! MakeAbsoluteSD(
        pSD,
        pAbsSD,
        &AbsSdSize,
        pAbsAcl,
        &AbsAclSize,
        pAbsSacl,
        &AbsSaclSize,
        pAbsOwner,
        &AbsOwnerSize,
        pAbsGroup,
        &AbsGroupSize
        ))
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto Cleanup;
    }
}
else
{
    hr = HRESULT_FROM_WIN32(GetLastError());
    goto Cleanup;
}

// Call CoInitializeSecurity .

Izin COM dan Label Akses Wajib

Windows Vista memperkenalkan gagasan label akses wajib dalam deskriptor keamanan. Label menentukan apakah klien bisa mendapatkan akses eksekusi ke objek COM. Label ditentukan dalam bagian daftar kontrol akses sistem (SACL) dari deskriptor keamanan. Di Windows Vista, COM mendukung label SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP. SACL dalam izin COM diabaikan pada sistem operasi sebelum Windows Vista.

Pada Windows Vista, dcomcnfg.exe tidak mendukung perubahan tingkat integritas (IL) dalam izin COM. Ini harus diatur secara terprogram.

Contoh kode berikut menunjukkan cara membuat deskriptor keamanan COM dengan label yang memungkinkan permintaan peluncuran/aktivasi dari semua klien LOW IL. Perhatikan bahwa label valid untuk izin Luncurkan/Aktivasi dan Panggilan. Dengan demikian, dimungkinkan untuk menulis server COM yang melarang peluncuran, aktivasi, atau panggilan dari klien dengan IL tertentu. Untuk informasi selengkapnya tentang tingkat integritas, lihat bagian "Memahami Mekanisme Integritas Windows Vista" dalam Memahami dan Bekerja dalam Mode Terlindungi Internet Explorer.

BOOL GetLaunchActPermissionsWithIL (SECURITY_DESCRIPTOR **ppSD)
{
// Allow World Local Launch/Activation permissions. Label the SD for LOW IL Execute UP
    LPWSTR lpszSDDL = L"O:BAG:BAD:(A;;0xb;;;WD)S:(ML;;NX;;;LW)";
    if (ConvertStringSecurityDescriptorToSecurityDescriptorW(lpszSDDL, SDDL_REVISION_1, (PSECURITY_DESCRIPTOR *)&pSD, NULL))
    {
        *ppSD = pSD;
        return TRUE;
    }
}

BOOL SetLaunchActPermissions(HKEY hkey, PSECURITY_DESCRIPTOR pSD)
{
    
    BOOL bResult = FALSE;
    DWORD dwLen = GetSecurityDescriptorLength(pSD);
    LONG lResult;
    lResult = RegSetValueExA(hkey, 
        "LaunchPermission",
        0,
        REG_BINARY,
        (BYTE*)pSD,
        dwLen);
    if (lResult != ERROR_SUCCESS) goto done;
    bResult = TRUE;
done:
    return bResult;
};

Tingkat CoCreateInstance dan Integritas

Perilaku CoCreateInstance telah berubah di Windows Vista, untuk mencegah klien Low IL mengikat ke server COM secara default. Server harus secara eksplisit mengizinkan pengikatan tersebut dengan menentukan SACL. Perubahan pada CoCreateInstance adalah sebagai berikut:

  1. Saat meluncurkan proses server COM, IL dalam token proses server diatur ke KLIEN atau IL token server, mana pun yang lebih rendah.
  2. Secara default, COM akan mencegah klien Low IL mengikat ke menjalankan instans server COM apa pun. Untuk mengizinkan pengikatan, deskriptor keamanan Peluncuran/Aktivasi server COM harus berisi SACL yang menentukan label LOW IL (lihat bagian sebelumnya untuk kode sampel untuk membuat deskriptor keamanan seperti itu).

Server yang Ditinggikan dan Pendaftaran ROT

Jika server COM ingin mendaftar di tabel objek yang sedang berjalan (ROT) dan mengizinkan klien mana pun untuk mengakses pendaftaran, server harus menggunakan bendera ROTFLAGS_ALLOWANYCLIENT. Server COM "Aktifkan Sebagai Pengaktif" tidak dapat menentukan ROTFLAGS_ALLOWANYCLIENT karena manajer kontrol layanan DCOM (DCOMSCM) memberlakukan pemeriksaan spoof terhadap bendera ini. Oleh karena itu, di Windows Vista, COM menambahkan dukungan untuk entri registri baru yang memungkinkan server untuk menetapkan bahwa pendaftaran ROT-nya tersedia untuk klien apa pun:

HKEY_LOCAL_MACHINE\Software\Classes\AppID
   {APPID}
      ROTFlags

Satu-satunya nilai yang valid untuk entri REG_DWORD ini adalah:

ROTREGFLAGS_ALLOWANYCLIENT 0x1

Entri harus ada di sarang HKEY_LOCAL_MACHINE .

Entri ini menyediakan server "Aktifkan Sebagai Aktivator" dengan fungsionalitas yang sama dengan yang ROTFLAGS_ALLOWANYCLIENT sediakan untuk server RunAs.

Keamanan di COM

Memahami dan Bekerja dalam Mode Terproteksi Internet Explorer