デバイス オブジェクトのセキュリティ
久方ぶりです。まさかたです。
今回は、デバイスにアクセスする際のセキュリティに深く関係のある、デバイスオブジェクトのセキュリティについてお話ししたいと思います。
まず、アプリケーションが、デバイスに対して I/O のリクエストをする場合、入り口として CreateFile() でデバイスハンドルを取得し、このハンドルを通して ReadFile() や WriteFile(), DeviceIoControl() などでリクエストを行います。このようなデバイスハンドルの取得や、I/O のリクエストの実行は、セキュリティの観点から、どんなユーザーからでも実行できては困りますので、一定の制限を設ける必要があります。
以前、A 寿さんの記事の中で、I/O コントロールの発行に必要なデバイス ハンドルのアクセス権限についてのお話がありましたが、それもこのようなセキュリティを保つための仕組みの一つだと思います。
通常は、デバイスへのアクセスは管理者権限を必要とする場合が多いのですが、お客様によっては、管理者権限以外でもアクセスできるようにしたいなど、このセキュリティをコントロールする方法についてお問い合わせいただくことがあります。
そこで、これに関連するお話として、ユーザーによって、CreateFile() の実行可否や、設定可能なアクセス権限などをコントロールすることができる、デバイスオブジェクトのセキュリティについてお話をしたいと思います。
セキュリティのチェックを行うためには、どのユーザーが、どのデバイスオブジェクトに対して、どんなアクセス権限を持っているのかといったことを識別し、判断する必要がありますが、そのための情報として、アクセストークン、や Security Descriptorと呼ばれるものがあります。それぞれの詳細は、こちらのページを見ていただければと思いますが、大まかには以下のようになると思います。
|
デバイスにアクセスしようとした時に、ユーザーの権限や、デバイスオブジェクトのアクセスに必要な権限を表すのは、これらの情報になります。そして、CreateFile() でデバイス オブジェクトのオープンを行おうとした場合、Windows では以下のような流れでリクエストの処理が行われており、その要所でセキュリティチェックが行われています。
※「Windows セキュリティ モデル : ドライバー作成者向け情報」から抜粋
図 2. CreateFile 要求の処理 図 2 は、ユーザー モードのアプリケーションが CreateFile 関数を呼び出すときのシステムの応答方法を示しています。下記の説明は、図中の丸で囲まれた数字に対応しています。
|
この中で、特にドライバー自身がチェックを行うのは ⑨ になります。ただ、前述の Access Token や Security Descriptor に基づいたチェックは、⑦ の I/O マネージャーが行っています。
デバイス オブジェクトそのものに設定するという点では、前述の Security Descriptorの記述が、デバイス オブジェクトをセキュリティで保護するための直接的な方法です。これ以外にも、デバイスオブジェクトをセキュリティで保護するためにドライバー側でできることには、デバイスの名前空間の保護や、デバイスオープンの排他制御といったものがありますが、今回は、Security Descriptor の設定について、ご紹介したいと思います。
デバイスオブジェクトへのSecurity Descriptor の設定方法
デバイス オブジェクトに Security Descriptor を設定・変更する方法には、主に以下の 3 つを使った方法があります。
(1) INF
(2) IoCreateDeviceSecure 関数
(3) SetupDiSetDeviceRegistryProperty 関数
以下では、それぞれについて WDK の Toaster サンプルや DevCon サンプルを使った例を交えながら、紹介したいと思います。
(1) INF
INFに特定の記述を行うことで、デバイスオブジェクトに設定する Security Descriptor を制御できます。また、その方法は、(ア) デバイス セットアップ クラスの既定の設定を利用する方法と、(イ) SDDL で独自に指定する方法の 2 つがあります。(ア) は、既定ではセットアップクラスに属するデバイスすべてに適用されるものですが、(イ) の設定はクラスではなく個々のデバイスに対して適用されるもので、設定した場合には、(ア) の設定より優先されます。
(ア) デバイス セットアップ クラスの既定の設定を利用
INF の Version セクション内では、Class エントリや ClassGuid エントリでデバイスが属するデバイス セットアップ クラスを指定することができますが、既存のセットアップクラスは、既定の Security Descriptor を持っています。そのため、INF の中で既存のセットアップクラスに属するよう設定し、(イ) の設定を行わなければ、セットアップクラスの既定の Security Descriptor が適用されることになります。
なお、この既存のセットアップクラスの一部が持っている独自の Security Descriptor に関して、技術情報としてまとまったものは公開されていないようです。ただ、SetupDiGetClassProperty 関数を使用することで、セットアップクラス毎の Security Descriptor に関する情報を取得できます。具体的には、関数の引数に指定するプロパティのフラグとして、DEVPKEY_DeviceClass_Security や DEVPKEY_DeviceClass_SecuritySDS を指定すれば、セットアップクラスの Security Descriptor の情報を取得できます。
例えば、WDK サンプルの devcon の classes オプションの処理 cmdClasses 関数に実装を追加して、SetupDiGetClassProperty 関数で、DEVPKEY_DeviceClass_SecuritySDS を指定し、各セットアップクラスの Security Descriptor の SDDL を取得できるようにしてみました。
// devcon サンプル cmds.cpp 112 行目付近 int cmdClasses(__in LPCTSTR BaseName, __in LPCTSTR Machine, __in DWORD Flags, __in int argc, __in_ecount(argc) TCHAR* argv[]) …(中略)… for(index=0;index<numGuids;index++) { // 162 行目付近 …(中略)… TCHAR propBuff[LINE_LEN]; DEVPROPTYPE devPropType; if(!SetupDiGetClassProperty(&guids[index], &DEVPKEY_DeviceClass_SecuritySDS, &devPropType, (PBYTE)propBuff, LINE_LEN, NULL, DICLASSPROP_INSTALLER)) { if (FAILED(StringCchCopy(propBuff,LINE_LEN,TEXT("Default")))) { goto final; } } _tprintf(TEXT("%-20s: %s\n"),className,propBuff);
試しに、私の手元の Windows 7 SP1 の環境で実行してみた結果が以下です。事前に、サンプルの Toaster function driver をインストールしてあります。(SetupDiGetClassProperty 関数の戻り値が False の場合には、Default と出力しています。)
Listing 58 setup classes.
WCEUSBS : Default
USB : Default
Media Center Extender: Default
PnpPrinters : Default
Dot4 : Default
Dot4Print : Default
CDROM : Default
Computer : Default
DiskDrive : Default
Display : D:P(A;;GA;;;SY)
fdc : Default
hdc : D:P(A;;0x101f01ff;;;SY)(A;;0x101f01ff;;;BA)
Keyboard : Default
MEDIA : Default
Modem : Default
Monitor : Default
Mouse : Default
MTD : Default
MultiFunction : Default
Net : Default
NetClient : Default
NetService : Default
NetTrans : D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;NS)(A;;GA;;;LS)(A;;GXGR;;;AU)
PCMCIA : Default
Ports : Default
Printer : Default
SCSIAdapter : D:P(A;;0x101f01ff;;;SY)(A;;0x101f01ff;;;BA)
System : Default
Unknown : Default
FloppyDisk : Default
Processor : Default
MultiPortSerial : Default
Memory : Default
SmartCardReader : Default
Sensor : Default
VolumeSnapshot : Default
BiometricDevice : Default
1394 : D:P(A;;GA;;;SY)(A;;GA;;;BA)
Infrared : Default
Image : Default
TapeDrive : D:P(A;;0x101f01ff;;;SY)(A;;0x101f01ff;;;BA)(A;;0x101f01ff;;;BO)
Volume : Default
Battery : Default
HIDClass : Default
61883 : Default
LegacyDriver : Default
SmartCard : Default
SideShow : Default
SDHost : Default
TOASTER : D:P(A;;GA;;;SY)(A;;GA;;;BA)
Transfer Cable : Default
AVC : Default
MediumChanger : D:P(A;;0x101f01ff;;;SY)(A;;0x101f01ff;;;BA)(A;;0x101f01ff;;;BO)
SBP2 : Default
XnaComposite : Default
SecurityDevices : Default
SmartCardFilter : Default
Bluetooth : Default
WPD : DefaultToaster クラスを含め、ところどころ、独自の Security Descriptor を設定しているクラスがありますが、多くは独自の設定はしていないことが分かります。その場合、多くのデバイスでは、Default の Security Descriptor として、Administrators に GENERIC_ALL、everyone に対して (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE) を付与しています。
ちなみに、独自のセットアップクラスを作成する場合、クラスインストーラーの INF の ClassInstall32 セクション内の AddReg ディレクティブで、クラスの Security Descriptor を指定できます。
例として、WDK の Toaster サンプルでは、独自の Toaster クラスを作成していますが、INF の中で独自の Security Descriptor を設定しており、前述の Toaster クラスの SDDL と一致しているのが分かります。
// toaster.inf より抜粋 [Version] Signature="$WINDOWS NT$" Class=TOASTER ClassGuid={B85B7C50-6A01-11d2-B841-00C04FAD5171} … (中略) … ; ================= Class section ===================== [ClassInstall32] Addreg=ToasterClassReg CopyFiles=ToasterClassInstallerCopyFiles [ToasterClassReg] HKR,,,0,%ClassName% HKR,,Icon,,100 HKR,,Installer32,,"tostrcls.dll,ToasterClassInstaller" HKR,,DeviceCharacteristics,0x10001,0x100 ;Use same security checks on relative opens HKR,,Security,,"D:P(A;;GA;;;SY)(A;;GA;;;BA)" ;Allow generic all access to system and built-in Admin. ;This one overrides the security set by the driver
(イ) SDDL で明示的に指定
クラスごとの設定ではなく、個々のデバイスに独自の Security Descriptor を設定したい場合には、INF の DDInstall.HW セクション、AddReg ディレクティブ で、Security のレジストリに SDDL を記述します。前述の通り、ここで設定した値は、デバイスセットアップ クラス のSecurity Descriptorの既定値よりも優先されます。
例として、Toaster サンプルの bus ドライバーの INF が参考になると思います。Toaster Bus ドライバーでは、クラスは System になっていますが、Security Descriptor は独自に設定を行っています。
// bus.inf より抜粋 [Version] Signature="$WINDOWS NT$" Class=System ClassGuid={4D36E97D-E325-11CE-BFC1-08002BE10318} … (中略) … [ToasterBus_Device.NT.HW] AddReg=ToasterBus_Device.NT.AddReg [ToasterBus_Device.NT.AddReg] HKR,,DeviceCharacteristics,0x10001,0x0100 ; Use same security checks on relative opens HKR,,Security,,"D:P(A;;GA;;;BA)(A;;GA;;;SY)" ; Allow generic-all access to Built-in administrators and Local system
(2) IoCreateDeviceSecure 関数
デバイス オブジェクトを作成するための関数として、IoCreateDevice 関数が使われますが、本関数には、Security Descriptor を指定できるような引数がありません。これに対して、IoCreateDeviceSecure 関数では、引数の中で、SDDL を記述することができるようになっています。
NTSTATUS IoCreateDeviceSecure( __in PDRIVER_OBJECT DriverObject, __in ULONG DeviceExtensionSize, __in_opt PUNICODE_STRING DeviceName, __in DEVICE_TYPE DeviceType, __in ULONG DeviceCharacteristics, __in BOOLEAN Exclusive, __in PCUNICODE_STRING DefaultSDDLString, __in_opt LPCGUID DeviceClassGuid, __out PDEVICE_OBJECT *DeviceObject ); |
ただし、IoCreateDeviceSecure 関数は、どんな種類のドライバーやデバイス オブジェクトの作成にも使えるわけではありませんのでご注意ください。
一般的に本関数の使用を想定しているのは、バスドライバーが作成する一部の PDO (Raw Mode で動作するデバイスの PDO や、クラスで既定のものではなく独自の SDDL を設定する必要のある PDO) や、レガシードライバーとなっており、通常の WDM Function Driver や Filter Driver でのデバイスオブジェクトの作成には、IoCreateDevice 関数を使い、独自の SDDL の記述は、INF で行うようにします。また、Bus Driver でも、クラスの既定の Security Descriptor を使用する場合には、IoCreateDevice 関数を使うことになります。これらの詳細については、以下が参考になると思います。
- Creating a Device Object
<https://msdn.microsoft.com/en-us/library/windows/hardware/ff542862(v=vs.85).aspx>
ただ、Function Driver や Filter Driver でも、コントロール デバイス オブジェクトを作成する場合は、 IoCreateDeviceSecure 関数でオブジェクトの SDDL を指定します。例えば、Toaster サンプルでは、IoCreateDeviceSecure 関数でコントロールデバイス オブジェクトを作成しているのが分かります。
// pnp.c 1108 行目付近 NTSTATUS Bus_PlugInDevice ( PBUSENUM_PLUGIN_HARDWARE PlugIn, ULONG PlugInSize, PFDO_DEVICE_DATA FdoData ) … (中略) … // // PDO must have a name. You should let the system auto generate a // name by specifying FILE_AUTOGENERATED_DEVICE_NAME in the // DeviceCharacteristics parameter. Let us create a secure deviceobject, // in case the child gets installed as a raw device (RawDeviceOK), to prevent // an unpriviledged user accessing our device. This function is avaliable // in a static WDMSEC.LIB and can be used in Win2k, XP, and Server 2003 // Just make sure that the GUID specified here is not a setup class GUID. // If you specify a setup class guid, you must make sure that class is // installed before enumerating the PDO. // status = IoCreateDeviceSecure(FdoData->Self->DriverObject, sizeof (PDO_DEVICE_DATA), NULL, FILE_DEVICE_BUS_EXTENDER, FILE_AUTOGENERATED_DEVICE_NAME |FILE_DEVICE_SECURE_OPEN, FALSE, &SDDL_DEVOBJ_SYS_ALL_ADM_ALL, // read wdmsec.h for more info (LPCGUID)&GUID_SD_BUSENUM_PDO, &pdo); |
補足 : デバイス オブジェクトのSDDL について デバイス オブジェクトの場合、INF で記述する場合には、一般的な SDDL と同じ記述が可能ですが、IoCreateDeviceSecure 関数で記述できる SDDL はそのサブセットとなっています。また、前述の Toaster の Bus Driver で指定していた、SDDL_DEVOBJ_SYS_ALL_ADM_ALL のような template を使用した SDDL の指定の仕方も可能です。詳細は以下をご参照いただければと思います。 - SDDL for Device Objects <https://msdn.microsoft.com/en-us/library/windows/hardware/ff563667(v=vs.85).aspx> なお、一般的な SDDL の記述にご興味のある方は、こちらのページを見ていただければと思います。 - Security Descriptor String Format <https://msdn.microsoft.com/en-us/library/windows/desktop/aa379570(v=vs.85).aspx> |
(3) SetupDiSetDeviceRegistryProperty 関数
(1) の INF の記述による Security Descriptor は、詰まる所、レジストリ上に値の設定を行っていますので、お馴染みの Setup API のひとつである、SetupDiSetDeviceRegistryProperty 関数を使うことで、ドライバーのインストール後でも設定の変更が可能です。
関数のプロパティを指定するためのフラグには、SPDRP_SECURITY もしくは SPDRP_SECURITY_SDS を使用することになると思います。ちなみに、値の取得は、SetupDiGetDeviceRegistryProperty 関数でできます。
例えば、DevCon サンプルを改造して、/findall オプション実行時に、SetupDiGetDeviceRegistryProperty 関数で、デバイスの Friendly Name を取得する代わりに、SDDL を取得するようにしてみます。
// devcon サンプル cmds.cpp 291 行目付近 #define DEFAULT_TEXT TEXT("Default") LPTSTR GetDeviceDescription(__in HDEVINFO Devs, __in PSP_DEVINFO_DATA DevInfo) { LPTSTR desc; #if 0 // [masakata] desc = GetDeviceStringProperty(Devs,DevInfo,SPDRP_FRIENDLYNAME); #else // [masakata] desc = GetDeviceStringProperty(Devs,DevInfo,SPDRP_SECURITY_SDS); #endif // [masakata] if(!desc) { desc = new TCHAR[32]; lstrcpyn(desc,DEFAULT_TEXT,sizeof(DEFAULT_TEXT)); } return desc; } |
以下が、手元の Windows 7 SP1 環境 (Hyper-V 上) で試してみた結果です。デバイスによっては、複雑な SDDL を記述しているものがあるのが分かると思います。(レジストリが存在しない等、クラスで既定の設定を使っているものには、Default と表示するようにしています。)
ちなみに、赤字で示している ROOT\UNKNOWN000 は、事前にインストールしておいた Toaster の Bus Driver で、SDDL は前述の bus.inf で設定した通り、D:P(A;;GA;;;BA)(A;;GA;;;SY) となっているのが分かります。
ROOT\LEGACY_SRVNET000 : Default ROOT\LEGACY_DISCACHE000 : Default ROOT\MS_PPTPMINIPORT000 : Default UMB\UMB\1&841921D&0&PRINTERBUSENUMERATOR : Default ACPI\PNP0C02\1 : Default ROOT\LEGACY_NDPROXY000 : Default ROOT\LEGACY_STORFLT000 : Default ROOT\LEGACY_FILEINFO000 : Default ROOT\MS_SSTPMINIPORT000 : Default ACPI\PNP0C02\2 : Default VMBUS\{58F75A6D-D949-4320-99E1-A2A2576D581C}\5&296C0F0E&0&{58F75A6D-D949-4320-99E1-A2A2576D581C}: Default ROOT\LEGACY_NETBIOS000 : Default PCI\VEN_8086&DEV_7111&SUBSYS_00000000&REV_01\3&267A616A&0&39: Default ACPI\PNP0C04\4&215D0F95&0 : Default ROOT\LEGACY_TCPIP000 : Default STORAGE\VOLUMESNAPSHOT\HARDDISKVOLUMESNAPSHOT3 : Default VMBUS\{00000000-0000-8899-0000-000000000000}\5&296C0F0E&0&{00000000-0000-8899-0000-000000000000}: Default ROOT\LEGACY_FLTMGR000 : Default ROOT\RDPBUS000 : Default ROOT\LEGACY_NETBT000 : Default ROOT\RDP_KBD000 : Default ROOT\LEGACY_TCPIPREG000 : Default ACPI\PNP0F03\4&215D0F95&0 : Default ROOT\LEGACY_FS_REC000 : Default ROOT\RDP_MOU000 : Default ROOT\LEGACY_NPFS000 : Default ROOT\LEGACY_TDX000 : Default ROOT\LEGACY_FVEVOL000 : Default ACPI\VMBUS\4&215D0F95&0 : D:P(A;;GA;;;BA)(A;;GA;;;SY) PCI\VEN_8086&DEV_7192&SUBSYS_00000000&REV_03\3&267A616A&0&00: Default ROOT\SYSTEM000 : Default ROOT\LEGACY_NSIPROXY000 : Default ACPI\FIXEDBUTTON\2&DABA3FF&2 : Default ROOT\LEGACY_UDFS000 : Default ROOT\LEGACY_HTTP000 : Default ACPI_HAL\PNP0C08 : Default ROOT\UMBUS000 : Default VMBUS\{6B6E7049-1CC7-4653-A142-9B7B5AC318FA}\5&296C0F0E&0&{6B6E7049-1CC7-4653-A142-9B7B5AC318FA}: Default ROOT\LEGACY_NTFS000 : Default VMBUS\{242FF919-07DB-4180-9C2E-B86CB68C8C55}\5&296C0F0E&0&{242FF919-07DB-4180-9C2E-B86CB68C8C55}: D:P(A;;GA;;;BA)(A;;GA;;;SY)(A;;GA;;;S-1-5-80-1877308096-3090306141-3032871208-3115266146-1400827410) ROOT\LEGACY_VGASAVE000 : Default FDC\GENERIC_FLOPPY_DRIVE\5&3AA3947E&0&0 : Default ROOT\UNKNOWN000 : D:P(A;;GA;;;BA)(A;;GA;;;SY) ROOT\LEGACY_HWPOLICY000 : Default ACPI\GENUINEINTEL_-_X86_FAMILY_6_MODEL_15_-_INTEL(R)_CORE(TM)2_CPU__________6400__@_2.13GHZ\_1: Default ROOT\LEGACY_NULL000 : Default ROOT\VDRVROOT000 : Default PCIIDE\IDECHANNEL\4&10BF2F88&0&0 : Default ROOT\LEGACY_VOLMGRX000 : Default ROOT\LEGACY_KSECDD000 : Default HID\{58F75A6D-D949-4320-99E1-A2A2576D581C}\6&E4AA24C&0&0000 : Default ROOT\VOLMGR000 : Default ROOT\LEGACY_PCW000 : Default ROOT\LEGACY_VOLSNAP000 : Default ROOT\LEGACY_KSECPKG000 : Default PCIIDE\IDECHANNEL\4&10BF2F88&0&1 : Default STORAGE\VOLUME\{F841DCBE-4BB0-11E1-99F2-806E6F6E6963}#0000000000100000: Default ROOT\LEGACY_PEAUTH000 : Default ROOT\LEGACY_WANARPV6000 : Default ROOT\LEGACY_LLTDIO000 : Default VMBUS\{AA5601EE-5D88-48AD-8E1A-4250FB1256E7}\5&296C0F0E&0&{AA5601EE-5D88-48AD-8E1A-4250FB1256E7}: D:P(A;;GA;;;BA)(A;;GA;;;SY)(A;;GWGR;;;BU) ROOT\LEGACY_PSCHED000 : Default ROOT\*ISATAP000 : Default VMBUS\{2450EE40-33BF-4FBD-892E-9FB06E9214CF}\5&296C0F0E&0&{2450EE40-33BF-4FBD-892E-9FB06E9214CF}: D:P(A;;GA;;;BA)(A;;GA;;;SY)(A;;GA;;;S-1-5-80-1752088424-1054500994-3489791022-3310831482-3926524968) ACPI\PNP0000\4&215D0F95&0 : Default HTREE\ROOT : Default ROOT\LEGACY_LUAFV000 : Default ROOT\LEGACY_WDF01000000 : Default ROOT\ACPI_HAL000 : Default ROOT\LEGACY_RDBSS000 : Default IDE\CDROMMSFT_VIRTUAL_CD/ROM_____________________1.0_____\5&CFB56DE&0&1.0.0: Default ACPI\PNP0100\4&215D0F95&0 : Default ROOT\LEGACY_MOUNTMGR000 : Default ROOT\BLBDRIVE000 : Default STORAGE\VOLUME\{F841DCBE-4BB0-11E1-99F2-806E6F6E6963}#0000000006500000: Default ROOT\LEGACY_WFPLWF000 : Default ROOT\LEGACY_RDPCDD000 : Default ROOT\COMPOSITEBUS000 : D:P(A;;GA;;;BA)(A;;GA;;;SY) ACPI\PNP0200\4&215D0F95&0 : Default ROOT\LEGACY_MPSDRV000 : Default ROOT\MSSMBIOS000 : Default ROOT\LEGACY_RDPENCDD000 : Default ROOT\LEGACY_AFD000 : Default ACPI\PNP0303\4&215D0F95&0 : Default ROOT\MS_AGILEVPNMINIPORT000 : Default VMBUS\{B6650FF7-33BC-4840-8048-E0676786F393}\5&296C0F0E&0&{B6650FF7-33BC-4840-8048-E0676786F393}: D:P(A;;GA;;;BA)(A;;GA;;;SY)(A;;GA;;;S-1-5-80-3110303136-3426481729-3186938678-1087894076-2178433439) ROOT\LEGACY_MRXSMB000 : Default IDE\DISKVIRTUAL_HD______________________________1.1.0___\5&35DC7040&0&0.0.0: Default VMBUS\{2DD1CE17-079E-403C-B352-A1921EE207EE}\5&296C0F0E&0&{2DD1CE17-079E-403C-B352-A1921EE207EE}: D:P(A;;GA;;;BA)(A;;GA;;;SY)(A;;GA;;;S-1-5-80-3098585136-2538892366-1097114017-2832417424-2016953023) ROOT\LEGACY_RDPREFMP000 : Default ROOT\LEGACY_BEEP000 : Default STORAGE\VOLUMESNAPSHOT\HARDDISKVOLUMESNAPSHOT1 : Default ACPI\PNP0501\1 : Default ROOT\LEGACY_MRXSMB10000 : Default ROOT\MS_L2TPMINIPORT000 : Default ROOT\LEGACY_RSPNDR000 : Default ROOT\LEGACY_BOWSER000 : Default ACPI\PNP0501\2 : Default ROOT\LEGACY_MRXSMB20000 : Default ROOT\MS_NDISWANBH000 : Default ACPI\PNP0700\4&215D0F95&0 : Default ROOT\LEGACY_SECDRV000 : Default ROOT\LEGACY_CLFS000 : Default STORAGE\VOLUMESNAPSHOT\HARDDISKVOLUMESNAPSHOT2 : Default ROOT\LEGACY_MSFS000 : Default ROOT\MS_NDISWANIP000 : Default PCI\VEN_1414&DEV_5353&SUBSYS_00000000&REV_00\3&267A616A&0&40: Default ACPI\PNP0800\4&215D0F95&0 : Default ROOT\LEGACY_SPLDR000 : Default ROOT\LEGACY_CNG000 : Default VMBUS\{FD149E91-82E0-4A7D-AFA6-2A4166CBD7C0}\5&296C0F0E&0&{FD149E91-82E0-4A7D-AFA6-2A4166CBD7C0}: D:P(A;;GA;;;BA)(A;;GA;;;SY)(A;;GA;;;S-1-5-80-534935901-3437432317-481271085-1710633381-983106267) ROOT\LEGACY_MSISADRV000 : Default VMBUS\{5620E0C7-8062-4DCE-AEB7-520C7EF76171}\5&296C0F0E&0&{5620E0C7-8062-4DCE-AEB7-520C7EF76171}: Default ROOT\MS_NDISWANIPV6000 : Default ROOT\LEGACY_SRV000 : Default ROOT\LEGACY_CSC000 : Default ACPI\PNP0A03 : Default SW\{EEAB7790-C514-11D1-B42B-00805FC1270E}\ASYNCMAC : Default ROOT\LEGACY_MUP000 : Default ACPI\PNP0B00\4&215D0F95&0 : Default ROOT\MS_PPPOEMINIPORT000 : Default ROOT\LEGACY_SRV2000 : Default ROOT\LEGACY_DFSC000 : Default PCI\VEN_8086&DEV_7110&SUBSYS_00001414&REV_01\3&267A616A&0&38: Default ROOT\LEGACY_NDIS000 : Default ACPI\PNP0C01\1 : Default 126 matching device(s) found. |
さらに、SetupDiSetDeviceRegistryProperty 関数の方も試してみます。
実際にはこんなことをすべきではありませんが、以下では、全てのデバイスの SDDL で World (everyone) に対して、Generic_All のアクセス権を付与して、その後、SDDL を取得して表示します。
#define MY_SDDL_STRING TEXT("D:P(A;;GA;;;WD)") #define DEFAULT_TEXT TEXT("Default") LPTSTR GetDeviceDescription(__in HDEVINFO Devs, __in PSP_DEVINFO_DATA DevInfo) { LPTSTR desc; #if 0 // [masakata] desc = GetDeviceStringProperty(Devs,DevInfo,SPDRP_FRIENDLYNAME); #else // [masakata] SetupDiSetDeviceRegistryProperty(Devs,DevInfo,SPDRP_SECURITY_SDS,(BYTE*)MY_SDDL_STRING,sizeof(MY_SDDL_STRING)); desc = GetDeviceStringProperty(Devs,DevInfo,SPDRP_SECURITY_SDS); #endif // [masakata] if(!desc) { desc = new TCHAR[64]; lstrcpyn(desc,DEFAULT_TEXT,sizeof(DEFAULT_TEXT)); } return desc; } |
すると、全ての SDDL が指定した通りに変更されました。しかし、これでは、セキュリティとしては穴だらけの状態ですので、このようなことはお勧めしません。
先ほどの Toaster Bus Driver も、元々の D:P(A;;GA;;;BA)(A;;GA;;;SY) から、D:P(A;;GA;;;WD) に変わってしまっています。
ROOT\LEGACY_SRVNET000 : D:P(A;;GA;;;WD) ROOT\LEGACY_DISCACHE000 : D:P(A;;GA;;;WD) ROOT\MS_PPTPMINIPORT000 : D:P(A;;GA;;;WD) UMB\UMB\1&841921D&0&PRINTERBUSENUMERATOR: D:P(A;;GA;;;WD) ACPI\PNP0C02\1 : D:P(A;;GA;;;WD) ROOT\LEGACY_NDPROXY000 : D:P(A;;GA;;;WD) ROOT\LEGACY_STORFLT000 : D:P(A;;GA;;;WD) ROOT\LEGACY_FILEINFO000 : D:P(A;;GA;;;WD) ROOT\MS_SSTPMINIPORT000 : D:P(A;;GA;;;WD) ACPI\PNP0C02\2 : D:P(A;;GA;;;WD) VMBUS\{58F75A6D-D949-4320-99E1-A2A2576D581C}\5&296C0F0E&0&{58F75A6D-D949-4320-99E1-A2A2576D581C} : D:P(A;;GA;;;WD) ROOT\LEGACY_NETBIOS000 : D:P(A;;GA;;;WD) PCI\VEN_8086&DEV_7111&SUBSYS_00000000&REV_01\3&267A616A&0&39 : D:P(A;;GA;;;WD) ACPI\PNP0C04\4&215D0F95&0 : D:P(A;;GA;;;WD) ROOT\LEGACY_TCPIP000 : D:P(A;;GA;;;WD) STORAGE\VOLUMESNAPSHOT\HARDDISKVOLUMESNAPSHOT3 : D:P(A;;GA;;;WD) VMBUS\{00000000-0000-8899-0000-000000000000}\5&296C0F0E&0&{00000000-0000-8899-0000-000000000000} : D:P(A;;GA;;;WD) ROOT\LEGACY_FLTMGR000 : D:P(A;;GA;;;WD) ROOT\RDPBUS000 : D:P(A;;GA;;;WD) ROOT\LEGACY_NETBT000 : D:P(A;;GA;;;WD) ROOT\RDP_KBD000 : D:P(A;;GA;;;WD) ROOT\LEGACY_TCPIPREG000 : D:P(A;;GA;;;WD) ACPI\PNP0F03\4&215D0F95&0 : D:P(A;;GA;;;WD) ROOT\LEGACY_FS_REC000 : D:P(A;;GA;;;WD) ROOT\RDP_MOU000 : D:P(A;;GA;;;WD) ROOT\LEGACY_NPFS000 : D:P(A;;GA;;;WD) ROOT\LEGACY_TDX000 : D:P(A;;GA;;;WD) ROOT\LEGACY_FVEVOL000 : D:P(A;;GA;;;WD) ACPI\VMBUS\4&215D0F95&0 : D:P(A;;GA;;;WD) PCI\VEN_8086&DEV_7192&SUBSYS_00000000&REV_03\3&267A616A&0&00 : D:P(A;;GA;;;WD) ROOT\SYSTEM000 : D:P(A;;GA;;;WD) ROOT\LEGACY_NSIPROXY000 : D:P(A;;GA;;;WD) ACPI\FIXEDBUTTON\2&DABA3FF&2 : D:P(A;;GA;;;WD) ROOT\LEGACY_UDFS000 : D:P(A;;GA;;;WD) ROOT\LEGACY_HTTP000 : D:P(A;;GA;;;WD) ACPI_HAL\PNP0C08 : D:P(A;;GA;;;WD) ROOT\UMBUS000 : D:P(A;;GA;;;WD) VMBUS\{6B6E7049-1CC7-4653-A142-9B7B5AC318FA}\5&296C0F0E&0&{6B6E7049-1CC7-4653-A142-9B7B5AC318FA} : D:P(A;;GA;;;WD) ROOT\LEGACY_NTFS000 : D:P(A;;GA;;;WD) VMBUS\{242FF919-07DB-4180-9C2E-B86CB68C8C55}\5&296C0F0E&0&{242FF919-07DB-4180-9C2E-B86CB68C8C55} : D:P(A;;GA;;;WD) ROOT\LEGACY_VGASAVE000 : D:P(A;;GA;;;WD) FDC\GENERIC_FLOPPY_DRIVE\5&3AA3947E&0&0 : D:P(A;;GA;;;WD) ROOT\UNKNOWN000 : D:P(A;;GA;;;WD) ROOT\LEGACY_HWPOLICY000 : D:P(A;;GA;;;WD) ACPI\GENUINEINTEL_-_X86_FAMILY_6_MODEL_15_-_INTEL(R)_CORE(TM)2_CPU__________6400__@_2.13GHZ\_1 : D:P(A;;GA;;;WD) ROOT\LEGACY_NULL000 : D:P(A;;GA;;;WD) ROOT\VDRVROOT000 : D:P(A;;GA;;;WD) PCIIDE\IDECHANNEL\4&10BF2F88&0&0 : D:P(A;;GA;;;WD) ROOT\LEGACY_VOLMGRX000 : D:P(A;;GA;;;WD) ROOT\LEGACY_KSECDD000 : D:P(A;;GA;;;WD) HID\{58F75A6D-D949-4320-99E1-A2A2576D581C}\6&E4AA24C&0&0000 : D:P(A;;GA;;;WD) ROOT\VOLMGR000 : D:P(A;;GA;;;WD) ROOT\LEGACY_PCW000 : D:P(A;;GA;;;WD) ROOT\LEGACY_VOLSNAP000 : D:P(A;;GA;;;WD) ROOT\LEGACY_KSECPKG000 : D:P(A;;GA;;;WD) PCIIDE\IDECHANNEL\4&10BF2F88&0&1 : D:P(A;;GA;;;WD) STORAGE\VOLUME\{F841DCBE-4BB0-11E1-99F2-806E6F6E6963}#0000000000100000: D:P(A;;GA;;;WD) ROOT\LEGACY_PEAUTH000 : D:P(A;;GA;;;WD) ROOT\LEGACY_WANARPV6000 : D:P(A;;GA;;;WD) ROOT\LEGACY_LLTDIO000 : D:P(A;;GA;;;WD) VMBUS\{AA5601EE-5D88-48AD-8E1A-4250FB1256E7}\5&296C0F0E&0&{AA5601EE-5D88-48AD-8E1A-4250FB1256E7}: D:P(A;;GA;;;WD) ROOT\LEGACY_PSCHED000 : D:P(A;;GA;;;WD) ROOT\*ISATAP000 : D:P(A;;GA;;;WD) VMBUS\{2450EE40-33BF-4FBD-892E-9FB06E9214CF}\5&296C0F0E&0&{2450EE40-33BF-4FBD-892E-9FB06E9214CF}: D:P(A;;GA;;;WD) ACPI\PNP0000\4&215D0F95&0 : D:P(A;;GA;;;WD) HTREE\ROOT : D:P(A;;GA;;;WD) ROOT\LEGACY_LUAFV000 : D:P(A;;GA;;;WD) ROOT\LEGACY_WDF01000000 : D:P(A;;GA;;;WD) ROOT\ACPI_HAL000 : D:P(A;;GA;;;WD) ROOT\LEGACY_RDBSS000 : D:P(A;;GA;;;WD) IDE\CDROMMSFT_VIRTUAL_CD/ROM_____________________1.0_____\5&CFB56DE&0&1.0.0: D:P(A;;GA;;;WD) ACPI\PNP0100\4&215D0F95&0 : D:P(A;;GA;;;WD) ROOT\LEGACY_MOUNTMGR000 : D:P(A;;GA;;;WD) ROOT\BLBDRIVE000 : D:P(A;;GA;;;WD) STORAGE\VOLUME\{F841DCBE-4BB0-11E1-99F2-806E6F6E6963}#0000000006500000: D:P(A;;GA;;;WD) ROOT\LEGACY_WFPLWF000 : D:P(A;;GA;;;WD) ROOT\LEGACY_RDPCDD000 : D:P(A;;GA;;;WD) ROOT\COMPOSITEBUS000 : D:P(A;;GA;;;WD) ACPI\PNP0200\4&215D0F95&0 : D:P(A;;GA;;;WD) ROOT\LEGACY_MPSDRV000 : D:P(A;;GA;;;WD) ROOT\MSSMBIOS000 : D:P(A;;GA;;;WD) ROOT\LEGACY_RDPENCDD000 : D:P(A;;GA;;;WD) ROOT\LEGACY_AFD000 : D:P(A;;GA;;;WD) ACPI\PNP0303\4&215D0F95&0 : D:P(A;;GA;;;WD) ROOT\MS_AGILEVPNMINIPORT000 : D:P(A;;GA;;;WD) VMBUS\{B6650FF7-33BC-4840-8048-E0676786F393}\5&296C0F0E&0&{B6650FF7-33BC-4840-8048-E0676786F393}: D:P(A;;GA;;;WD) ROOT\LEGACY_MRXSMB000 : D:P(A;;GA;;;WD) IDE\DISKVIRTUAL_HD______________________________1.1.0___\5&35DC7040&0&0.0.0: D:P(A;;GA;;;WD) VMBUS\{2DD1CE17-079E-403C-B352-A1921EE207EE}\5&296C0F0E&0&{2DD1CE17-079E-403C-B352-A1921EE207EE}: D:P(A;;GA;;;WD) ROOT\LEGACY_RDPREFMP000 : D:P(A;;GA;;;WD) ROOT\LEGACY_BEEP000 : D:P(A;;GA;;;WD) STORAGE\VOLUMESNAPSHOT\HARDDISKVOLUMESNAPSHOT1 : D:P(A;;GA;;;WD) ACPI\PNP0501\1 : D:P(A;;GA;;;WD) ROOT\LEGACY_MRXSMB10000 : D:P(A;;GA;;;WD) ROOT\MS_L2TPMINIPORT000 : D:P(A;;GA;;;WD) ROOT\LEGACY_RSPNDR000 : D:P(A;;GA;;;WD) ROOT\LEGACY_BOWSER000 : D:P(A;;GA;;;WD) ACPI\PNP0501\2 : D:P(A;;GA;;;WD) ROOT\LEGACY_MRXSMB20000 : D:P(A;;GA;;;WD) ROOT\MS_NDISWANBH000 : D:P(A;;GA;;;WD) ACPI\PNP0700\4&215D0F95&0 : D:P(A;;GA;;;WD) ROOT\LEGACY_SECDRV000 : D:P(A;;GA;;;WD) ROOT\LEGACY_CLFS000 : D:P(A;;GA;;;WD) STORAGE\VOLUMESNAPSHOT\HARDDISKVOLUMESNAPSHOT2 : D:P(A;;GA;;;WD) ROOT\LEGACY_MSFS000 : D:P(A;;GA;;;WD) ROOT\MS_NDISWANIP000 : D:P(A;;GA;;;WD) PCI\VEN_1414&DEV_5353&SUBSYS_00000000&REV_00\3&267A616A&0&40 : D:P(A;;GA;;;WD) ACPI\PNP0800\4&215D0F95&0 : D:P(A;;GA;;;WD) ROOT\LEGACY_SPLDR000 : D:P(A;;GA;;;WD) ROOT\LEGACY_CNG000 : D:P(A;;GA;;;WD) VMBUS\{FD149E91-82E0-4A7D-AFA6-2A4166CBD7C0}\5&296C0F0E&0&{FD149E91-82E0-4A7D-AFA6-2A4166CBD7C0} : D:P(A;;GA;;;WD) ROOT\LEGACY_MSISADRV000 : D:P(A;;GA;;;WD) VMBUS\{5620E0C7-8062-4DCE-AEB7-520C7EF76171}\5&296C0F0E&0&{5620E0C7-8062-4DCE-AEB7-520C7EF76171} : D:P(A;;GA;;;WD) ROOT\MS_NDISWANIPV6000 : D:P(A;;GA;;;WD) ROOT\LEGACY_SRV000 : D:P(A;;GA;;;WD) ROOT\LEGACY_CSC000 : D:P(A;;GA;;;WD) ACPI\PNP0A03 : D:P(A;;GA;;;WD) SW\{EEAB7790-C514-11D1-B42B-00805FC1270E}\ASYNCMAC : D:P(A;;GA;;;WD) ROOT\LEGACY_MUP000 : D:P(A;;GA;;;WD) ACPI\PNP0B00\4&215D0F95&0 : D:P(A;;GA;;;WD) ROOT\MS_PPPOEMINIPORT000 : D:P(A;;GA;;;WD) ROOT\LEGACY_SRV2000 : D:P(A;;GA;;;WD) ROOT\LEGACY_DFSC000 : D:P(A;;GA;;;WD) PCI\VEN_8086&DEV_7110&SUBSYS_00001414&REV_01\3&267A616A&0&38 : D:P(A;;GA;;;WD) ROOT\LEGACY_NDIS000 : D:P(A;;GA;;;WD) ACPI\PNP0C01\1 : D:P(A;;GA;;;WD) 126 matching device(s) found. |
実際、この状態で、Bus Driver に対して、サンプルの Enum.exe を使用して、Toaster Device のインスタンスの追加を行おうとすると、管理者権限でなくても追加ができてしまいます。
対して、サンプルの元々の Security Descriptor だと、管理者権限であればアクセスできますが、通常のユーザー権限だと以下のように Access Denied (Error Code : 0x5) となります。
このように、デバイス オブジェクトの Security Descriptor は、ドライバー作成者の方々である程度コントロールすることができますし、Setup API を使用すれば、インストール後にも変更することが可能です。しかし、設定の際に、不用意に誰にでもアクセスできるようにしてしまうと、重大なセキュリティホールとなる可能性がありますので、十分ご注意ください。
それでは、また。
[参考]
- Controlling Device Access
<https://msdn.microsoft.com/en-us/library/windows/hardware/ff542063(v=vs.85).aspx>
- Applying Security Descriptors on the Device Object
<https://msdn.microsoft.com/en-us/library/windows/hardware/ff538907(v=vs.85).aspx>
- Creating Secure Device Installations
<https://msdn.microsoft.com/en-us/library/windows/hardware/ff540212(v=vs.85).aspx>
- Setting Device Object Properties in the Registry
<https://msdn.microsoft.com/en-us/library/windows/hardware/ff563750(v=vs.85).aspx>