Доступ к разделу реестра запрещен для выдающегося администратора

Вот сценарий:
1. Приложение уже запущено как локальный администратор.
2. Оно выдает себя за учетную запись домена, которая также является администратором локального компьютера.
3. Пока вы олицетворяетесь, приложение пытается создать regkey под ключом, имеющим полный доступ к группе администраторов для «этого ключа и подразделов».

Этот шаг завершается ошибкой UnauthorizedException «Доступ к разделу реестра ..» запрещен. Теперь, если я явно ACL для регистрационного ключа для пользователя домена, создание regkey будет выполнено. Но тогда это решение побеждает цель нахождения в группе администраторов.

Есть идеи, что здесь может пойти не так?

РЕДАКТИРОВАТЬ: я работаю на Windows Server 2008 R2. Я подумал, что эта проблема связана с включенным UAC. Метод LogonUser возвращает ограниченный токен, у которого нет повышенных прав доступа к реестру. Есть идеи о том, как получить повышенный доступ с помощью метода LogonUser?

Вот как я это называю:
IntPtr token = IntPtr.Zero;
LogonUser(username, domain, password, LOGON32_LOGON_BATCH, LOGON32_PROVIDER_DEFAULT, out token)


person kateroh    schedule 07.04.2011    source источник
comment
Возможно, обсуждение поможет, если вы упомянули, в какой операционной системе вы запускаете эти тесты. Я предполагаю, что вы работаете с чем-то недавним, и вам мешает ужесточение правил безопасности.   -  person Frank Boyne    schedule 08.04.2011
comment
Поскольку приложение уже запущено под локальным администратором, рассматривали ли вы возможность просто вернуться к этому идентификатору перед созданием раздела реестра?   -  person Frank Boyne    schedule 08.04.2011
comment
это приложение является веб-приложением и запускать его из iis?   -  person Mhmd    schedule 12.04.2011


Ответы (1)


Я предлагаю проверить несколько вещей:

  • Вы должны указать свой класс (который выполняет олицетворение) для запроса режима полного доверия, что вы можете сделать, используя

    [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
    
  • Кроме того, вы должны импортировать "advapi32.dll" и LogonUser, чтобы использовать их позже.

  • Наконец, вы должны получить безопасный дескриптор маркера (унаследованный от SafeHandleZeroOrMinusOneIsInvalid, который предоставляет базовый класс для реализаций безопасного дескриптора Win32, в котором значение 0 или -1 указывает на недопустимый дескриптор).
  • В этом случае вы должны называть это так (* используя LOGON32_LOGON_INTERACTIVE, поскольку BATCH не будет работать *)

    LogonUser(userName, domainName, password, 2, 0, out safeTokenHandle);
    

Получив дескриптор, вы должны использовать его для выполнения любых действий:

    WindowsIdentity impid = new WindowsIdentity(safeTokenHandle.DangerousGetHandle());

После его получения инкапсулируйте свои действия:

    using (WindowsImpersonationContext imp = impid.Impersonate())
    { 
      // myActions
    }

Это должно позволить вам сделать это правильно и определить, как все прошло.

Я попытался сделать это в приложении ASP.NET, и мне это удалось. Вот рабочий код для контроллера приложения MVC:

using System;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Security.Principal;
using System.Web.Mvc;
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;

namespace StackOimpersonationExample.Controllers
{
    [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
    public class HomeController : Controller
    {
        [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
                                            int dwLogonType, int dwLogonProvider, out TokenHandle phToken);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern bool CloseHandle(IntPtr handle);

        public ActionResult Index()
        {
            ViewBag.Message = "This line contains status info.";


            #region ImpersonateTestUserAndWriteToRegistry

            try
            {
                const string domainName = "W8CP";
                const string userName = "testadmin";
                const string password = "sxt";

                TokenHandle tokenHandle;
                bool returnValue = LogonUser(userName, domainName, password, 2, 0, out tokenHandle);

                if (returnValue == false)
                {
                    int retVal = Marshal.GetLastWin32Error();
                    ViewBag.Message = String.Format("Failed logon: {0}", retVal);
                    throw new System.ComponentModel.Win32Exception(retVal);
                }
                using (tokenHandle)
                {
                    ViewBag.Message = "Logon successful!";
                    var newId = new WindowsIdentity(tokenHandle.DangerousGetHandle());
                    using (newId.Impersonate())
                    {
                        RegistryKey parentKey = Registry.LocalMachine;
                        RegistryKey softwareKey = parentKey.OpenSubKey("SOFTWARE", true);
                        if (softwareKey != null)
                        {
                            RegistryKey subKey = softwareKey.CreateSubKey("StackAnswer");

                            subKey.SetValue("CreatedAs", WindowsIdentity.GetCurrent().Name, RegistryValueKind.String);
                            subKey.SetValue("Website", "http://codecentral.org", RegistryValueKind.String);
                            subKey.SetValue("Email", "[email protected]", RegistryValueKind.String);

                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ViewBag.Message += String.Format(" Exception: " + ex.Message);
            }
            #endregion

            return View();
        }
    }

    public sealed class TokenHandle : SafeHandleZeroOrMinusOneIsInvalid
    {
        private TokenHandle(): base(true){}

        [DllImport("kernel32.dll")]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        [SuppressUnmanagedCodeSecurity]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CloseHandle(IntPtr handle);

        protected override bool ReleaseHandle()
        {
            return CloseHandle(handle);
        }
    }
}
person Tonči Jukić    schedule 03.03.2012