2011-04-07 65 views
2

下面是这种情况:
1.应用程序已在运行的本地管理员
2.冒充为域帐户,这是也是本地方框上的管理员
3.模拟时,该应用正试图在对“此密钥和子密钥”具有完全控制管理员组的密钥下创建一个regkey。访问注册表项“......” t被拒绝到模拟的管理

此步骤失败,出现UnauthorizedException“访问注册表项..”被拒绝。 现在,如果我明确地为域用户ACL注册了regkey,那么regkey的创建就会通过。但是这个解决方案打败了管理员组的目的。

任何想法可能会出现什么问题吗?

编辑:我在Windows Server 2008 R2上运行。我想这个问题是由于启用UAC。 LogonUser方法返回受限令牌,该令牌不具有对注册表的高级访问权限。有关如何使用LogonUser方法获得高级访问权的任何想法?

这是我如何称呼它:
IntPtr token = IntPtr.Zero;
LogonUser(username, domain, password, LOGON32_LOGON_BATCH, LOGON32_PROVIDER_DEFAULT, out token)

+0

如果您提到您正在运行这些测试的操作系统,它可能有助于讨论。我的猜测是你最近在做什么,而且一些紧缩的安全规则正在让你失望。 – 2011-04-07 20:14:10

+0

由于该应用程序已经在本地管理员下运行,您是否已考虑在创建注册表项之前恢复该身份? – 2011-04-07 20:23:42

+0

这个应用程序是网络,并从iis运行它? – Mhmd 2011-04-11 21:45:15

回答

3

我会建议几件事情要检查:

  • 您应归功于你的类(即执行模拟)的完全信任模式的要求,你可以使用

    [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")] 
    
  • 此外,你应该导入“advapi32.dl l“和LogonUser稍后使用。

  • 最后,您应该得到一个安全的令牌句柄(继承自SafeHandleZeroOrMinusOneIsInvalid,它为Win32安全句柄实现提供了一个基类,其中0或-1的值表示无效句柄)。 (使用LOGON32_LOGON_INTERACTIVE *由于批处理将无法正常工作*
  • 在这个你应该调用它像这样

    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); 
     } 
    } 
}