'File Security permissions and inheritance writing file during installation
I have some data that I want to use from a process which will run as NT_AUTHORITY\SYSTEM. The data I want to save I want to hide from regular users. So, I create a directory like this during installation during the InstallExecute sequence (it is deferred and not impersonating, so should be running as SYSTEM):
static string CreateProtectedDirectory(string name)
{
string programData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
var blah = Path.Combine(programData, "Blah");
var blahInfo = new DirectoryInfo(blah);
if (!blahInfo.Exists)
blahInfo.Create();
var finalPathInfo = new DirectoryInfo(Path.Combine(blah, name));
if (!finalPathInfo.Exists)
{
// create with
DirectorySecurity ds = new DirectorySecurity();
var administratorsSID = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null);
var systemSID = new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null);
var rule1 = new FileSystemAccessRule(administratorsSID, FileSystemRights.FullControl, AccessControlType.Allow);
var rule2 = new FileSystemAccessRule(systemSID, FileSystemRights.FullControl, AccessControlType.Allow);
ds.AddAccessRule(rule1);
ds.AddAccessRule(rule2);
ds.SetAccessRuleProtection(true, false);
finalPathInfo.Create(ds);
}
return finalPathInfo.ToString();
}
After creating the directory, I write data to it, like this:
var protectedPath = CreateProtectedDirectory("blah2"); // c:\programdata\blah\blah2 where blah2 is protected
var filename = Path.Combine(protectedPath, "blahdata.dat");
var bytes = Encoding.ASCII.GetBytes("ABC123xyz");
File.WriteAllBytes(filename, bytes);
My understanding is that when I create c:\ProgramData\blah directory, that it is readable and writeable from anyone because without a security descriptor when creating it, it just inherits from c:\ProgramData. So, when I create c:\ProgramData\blah\blah2, I specifically set security on it.
When I go to PowerShell and try to view c:\ProgramData\blah\blah2 directory it does not allow me unless I elevate. That all makes sense to me. If I run an elevated PowerShell and switch to that directory and do a dir on the contents, I can see the 'blahdata.dat' file. I can even delete it. However, if I try to copy it or do a Get-Content on the file, I get a security permissions error.
That is surprising to me. Since I have permissions for the blah2 directory, I thought I would have full permissions for the blahdata.dat file within it. But, I do not. It is strange to me that I can delete the file, but not copy or view contents (obviously, copying needs to view contents). So, for some reason, I do not have read permissions on that file.
I killed explorer and re-started it elevated, trying to get more details on the file. It's not clear that it has an owner. Maybe the owner is SYSTEM or ???
I have one other head scratching part. I have basically the same code running in a Service which is running as the LocalSystem. Files created from that service I can view in an elevated process whereas the ones created during the InstallExecute sequence in the installer I cannot view. I have read somewhere that services have a service account associated with files that they create. IDK if that's true or if it makes a difference on who the owner is.
Is there a simple explanation for why the file can be deleted but not read when it is created like in the code above.
===========================
Further info on permissions. When file created during install, file permissions appear like:
Owner : NT AUTHORITY\SYSTEM
Group : NT AUTHORITY\SYSTEM
Access : OWNER RIGHTS Allow ReadPermissions
NT AUTHORITY\SYSTEM Allow FullControl
NT SERVICE\msiserver Allow FullControl
Audit :
Sddl : O:SYG:SYD:(A;;RC;;;OW)(A;;FA;;;SY)(A;;FA;;;S-1-5-80-685333868-2237257676-1431965530-1907094206-2438021966)
When same basic code run on a process running as SYSTEM, permissions are:
Owner : BUILTIN\Administrators
Group : NT AUTHORITY\SYSTEM
Access : NT AUTHORITY\SYSTEM Allow FullControl
BUILTIN\Administrators Allow ReadAndExecute, Synchronize
Audit :
Sddl : O:BAG:SYD:(A;;FA;;;SY)(A;;0x1200a9;;;BA)
You can see when created running under the installer, the owner is the SYSTEM account (and the msiserver account has access). When running under a system process, the owner is the Administrators group.
For the permissions of the directory that the file is under, the permissions for the directory created under the installer are:
Owner : NT AUTHORITY\SYSTEM
Group : NT AUTHORITY\SYSTEM
Access : NT AUTHORITY\SYSTEM Allow FullControl
BUILTIN\Administrators Allow FullControl
Audit :
Sddl : O:SYG:SYD:P(A;;FA;;;SY)(A;;FA;;;BA)
Permissions for the directory created when running as a SYSTEM process:
Owner : BUILTIN\Administrators
Group : BUILTIN\Administrators
Access : NT AUTHORITY\SYSTEM Allow FullControl
BUILTIN\Administrators Allow FullControl
Audit :
Sddl : O:BAG:BAD:P(A;;FA;;;SY)(A;;FA;;;BA)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
