Exemple #1
0
        static bool StartedInCage()
        {
            IntPtr security_descriptor         = IntPtr.Zero;
            IntPtr entries_pointer             = IntPtr.Zero;
            bool   desktop_access_right_status = false;

            try
            {
                var desktop = NativeMethods.GetThreadDesktop(NativeMethods.GetCurrentThreadId());
                if (desktop == IntPtr.Zero)
                {
                    throw new NativeCallException("Failed to retrieve desktop handle.");
                }

                IntPtr owner_sid = IntPtr.Zero;
                IntPtr group_sid = IntPtr.Zero;
                IntPtr dacl;
                IntPtr sacl = IntPtr.Zero;

                if (NativeMethods.GetSecurityInfo(
                        desktop,
                        NativeMethods.SE_OBJECT_TYPE.SE_WINDOW_OBJECT,
                        NativeMethods.SECURITY_INFORMATION.DACL_SECURITY_INFORMATION,
                        out owner_sid,
                        out group_sid,
                        out dacl,
                        out sacl,
                        out security_descriptor) != 0)
                {
                    throw new NativeCallException("Failed to retrieve security info.");
                }

                ulong entry_count = 0;
                if (NativeMethods.GetExplicitEntriesFromAclW(dacl, ref entry_count, out entries_pointer) != 0)
                {
                    throw new NativeCallException("Failed to retrieve acl entries.");
                }

                if (entry_count == 3)
                {
                    bool system_sid_correct_access = false;
                    bool admin_sid_correct_access  = false;
                    bool shark_sid_correct_access  = false;

                    IntPtr shark_entry  = entries_pointer;
                    IntPtr admin_entry  = IntPtr.Add(shark_entry, Marshal.SizeOf(typeof(NativeMethods.EXPLICIT_ACCESS)));
                    IntPtr system_entry = IntPtr.Add(admin_entry, Marshal.SizeOf(typeof(NativeMethods.EXPLICIT_ACCESS)));

                    NativeMethods.EXPLICIT_ACCESS ea_shark  = (NativeMethods.EXPLICIT_ACCESS)Marshal.PtrToStructure(shark_entry, typeof(NativeMethods.EXPLICIT_ACCESS));
                    NativeMethods.EXPLICIT_ACCESS ea_admin  = (NativeMethods.EXPLICIT_ACCESS)Marshal.PtrToStructure(admin_entry, typeof(NativeMethods.EXPLICIT_ACCESS));
                    NativeMethods.EXPLICIT_ACCESS ea_system = (NativeMethods.EXPLICIT_ACCESS)Marshal.PtrToStructure(system_entry, typeof(NativeMethods.EXPLICIT_ACCESS));

                    const int GRANT_ACCESS   = 1;
                    const int NO_INHERITANCE = 0;

                    if (ea_shark.Trustee.TrusteeForm == NativeMethods.TRUSTEE_FORM.TRUSTEE_IS_SID)
                    {
                        const NativeMethods.DESKTOP_ACCESS_RIGHTS desired_shark_permissions = NativeMethods.DESKTOP_ACCESS_RIGHTS.DESKTOP_READOBJECTS
                                                                                              | NativeMethods.DESKTOP_ACCESS_RIGHTS.DESKTOP_CREATEWINDOW
                                                                                              | NativeMethods.DESKTOP_ACCESS_RIGHTS.DESKTOP_CREATEMENU
                                                                                              | NativeMethods.DESKTOP_ACCESS_RIGHTS.DESKTOP_HOOKCONTROL
                                                                                              | NativeMethods.DESKTOP_ACCESS_RIGHTS.DESKTOP_JOURNALRECORD
                                                                                              | NativeMethods.DESKTOP_ACCESS_RIGHTS.DESKTOP_JOURNALPLAYBACK
                                                                                              | NativeMethods.DESKTOP_ACCESS_RIGHTS.DESKTOP_ENUMERATE
                                                                                              | NativeMethods.DESKTOP_ACCESS_RIGHTS.DESKTOP_WRITEOBJECTS;

                        if ((ea_shark.grfAccessPermissions & (uint)desired_shark_permissions) == (uint)desired_shark_permissions &&
                            (ea_shark.grfAccessPermissions & (~((uint)desired_shark_permissions))) == 0 &&
                            ea_shark.grfAccessMode == GRANT_ACCESS &&
                            ea_shark.grfInheritance == NO_INHERITANCE)
                        {
                            shark_sid_correct_access = true;
                        }
                    }

                    if (ea_admin.Trustee.TrusteeForm == NativeMethods.TRUSTEE_FORM.TRUSTEE_IS_SID)
                    {
                        const int nt_security_authority       = 5;
                        const int security_builtin_domain_rid = 32;
                        const int domain_alias_rid_admins     = 544;
                        var       nt_authority = new NativeMethods.SidIdentifierAuthority();
                        nt_authority.Value = new byte[] { 0, 0, 0, 0, 0, nt_security_authority };

                        IntPtr admin_sid = IntPtr.Zero;
                        if (!NativeMethods.AllocateAndInitializeSid(
                                ref nt_authority,
                                2,
                                security_builtin_domain_rid,
                                domain_alias_rid_admins,
                                0,
                                0,
                                0,
                                0,
                                0,
                                0,
                                out admin_sid))
                        {
                            throw new NativeCallException("Failed to allocate or initialize admin security identifier.");
                        }

                        if (ea_admin.Trustee.ptstrName == IntPtr.Zero)
                        {
                            throw new NativeCallException("Failed to retrieve admin sid.");
                        }
                        else if (NativeMethods.EqualSid(ea_admin.Trustee.ptstrName, admin_sid))
                        {
                            NativeMethods.DESKTOP_ACCESS_RIGHTS desired_admin_permissions = NativeMethods.DESKTOP_ACCESS_RIGHTS.DELETE
                                                                                            | NativeMethods.DESKTOP_ACCESS_RIGHTS.DESKTOP_ENUMERATE
                                                                                            | NativeMethods.DESKTOP_ACCESS_RIGHTS.READ_CONTROL
                                                                                            | NativeMethods.DESKTOP_ACCESS_RIGHTS.WRITE_DAC
                                                                                            | NativeMethods.DESKTOP_ACCESS_RIGHTS.WRITE_OWNER;

                            if ((ea_admin.grfAccessPermissions & (uint)desired_admin_permissions) == (uint)desired_admin_permissions &&
                                (ea_admin.grfAccessPermissions & (~((uint)desired_admin_permissions))) == 0 &&
                                ea_admin.grfAccessMode == GRANT_ACCESS &&
                                ea_admin.grfInheritance == NO_INHERITANCE)
                            {
                                admin_sid_correct_access = true;
                            }
                        }

                        if (admin_sid != IntPtr.Zero)
                        {
                            NativeMethods.FreeSid(admin_sid);
                        }
                    }

                    if (ea_system.Trustee.TrusteeForm == NativeMethods.TRUSTEE_FORM.TRUSTEE_IS_SID)
                    {
                        const int nt_security_authority     = 5;
                        const int security_local_system_rid = 18;
                        var       nt_authority = new NativeMethods.SidIdentifierAuthority();
                        nt_authority.Value = new byte[] { 0, 0, 0, 0, 0, nt_security_authority };

                        IntPtr system_sid = IntPtr.Zero;
                        if (!NativeMethods.AllocateAndInitializeSid(ref nt_authority,
                                                                    1,
                                                                    security_local_system_rid,
                                                                    0,
                                                                    0,
                                                                    0,
                                                                    0,
                                                                    0,
                                                                    0,
                                                                    0,
                                                                    out system_sid))
                        {
                            throw new NativeCallException("Failed to allocate or initialize system security identifier.");
                        }

                        if (ea_system.Trustee.ptstrName == IntPtr.Zero)
                        {
                            throw new NativeCallException("Failed to retrieve system sid.");
                        }
                        else if (NativeMethods.EqualSid(ea_system.Trustee.ptstrName, system_sid))
                        {
                            const NativeMethods.DESKTOP_ACCESS_RIGHTS desired_system_permissions = NativeMethods.DESKTOP_ACCESS_RIGHTS.DELETE
                                                                                                   | NativeMethods.DESKTOP_ACCESS_RIGHTS.DESKTOP_READOBJECTS
                                                                                                   | NativeMethods.DESKTOP_ACCESS_RIGHTS.DESKTOP_CREATEWINDOW
                                                                                                   | NativeMethods.DESKTOP_ACCESS_RIGHTS.DESKTOP_CREATEMENU
                                                                                                   | NativeMethods.DESKTOP_ACCESS_RIGHTS.DESKTOP_HOOKCONTROL
                                                                                                   | NativeMethods.DESKTOP_ACCESS_RIGHTS.DESKTOP_JOURNALRECORD
                                                                                                   | NativeMethods.DESKTOP_ACCESS_RIGHTS.DESKTOP_JOURNALPLAYBACK
                                                                                                   | NativeMethods.DESKTOP_ACCESS_RIGHTS.DESKTOP_ENUMERATE
                                                                                                   | NativeMethods.DESKTOP_ACCESS_RIGHTS.DESKTOP_WRITEOBJECTS
                                                                                                   | NativeMethods.DESKTOP_ACCESS_RIGHTS.DESKTOP_SWITCHDESKTOP
                                                                                                   | NativeMethods.DESKTOP_ACCESS_RIGHTS.READ_CONTROL
                                                                                                   | NativeMethods.DESKTOP_ACCESS_RIGHTS.WRITE_DAC
                                                                                                   | NativeMethods.DESKTOP_ACCESS_RIGHTS.WRITE_OWNER;

                            if ((ea_system.grfAccessPermissions & (uint)desired_system_permissions) == (uint)desired_system_permissions &&
                                (ea_system.grfAccessPermissions & (~((uint)desired_system_permissions))) == 0 &&
                                ea_system.grfAccessMode == GRANT_ACCESS &&
                                ea_system.grfInheritance == NO_INHERITANCE)
                            {
                                system_sid_correct_access = true;
                            }
                        }

                        if (system_sid != IntPtr.Zero)
                        {
                            NativeMethods.FreeSid(system_sid);
                        }
                    }

                    if (system_sid_correct_access && admin_sid_correct_access && shark_sid_correct_access)
                    {
                        desktop_access_right_status = true;
                    }
                }
            }
            catch (Exception e)
            {
                MessageBox.Show("Could not determine on which desktop the process is running: " + e.ToString());
                Environment.Exit(1);
            }
            finally
            {
                NativeMethods.LocalFree(entries_pointer);
                NativeMethods.LocalFree(security_descriptor);
            }

            return(desktop_access_right_status);
        }
        public bool AddDirectorySecurity(
            string fileOrFolder,
            string userAccount,
            FileSystemRights requestedRights,
            AccessControlType controlType,
            InheritanceFlags inheritFlag = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
            PropagationFlags propFlag    = PropagationFlags.None,
            bool forcePermissions        = false)
        {
            try
            {
                if (File.Exists(fileOrFolder))
                {
                    var fInfo     = new FileInfo(fileOrFolder);
                    var fSecurity = fInfo.GetAccessControl();
                    fSecurity.SetAccessRuleProtection(false, true);
                    fSecurity.AddAccessRule(new FileSystemAccessRule(userAccount, requestedRights, controlType));
                    fInfo.SetAccessControl(fSecurity);
                }
                else if (Directory.Exists(fileOrFolder))
                {
                    var dInfo     = new DirectoryInfo(fileOrFolder);
                    var dSecurity = dInfo.GetAccessControl();
                    //dSecurity.SetAccessRuleProtection(false, true); // This option appears to flip the enable/disable inheritance option.
                    dSecurity.AddAccessRule(new FileSystemAccessRule(userAccount, requestedRights, inheritFlag, propFlag, controlType));
                    dInfo.SetAccessControl(dSecurity);
                }
                else
                {
                    _logger.Log($"Specified file or folder [{fileOrFolder}] does not exist.", Logger.MsgType.ERROR);
                    return(false);
                }

                return(true);
            }
            catch (Exception e)
            {
                // Force permissions? (e.g. take ownership and try again)
                if (forcePermissions)
                {
                    if (!NativeMethods.OpenProcessToken(
                            Process.GetCurrentProcess().Handle,
                            NativeMethods.TOKEN_ALL_ACCESS,
                            out IntPtr hToken))
                    {
                        _logger.Log("Unable to open specified process token [OpenProcessToken=" +
                                    Marshal.GetLastWin32Error().ToString() + "].");
                        return(false);
                    }

                    if (!new WindowsHelper(_logger).EnablePrivilege(hToken, NativeMethods.SE_TAKE_OWNERSHIP_NAME))
                    {
                        _logger.Log("Failed to enable privilege [SeTakeOwnershipPrivilege].", Logger.MsgType.ERROR);
                        Marshal.FreeHGlobal(hToken);
                        return(false);
                    }

                    // Administrators group trustee control information.
                    NativeMethods.EXPLICIT_ACCESS adminGroupAccess = new NativeMethods.EXPLICIT_ACCESS();
                    NativeMethods.BuildExplicitAccessWithName(
                        ref adminGroupAccess,
                        "Administrators",
                        NativeMethods.ACCESS_MASK.GENERIC_ALL,
                        NativeMethods.ACCESS_MODE.SET_ACCESS,
                        NativeMethods.NO_INHERITANCE);

                    IntPtr acl = IntPtr.Zero;
                    NativeMethods.SetEntriesInAcl(1, ref adminGroupAccess, IntPtr.Zero, ref acl);

                    // Allocate SID -- BUILTIN\Administrators.
                    NativeMethods.SID_IDENTIFIER_AUTHORITY sidNTAuthority = NativeMethods.SECURITY_NT_AUTHORITY;
                    IntPtr sidAdministrators = IntPtr.Zero;
                    NativeMethods.AllocateAndInitializeSid(ref sidNTAuthority,
                                                           2,
                                                           NativeMethods.SECURITY_BUILTIN_DOMAIN_RID,
                                                           NativeMethods.DOMAIN_ALIAS_RID_ADMINS,
                                                           0, 0, 0, 0, 0, 0,
                                                           ref sidAdministrators);

                    // Set the owner in the object's security descriptor.
                    NativeMethods.SetNamedSecurityInfo(
                        fileOrFolder,
                        NativeMethods.SE_OBJECT_TYPE.SE_FILE_OBJECT,
                        NativeMethods.SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION,
                        sidAdministrators,
                        IntPtr.Zero,
                        IntPtr.Zero,
                        IntPtr.Zero);

                    /*// Modify the object's DACL.
                     * NativeMethods.SetNamedSecurityInfo(
                     *  fileOrFolder,
                     *  NativeMethods.SE_OBJECT_TYPE.SE_FILE_OBJECT,
                     *  NativeMethods.SECURITY_INFORMATION.DACL_SECURITY_INFORMATION,
                     *  IntPtr.Zero,
                     *  IntPtr.Zero,
                     *  acl,
                     *  IntPtr.Zero);*/

                    NativeMethods.FreeSid(sidAdministrators);
                    NativeMethods.LocalFree(acl);

                    return(AddDirectorySecurity(fileOrFolder, userAccount, requestedRights, controlType, inheritFlag, propFlag, false));
                }
                else
                {
                    _logger.Log(e, "Failed to add filesystem permissions to [" + fileOrFolder + "].");
                    return(false);
                }
            }
        }