2011-04-07 67 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); 
     } 
    } 
}