场景:
管理员将安装该应用程序。该应用程序具有一些内核级别的操作,因此,它必须以特权模式运行。但是用户没有管理员凭据才能以提升模式运行应用程序。
那么,解决上述情况的最佳可能性是什么?
解决方案一(尝试): 通过管理员安装应用程序时,我们将创建一个管理员,在此我们可以知道他的用户名和密码。因此,当用户尝试执行任何操作时,我们将使用c#中的processstartinfo()和process.start()函数以提升模式运行应用程序。但是,该应用程序以管理员名称运行,因此该用户的映射驱动器不可见,因为该管理员不在ACL列表中。因此,这种方法正在被排除。
在使用c#应用程序完成操作之前,可以提升用户自己作为管理员的解决方案吗?
我被困住了,没有找到任何值得阅读的文章。
编辑: 在企业级别,Windows不会要求使用Bitlocker的管理员身份。因此,我们希望实现相同类型的功能。
有可能吗?
有人可以帮忙吗?
谢谢。
答案 0 :(得分:3)
我所做的解决方案是将程序分为两部分。一部分作为使用管理员特权运行的服务运行,另一部分使用普通特权运行。 这两个程序之间的通信可以通过以太网或共享内存运行。
答案 1 :(得分:0)
我认为您可能会陷入困境,因为您要处理具有权限功能的两个功能,并且这两个功能都必须正确运行您的应用程序。
我注意到您有以下两个:
为了说明这一点...
| File System Path | Application Process
User | OK | --
Admin | -- | OK
解决方案需要看起来像这样...
| File System Path | Application Process
Service | OK | OK
如果可能的话,我想这是最简单的方法,您可以通过该方法创建一个具有执行这两项权限的服务帐户。
答案 2 :(得分:0)
您可以尝试创建具有管理员权限的并行线程以执行内核操作。这样,您的整个程序就包含在一个可执行文件中。
答案 3 :(得分:0)
您可以使用COM+ Component Services。使用.NET,最简单的方法是使用Enterprise Services's ServicedComponent,它具有各种包装程序和实用程序类,可以与COM +组件服务进行互操作。
因此,请按以下步骤操作:
1)创建一个.NET Framework类库。
2)为它添加一个强名称并用它签名
3)例如为它添加一个这样的类(我还添加了一些实用的方法来诊断问题)
[ComVisible(true)]
public class AdminClass : ServicedComponent
{
public int DoSomethingAsAdmin()
{
// test something that a normal user shouldn't see
return Directory.GetFiles(Path.Combine(Environment.SystemDirectory, "config")).Length;
}
public string WindowsIdentityCurrentName => WindowsIdentity.GetCurrent().Name;
public string CurrentProcessFilePath => Process.GetCurrentProcess().MainModule.FileName;
// depending on how you call regsvcs, you can run as a 32 or 64 bit surrogate dllhost.exe
public bool Is64BitProcess => Environment.Is64BitProcess;
}
4)将以下内容添加到AssemblyInfo.cs
[assembly: ApplicationName("AdminApp")]
[assembly: SecurityRole("AdminAppUser")]
[assembly: ApplicationActivation(ActivationOption.Server)]
这是定义一个名为“ AdminApp”的COM +应用程序,向其中添加一个名为“ AdminAppUser”的角色,然后声明该应用程序将作为“服务器”运行,这意味着“进程外”。
5)进行编译并以admin身份运行此命令
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regsvcs.exe AdminApp.dll
或此命令:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\regsvcs.exe AdminApp.dll
这两个命令都将创建COM +应用程序,并将.NET库DLL托管在代理.exe(dllhost.exe)中。如果选择第一个,则托管进程将以x64运行,如果选择第二个,则托管进程将以x86运行。
如果您运行组件服务(从Windows / Run),则可以检查此注册的结果:
6)右键单击该应用程序,您会看到一大堆可以配置的很棒的东西。请注意,您甚至可以将其作为服务运行(在“激活”标签中),等等。您必须做的是配置将运行此过程的身份,如下所示:
在这里,我使用了自定义管理员帐户。您不想使用其他任何内置选项。
7)现在,由于已启用默认安全性,因此基本上没有人可以调用此组件。因此,我们只需要向先前创建的角色“ AdminAppUser”添加用户即可。您当然可以使用如下所示的UI进行此操作:
但这是一段以编程方式执行此操作的代码(我们使用COM+ administration objects):
AddUserInRole("AdminApp", "AdminAppUser", @"SMO01\simon");
....
static void AddUserInRole(string appName, string roleName, string userName)
{
dynamic catalog = Activator.CreateInstance(Type.GetTypeFromProgID("COMAdmin.COMAdminCatalog"));
// the list of collection hierarchy : https://docs.microsoft.com/en-us/windows/desktop/cossdk/com--administration-collections
var apps = catalog.GetCollection("Applications");
var app = GetCollectionItem(apps, appName);
if (app == null)
throw new Exception("Application '" + appName + "' was not found.");
var roles = apps.GetCollection("Roles", app.Key);
var role = GetCollectionItem(roles, roleName);
if (role == null)
throw new Exception("Role '" + roleName + "' was not found.");
// UsersInRole collection
// https://docs.microsoft.com/en-us/windows/desktop/cossdk/usersinrole
var users = roles.GetCollection("UsersInRole", role.Key);
var user = GetCollectionItem(users, userName);
if (user == null)
{
user = users.Add();
user.Value["User"] = userName;
users.SaveChanges();
}
}
static dynamic GetCollectionItem(dynamic collection, string name)
{
collection.Populate();
for (int i = 0; i < collection.Count; i++)
{
var item = collection.Item(i);
if (item.Name == name)
return item;
}
return null;
}
结果应该是这样的:
8)现在,对于客户端应用程序,使用AdminApp工具很容易。不要将.DLL引用为标准.NET引用,而应将其用作任何其他外部COM组件。您可以引用由regsvcs创建的.TLB文件,或者仅使用我在此处演示的magic动态关键字(缺点是您无法自动完成):
using System;
using System.Security.Principal;
namespace UserApp
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Is64BitProcess " + Environment.Is64BitProcess);
Console.WriteLine("Running As " + WindowsIdentity.GetCurrent().Name);
var type = Type.GetTypeFromProgID("AdminApp.AdminClass");
dynamic trustedClass = Activator.CreateInstance(type);
Console.WriteLine("Admin App Process Path: " + trustedClass.CurrentProcessFilePath);
Console.WriteLine("Admin App Running As: " + trustedClass.WindowsIdentityCurrentName);
Console.WriteLine("Admin App Is64BitProcess: " + trustedClass.Is64BitProcess);
Console.WriteLine("Admin App DoSomethingAsAdmin: " + trustedClass.DoSomethingAsAdmin());
}
}
}
现在,当您将其作为“ simon”运行时,您应该会看到类似的内容,它可以正常工作:
Is64BitProcess False
Running As SMO01\simon
Admin App Process Path: C:\WINDOWS\system32\dllhost.exe
Admin App Running As: SMO01\myAdmin
Admin App Is64BitProcess: True
Admin App DoSomethingAsAdmin: 71
例如,当您以未配置角色的“ bob”身份运行它时,您应该看到类似这样的内容,但访问被拒绝,这是预期的:
Is64BitProcess False
Running As SMO01\bob
Unhandled Exception: System.UnauthorizedAccessException: Retrieving the COM class factory for component with CLSID {0DC1F11A-A187-3B6D-9888-17E635DB0974} failed due to the following error: 80070005 Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)).
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
at System.Activator.CreateInstance(Type type, Boolean nonPublic)
at System.Activator.CreateInstance(Type type)
at UserApp.Program.Main(String[] args) in C:\Users\simon\source\repos\TrustedSystem\UserApp\Program.cs:line 14
请注意,我们创建了一个受信任的系统,而没有在任何地方设置任何密码。而且,我只是简单介绍了COM +组件的功能。例如,您可以将应用程序导出为.MSI,以便于部署等。