以下是该情景:
1.该应用已作为本地管理员运行
2.它冒充域名帐户,也是本地方框的管理员
3.在模拟时,应用程序正在尝试在“管理员”组的“此键和子项”的“完全控制”键下创建一个注册表。
此步骤因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 :(得分:3)
我会建议几件事要检查:
您应该将您的类(执行模拟)归因于完全信任模式请求,您可以使用
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
此外,您应该导入“advapi32.dll”和LogonUser以供日后使用。
在此之内你应该像这样调用它( *使用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", "tonci.jukic@gmail.com", 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);
}
}
}