ZwSetSecurityObject does not seem to be working

Ok. I’m successfully creating/reading my Bel LaPadulla markers in a raw disk device MBR, thanks to many of you on here. I’m in the final stages of this driver and now trying to secure the disk if needed. Ie, it should have only read access to all users or no access to all users

So I follow the example in http://blogs.msdn.com/doronh/archive/2007/10/16/setting-a-security-descriptor-on-a-legacy-device-object.aspx and it seems to work so far. I am able to see the pACLs get built and the ACEs added to the pACLs. The security descriptor seems to be built without issue and even the ZwSetSecurityObject seems to work (normal status returned). But when I try to open the disk I can still read/write to it.

For discussion, I am opening the raw disk device first, (i.e. \DosDevices\PhysicalDrive1 for a USB storage device) reading the MBR, since I have the disk open and then setting the security on that device while it is still open with:

status = ZwSetSecurityObject(deviceExtension->MBR, DACL_SECURITY_INFORMATION,
SecurityDescriptorNoAccess);

SecurityDescriptorNoAccess is comprised of the following:

aclNoAccessSize = sizeof(ACL);
aclNoAccessSize += RtlLengthSid(SeExports->SeLocalSystemSid);
aclNoAccessSize += 1 * FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart);
pAclNoAccess = (PACL) ExAllocatePoolWithTag(NonPagedPool, aclNoAccessSize, ‘3gaT’);
SecurityDescriptorNoAccess = (PSECURITY_DESCRIPTOR) ExAllocatePoolWithTag(
NonPagedPool, sizeof(SECURITY_DESCRIPTOR), ‘5gaT’);
status = RtlCreateAcl(pAclNoAccess, aclNoAccessSize, ACL_REVISION);
status = RtlAddAccessAllowedAce(pAclNoAccess, ACL_REVISION, GENERIC_READ,
SeExports->SeLocalSystemSid );
status = RtlCreateSecurityDescriptor(SecurityDescriptorNoAccess,
SECURITY_DESCRIPTOR_REVISION);
status = RtlSetDaclSecurityDescriptor(SecurityDescriptorNoAccess, TRUE, pAclNoAccess,
FALSE);

I wasn’t sure how to set the deny all( I found the ACCESS_DENIED_ACE structure but not a RtlAddAccessDeniedAce() method to apply the ACCESS_DENIED_ACE, so opted to just allow the SeLocalSystemSid to maintain access, though I would prefer nothing being able to access it. Then once the USB device completes my driver and is handed off for other OS functions, it is still completely read/write able. What am I doing wrong?

You are probably setting the acl on the wrong devobj. How did you get the value in deviceextension->MBR? I bet it is either the top of the stack or the devobj you attached to in adddevice. Run !devstack (mbr devobj) and see where it is in the stack (and send the output) and who in the stack has the object name you are trying to secure.

d

tiny phone keyboard + fat thumbs = you do the muth

-----Original Message-----
From: xxxxx@gmail.com
Sent: Thursday, April 01, 2010 5:41 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] ZwSetSecurityObject does not seem to be working

Ok. I’m successfully creating/reading my Bel LaPadulla markers in a raw disk device MBR, thanks to many of you on here. I’m in the final stages of this driver and now trying to secure the disk if needed. Ie, it should have only read access to all users or no access to all users

So I follow the example in http://blogs.msdn.com/doronh/archive/2007/10/16/setting-a-security-descriptor-on-a-legacy-device-object.aspx and it seems to work so far. I am able to see the pACLs get built and the ACEs added to the pACLs. The security descriptor seems to be built without issue and even the ZwSetSecurityObject seems to work (normal status returned). But when I try to open the disk I can still read/write to it.

For discussion, I am opening the raw disk device first, (i.e. \DosDevices\PhysicalDrive1 for a USB storage device) reading the MBR, since I have the disk open and then setting the security on that device while it is still open with:

status = ZwSetSecurityObject(deviceExtension->MBR, DACL_SECURITY_INFORMATION,
SecurityDescriptorNoAccess);

SecurityDescriptorNoAccess is comprised of the following:

aclNoAccessSize = sizeof(ACL);
aclNoAccessSize += RtlLengthSid(SeExports->SeLocalSystemSid);
aclNoAccessSize += 1 * FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart);
pAclNoAccess = (PACL) ExAllocatePoolWithTag(NonPagedPool, aclNoAccessSize, ‘3gaT’);
SecurityDescriptorNoAccess = (PSECURITY_DESCRIPTOR) ExAllocatePoolWithTag(
NonPagedPool, sizeof(SECURITY_DESCRIPTOR), ‘5gaT’);
status = RtlCreateAcl(pAclNoAccess, aclNoAccessSize, ACL_REVISION);
status = RtlAddAccessAllowedAce(pAclNoAccess, ACL_REVISION, GENERIC_READ,
SeExports->SeLocalSystemSid );
status = RtlCreateSecurityDescriptor(SecurityDescriptorNoAccess,
SECURITY_DESCRIPTOR_REVISION);
status = RtlSetDaclSecurityDescriptor(SecurityDescriptorNoAccess, TRUE, pAclNoAccess,
FALSE);

I wasn’t sure how to set the deny all( I found the ACCESS_DENIED_ACE structure but not a RtlAddAccessDeniedAce() method to apply the ACCESS_DENIED_ACE, so opted to just allow the SeLocalSystemSid to maintain access, though I would prefer nothing being able to access it. Then once the USB device completes my driver and is handed off for other OS functions, it is still completely read/write able. What am I doing wrong?


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Doron,

You are probably setting the acl on the wrong devobj. How did you get the value
in deviceextension->MBR? I bet it is either the top of the stack or the devobj
you attached to in adddevice.

MBR is just a HANDLE from inside of deviceExtension for the raw disk device I read the MBR of. It receives its value when I do:
(i.e., PhysicalDeviceName = L"\DosDevices\PhysicalDrive1", which in this case represents a USB storage device attached)

InitializeObjectAttributes(&obj_attrib, &deviceExtension->PhysicalDeviceName,
OBJ_CASE_INSENSITIVE, NULL, NULL);
status = ZwCreateFile(&deviceExtension->MBR,
FILE_READ_DATA | FILE_WRITE_DATA,
&obj_attrib, &file_status, NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN, FILE_NON_DIRECTORY_FILE, NULL, 0);

Run !devstack (mbr devobj) and see where it is in
the stack (and send the output) and who in the stack has the object name you are
trying to secure.

I tried running !devstack per your recommendation and got Device object not found. I also tried:
!devstack DeviceObject->DeviceExtension->PhysicalDeviceObject (where DeviceObject is passed into the workroutine MyWorkItemRoutine(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context) ) and other variations to no success.

I do have the following other PDEVICE_OBJECTS in the deviceExtension as well if that helps. PDEVICE_OBJECT TargetDeviceObject;// Target Device Object from
//IoAttachDeviceToDeviceStack(filterDeviceObject,
//PhysicalDeviceObject);
PDEVICE_OBJECT PhysicalDeviceObject;// Physical device object received in AddDevice

Thanks for the help Doron.

Brian

Doron,

I was finally able to figure out how to get the dev stack listed… diskperf is still the name of my driver for the current time being. I think I should be securing “81b82030 \Driver\Disk 81b820e8 DR0” to prevent any user access (read/writes to the disk) however, I am not sure if this is the correct device or if it should really be the bottom most device in the stack.

Furthermore I compared the values of my deviceExtension values for PhysicalDeviceObject is pointed to “81b83030 \Driver\atapi 81b830e8 IdeDeviceP0T0L0-3” and TargetDeviceObject is pointed to “81b6b810 \Driver\PartMgr 81b6b8c8”

Here are the results from WinDbg:

kd> !drvobj \Driver\disk
Driver object (81b6be98) is for:
\Driver\Disk
Driver Extension List: (id , addr)
(f99e3338 81b6bc98)
Device Object list:
81bd0810 81b82030

kd> !drvobj \Driver\diskperf
Driver object (81b6bbc0) is for:
\Driver\diskperf
Driver Extension List: (id , addr)

Device Object list:
81b6b638 81b6ba38

kd> !devstack 81bd0810
!DevObj !DrvObj !DevExt ObjectName

81bd0810 \Driver\Disk 81bd08c8 DP(1)0x7e00-0x27f4db200+1

kd> !devstack 81b82030
!DevObj !DrvObj !DevExt ObjectName
81b6b638 \Driver\diskperf 81b6b6f0
81b6b810 \Driver\PartMgr 81b6b8c8

81b82030 \Driver\Disk 81b820e8 DR0
81b83030 \Driver\atapi 81b830e8 IdeDeviceP0T0L0-3
!DevNode 81bd3ee8 :
DeviceInst is “IDE\DiskVMware_Virtual_IDE_Hard_Drive___________00000001\3030303030303030303030303030303030303130”
ServiceName is “disk”

I have tried opening a seperate handle aside from ZwCreateFile just for securing it to the device using:
HANDLE fileHandle;
status = ObOpenObjectByPointer(deviceExtension->PhysicalDeviceObject,
OBJ_KERNEL_HANDLE,
NULL,
WRITE_DAC,
NULL,
KernelMode,
&fileHandle);

where deviceExtension->PhysicalDeviceObject is:
8198cea0 \Driver\USBSTOR 8198cf58 0000005a !DevNode 81678408 :
DeviceInst is “USBSTOR\Disk&Ven_USB_2.0&Prod_Flash_Disk&Rev_PROL\7&20453587&0”
ServiceName is “disk”

The handle is created with status 0 and when I run
status = ZwSetSecurityObject(&fileHandle, DACL_SECURITY_INFORMATION,
SecurityDescriptorNoAccess);

I get a status of -1073741816 or 3221225480 = “an invalid handle was specified”.

I just am at a loss of what device to secure to control any type of authenticated user activity. Any help you all can provide is greatly appreciated!

Here is the devstack for this USB device… the last stack I showed in a prev message was for disk0.

kd> !devstack 81b82030
!DevObj !DrvObj !DevExt ObjectName
81b6b638 \Driver\diskperf 81b6b6f0
81b6b810 \Driver\PartMgr 81b6b8c8

81b82030 \Driver\Disk 81b820e8 DR0
81b83030 \Driver\atapi 81b830e8 IdeDeviceP0T0L0-3
!DevNode 81bd3ee8 :
DeviceInst is
“IDE\DiskVMware_Virtual_IDE_Hard_Drive___________00000001\30303030303030303030303
03030303030303130”
ServiceName is “disk”

oops… posted the wrong stack.

kd> !devstack 81940030
!DevObj !DrvObj !DevExt ObjectName
81a92020 \Driver\diskperf 81a920d8
81a175f8 \Driver\PartMgr 81a176b0

81940030 \Driver\Disk 819400e8 DR2
81972ea0 \Driver\USBSTOR 81972f58 00000057
!DevNode 81adbaf0 :
DeviceInst is “USBSTOR\Disk&Ven_USB_2.0&Prod_Flash_Disk&Rev_PROL\7&20453587&0”
ServiceName is “disk”

ok… I just tried to perform ZwSetSecurityObject on
81940030 \Driver\Disk 819400e8 DR2
which is one device above the PDO and is the first FDO created in the stack by disk.sys

I’m still getting the status of -1073741816 or 3221225480 = “an invalid handle was specified”.

Here is how I got to the first FDO.
PDEVICE_OBJECT pDisk;
pDisk = IoGetLowerDeviceObject( deviceExtension->TargetDeviceObject);
status = ObOpenObjectByPointer(pDisk, OBJ_KERNEL_HANDLE, NULL,
WRITE_DAC, 0, KernelMode, &fileHandle);

I’m now open to any ideas on what is going wrong and/or which device I should apply the security to.

Thanks.
Brian

status = ZwSetSecurityObject(&fileHandle, DACL_SECURITY_INFORMATION,
??? ??? SecurityDescriptorNoAccess);

Change it to

status = ZwSetSecurityObject(fileHandle, DACL_SECURITY_INFORMATION,
??? ??? SecurityDescriptorNoAccess);

You have passed the address of the handle instead of the handle itself to ZwSetSecurityObject!

Lijun


From: “xxxxx@gmail.com
To: Windows System Software Devs Interest List
Sent: Fri, April 2, 2010 7:55:15 PM
Subject: RE:[ntdev] ZwSetSecurityObject does not seem to be working

I have tried opening a seperate handle aside from ZwCreateFile just for securing it to the device using:
HANDLE fileHandle;
status = ObOpenObjectByPointer(deviceExtension->PhysicalDeviceObject,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OBJ_KERNEL_HANDLE,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? NULL,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? WRITE_DAC,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? NULL,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? KernelMode,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &fileHandle);

where deviceExtension->PhysicalDeviceObject is:
8198cea0? \Driver\USBSTOR? ? 8198cf58? 0000005a !DevNode 81678408 :
? DeviceInst is “USBSTOR\Disk&Ven_USB_2.0&Prod_Flash_Disk&Rev_PROL\7&20453587&0”
? ServiceName is “disk”

The handle is created with status 0 and when I run
status = ZwSetSecurityObject(&fileHandle, DACL_SECURITY_INFORMATION,
??? ??? SecurityDescriptorNoAccess);

I get a status of -1073741816 or 3221225480 = “an invalid handle was specified”.

I just am at a loss of what device to secure to control any type of authenticated user activity.? Any help you all can provide is greatly appreciated!

Here is the devstack for this USB device… the last stack I showed in a prev message was for disk0.

kd> !devstack 81b82030
? !DevObj? !DrvObj? ? ? ? ? ? !DevExt? ObjectName
? 81b6b638? \Driver\diskperf? 81b6b6f0?
? 81b6b810? \Driver\PartMgr? ? 81b6b8c8?
> 81b82030? \Driver\Disk? ? ? 81b820e8? DR0
? 81b83030? \Driver\atapi? ? ? 81b830e8? IdeDeviceP0T0L0-3
!DevNode 81bd3ee8 :
? DeviceInst is
“IDE\DiskVMware_Virtual_IDE_Hard_Drive ___________ 00000001\30303030303030303030303
03030303030303130”
? ServiceName is “disk”


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Thanks Lijun. I can’t believe I missed that.

Ok, so I changed the point of security to be the actual PDO or the first FDO (same effect either place) and using DeviceTree I can see that the disk has the correct permissions on it. However, I can still open the disk as a user and read/write to it. So I’m guessing that I need to secure the partitions as well. Here is what DeviceTree shows under disk for \Driver\Disk specifically for my attached USB storage device. The second DEV is the one I am filtering on and that is the one that shows the modified permissions I have set.

DEV \Device\Harddisk1\DP(1)0-0+3
DEV \Device\Harddisk1\DR2

First question, so how can I find out pointers to all of the partitions available on a specific disk so that I can secure them all in the same manner as I did DR2? For example, say for Harddisk1 there was another partition as well to what is listed above, DP(2)#-#+# (where # are the numbers for the partition).

Second question, if I was able to filter directly above Disk.sys in the devstack instead of above PartMgr would I receive an AddDevice for each partition as well as raw disks since they all show up as DEV under disk? If so how do I achieve that?

You should test your driver with driver verifier on, it would have caught the &filehandle bug for you. Run your app under process explorer and you might see different names/handles being opened than you are expecting.

d

tiny phone keyboard + fat thumbs = you do the muth

-----Original Message-----
From: xxxxx@gmail.com
Sent: Saturday, April 03, 2010 11:08 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] ZwSetSecurityObject does not seem to be working

Thanks Lijun. I can’t believe I missed that.

Ok, so I changed the point of security to be the actual PDO or the first FDO (same effect either place) and using DeviceTree I can see that the disk has the correct permissions on it. However, I can still open the disk as a user and read/write to it. So I’m guessing that I need to secure the partitions as well. Here is what DeviceTree shows under disk for \Driver\Disk specifically for my attached USB storage device. The second DEV is the one I am filtering on and that is the one that shows the modified permissions I have set.

DEV \Device\Harddisk1\DP(1)0-0+3
DEV \Device\Harddisk1\DR2

First question, so how can I find out pointers to all of the partitions available on a specific disk so that I can secure them all in the same manner as I did DR2? For example, say for Harddisk1 there was another partition as well to what is listed above, DP(2)#-#+# (where # are the numbers for the partition).

Second question, if I was able to filter directly above Disk.sys in the devstack instead of above PartMgr would I receive an AddDevice for each partition as well as raw disks since they all show up as DEV under disk? If so how do I achieve that?


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Doron -

You should test your driver with driver verifier on, it would have caught the
&filehandle bug for you. Run your app under process explorer and you might see
different names/handles being opened than you are expecting.

Yes, I normally run with driver verifier on - in this case, I just made a stupid mistake and didn’t have it running.

As for the different names/handles being opened, the driver is opening correctly the ones I had specified. I had been hoping that by changing the permissions say on the PDO disk device, that it would inturn effect all variants of it like the partitions. The handle opened by Explorer which is of type file "E:" would correspond to the partition of DEV \Device\Harddisk1\DP(1)0-0+3.

Which brings me back to my last two questions:

First question, so how can I find out pointers to all of the partitions
available on a specific disk so that I can secure them all in the same manner as
I did DR2? For example, say for Harddisk1 there was another partition as well to
what is listed above, DP(2)#-#+# (where # are the numbers for the partition).

Second question, if I was able to filter directly above Disk.sys in the devstack
instead of above PartMgr would I receive an AddDevice for each partition as well
as raw disks since they all show up as DEV under disk? If so how do I achieve
that?

ok, I answered question #2 though experimentation.

Second question, if I was able to filter directly above Disk.sys in the devstack
instead of above PartMgr would I receive an AddDevice for each partition as well
as raw disks since they all show up as DEV under disk? If so how do I achieve
that?

The answer is no. I modified the registry key manually and prepended my device driver above PartMgr. Everything still operates normally but it does not allow me to “attach” to the dev stacks of the DEV created for the partitions.

Which leaves me with only question 1:
How can I determine the pointers to the various parition devices only for the current disk which I am filtering. For example, if the device is currently filtering DEV \Device\Harddisk1\DR2, how do I get pointers to DEV \Device\Harddisk1\DP(N) where N is some value >= 1 for as many partitions exist for that disk?

I have seen an example written by Deepak that walked the \Driver\Disk stack and finds all raw disks (DR#) and partitions (PR(#)) using:

RtlInitUnicodeString(&DestinationString, L"\Driver\Disk");
if (ObReferenceObjectByName(&DestinationString, 64, 0, 0,*IoDriverObjectType, KernelMode, 0,
&pDiskObject) >= 0) {…}

Is it possible to point to the harddisk I am working on and do something similar? Say only walk that disk and grab its raw disks (DR#) and partitions (PR(#)) using:

RtlStringCbPrintfW(PhysicalDeviceNameBuffer, sizeof(PhysicalDeviceNameBuffer),
L"\Driver\Disk\Harddisk%d", deviceExtension->DiskNumber);
RtlInitUnicodeString(&DestinationString, &PhysicalDeviceNameBuffer[0]);
if (ObReferenceObjectByName(&DestinationString, 64, 0, 0,
*IoDeviceObjectType, KernelMode, 0, &pDisk) >= 0){…}

I am not 100% sure of the parameters for ObReferenceObjectByName, especially for the attributes value of 64 (ie is that appropriate for a PDEVICE_OBJECT instead of a PDRIVER_OBJECT?). *IoDeviceObjectType was found here: http://blogs.msdn.com/doronh/archive/2006/11/20/new-pobject-type-exports-documented-in-the-wdk.aspx and pDisk is a PDEVICE_OBJECT. If this solution works it provides a means to quickly secure all DEV objects for a physical disk drive.

I look forward to your comments.

Brian

Success!! I went with the last concept that I posted and it works! It successfully enforces the Bel LaPadulla security model! WOOHOO!

One remaining question for you. Is there a way to determine what the symbolic name is for an object who’s name is DEV \Device\Harddisk1\DP(1)0-0+3, for example this particular disk’s symbolic name is 'E:'. The reason I ask is I am considering performing an inverted call model and passing the symbolic name to a service running to perfom additional operations.

Brian