サービスをローカルシステムアカウントとしてログインしているWindowsサービスで、ドメインユーザーを偽装しようとしています。Windowsサービスの偽装ユーザー
これまでのところ、サービスをログに記録し、次のようなユーザーの資格情報を使用してプロセスを設定するだけで、これを動作させることができました。
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = CommandDetails.Command;
startInfo.WorkingDirectory = Settings.RoboCopyWorkingDirectory;
startInfo.Arguments = commandLine;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardOutput = true;
// Credentials
startInfo.Domain = ImperDomain;
startInfo.UserName = ImperUsername;
startInfo.Password = ImperPasswordSecure;
process = Process.Start(startInfo);
私の目標は、ドメインがパスワードをリセットを取得アカウントので、ドメインユーザーではなく、ローカルシステムとしてサービスのログを持っていないことです。
私は、ローカルシステムを使用する場合は、私が取得アクセスはこれを実現する方法をどのように
任意のアイデアを拒否されましたか?
StackTace
Access is denied
at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo)
at System.Diagnostics.Process.Start()
at System.Diagnostics.Process.Start(ProcessStartInfo startInfo)
at Ace.WindowsService.ProcessCmd.ProcessCommand.StartProcess(ProcessStartInfo startInfo) in
ノー成功して以下に記載されている偽装コードでコードをラップしようとしています。
偽装コード
public class Impersonation2 : IDisposable
{
private WindowsImpersonationContext _impersonatedUserContext;
// Declare signatures for Win32 LogonUser and CloseHandle APIs
[DllImport("advapi32.dll", SetLastError = true)]
static extern bool LogonUser(
string principal,
string authority,
string password,
LogonSessionType logonType,
LogonProvider logonProvider,
out IntPtr token);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool CloseHandle(IntPtr handle);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern int DuplicateToken(IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool RevertToSelf();
// ReSharper disable UnusedMember.Local
enum LogonSessionType : uint
{
Interactive = 2,
Network,
Batch,
Service,
NetworkCleartext = 8,
NewCredentials
}
// ReSharper disable InconsistentNaming
enum LogonProvider : uint
{
Default = 0, // default for platform (use this!)
WinNT35, // sends smoke signals to authority
WinNT40, // uses NTLM
WinNT50 // negotiates Kerb or NTLM
}
// ReSharper restore InconsistentNaming
// ReSharper restore UnusedMember.Local
/// <summary>
/// Class to allow running a segment of code under a given user login context
/// </summary>
/// <param name="user">domain\user</param>
/// <param name="password">user's domain password</param>
public Impersonation2(string domain, string username, string password)
{
var token = ValidateParametersAndGetFirstLoginToken(username, domain, password);
var duplicateToken = IntPtr.Zero;
try
{
if (DuplicateToken(token, 2, ref duplicateToken) == 0)
{
throw new Exception("DuplicateToken call to reset permissions for this token failed");
}
var identityForLoggedOnUser = new WindowsIdentity(duplicateToken);
_impersonatedUserContext = identityForLoggedOnUser.Impersonate();
if (_impersonatedUserContext == null)
{
throw new Exception("WindowsIdentity.Impersonate() failed");
}
}
finally
{
if (token != IntPtr.Zero)
CloseHandle(token);
if (duplicateToken != IntPtr.Zero)
CloseHandle(duplicateToken);
}
}
private static IntPtr ValidateParametersAndGetFirstLoginToken(string domain, string username, string password)
{
if (!RevertToSelf())
{
throw new Exception("RevertToSelf call to remove any prior impersonations failed");
ErrorLogger.LogEvent("RevertToSelf call to remove any prior impersonations failed", System.Diagnostics.EventLogEntryType.Error, "");
}
IntPtr token;
var result = LogonUser(domain, username,
password,
LogonSessionType.Interactive,
LogonProvider.Default,
out token);
if (!result)
{
var errorCode = Marshal.GetLastWin32Error();
ErrorLogger.LogEvent(string.Format("Could not impersonate the elevated user. LogonUser: {2}\\{1} returned error code: {0}.", errorCode, username, domain), System.Diagnostics.EventLogEntryType.Error, "");
throw new Exception("Logon for user " + username + " failed.");
}
return token;
}
public void Dispose()
{
// Stop impersonation and revert to the process identity
if (_impersonatedUserContext != null)
{
_impersonatedUserContext.Undo();
_impersonatedUserContext = null;
}
}
更新
私はちょうどそれを実行していた場合、私はちょうど実行している場合、これが正常に動作します。それがサービスとして実行されている場合しかし、それは動作しません
アップデート2
私はLogonSessionType.NewCredentialsになりすましログインを変更し、削除するときProcess.Startから拒否されたアクセス権を取得しておりませんプロセスからの信憑性。しかし、robocopyコマンドを実行するとエラーが表示されるようになりました。私は、プロセスの資格情報を持っているとき、それはrobocopyをコマンド
エラー
2016/07/16 09:19:12 ERROR 5 (0x00000005)
Accessing Source Directory \\[server]\[path]\
Access is denied.
変更
var result = LogonUser(domain, username,
password,
LogonSessionType.NewCredentials,
LogonProvider.Default,
out token);
アップデート3
からログファイルを生成しません。コピー機能と移動機能が動作しています。しかし、サブプロセスを作成することはできません。 Hary Johnstonが提案しているように、私はCreateProcessAsUserで遊んでいました。
サービスがローカルシステムとして実行されており、サービスがドメインユーザーのアカウントを使用して別のプロセスを開始しているとしますか? – wablab
もしそうなら、この質問はおそらくhttp://stackoverflow.com/questions/559719/windows-impersonation-from-c-sharpの複製である – wablab
「アクセスが拒否されました」というエラーを引き起こすコード行はありますか? –