Ребята, подскажите как можно передать security token из одного процесса в другой ? По идее же это объект ядра и работать должно.
У меня два приложения UI и Windows Service, пишу на C#, но в принципе я думаю код будет понятен всем. В UI приложении получаю token так:
private static bool GetImpersonationToken(out IntPtr token)
{
token = IntPtr.Zero;
IntPtr tempToken;
if (OpenProcessToken(GetCurrentProcess(), TokenImpersonate | TokenQuery | TokenDuplicate, out tempToken))
{
var sa = new SecurityAttributes { bInheritHandle = false };
sa.Length = Marshal.SizeOf(sa);
sa.lpSecurityDescriptor = (IntPtr)0;
// duplicate the token (this is necessary to convert the impersonated token to a primary token)return DuplicateTokenEx(
tempToken,
0x000f01ff /* all access */,
ref sa,
/* ImpersonationLevel = SecurityImpersonation */2,
/* TokenType = TokenImpersonation */ 2,
ref token);
}
return false;
}
полученный token перекидываю по named pipe в мой Windows сервис который крутится под пользователем Local System и пытаюсь вызвать на него ImpersonateLoggedOnUser. Получаю ошибку 6, что мой HANDLE корявый. Я пробовал вызвать ImpersonateLoggedOnUser на полученный токен сразу же в том же UI приложении, оно работает.
Заранее спасибо!
Re: ImpersonateLoggedOnUser даёт ошибку 6 (ERROR_INVALID_HAN
Хендлы уникальны в пределах процесса, а не системы. Ты передаёшь значение хендла из одного процесса в другой, но этого недостаточно, необходимо скопировать сам хендл из таблицы хендлов исходного процесса (в твоём случае, UI-приложение) в таблицу хендлов целевого процесса (в твоём случае, служба). Для этого следует воспользоваться DuplicateHandle(), а для этого, в свою очередь, у тебя должен быть хендл исходного процесса с соответствующими правами. Ну и наконец, полученный в результате копирования хендл уже можно будет использовать в контексте твоего целевого процесса (служба). Что ещё?
Re[4]: ImpersonateLoggedOnUser даёт ошибку 6 (ERROR_INVALID_
Здравствуйте, x64, Вы писали:
R>>"Сначала" это где ? На какой HANDLE ?
x64>Хендлы уникальны в пределах процесса, а не системы. Ты передаёшь значение хендла из одного процесса в другой, но этого недостаточно, необходимо скопировать сам хендл из таблицы хендлов исходного процесса (в твоём случае, UI-приложение) в таблицу хендлов целевого процесса (в твоём случае, служба). Для этого следует воспользоваться DuplicateHandle(), а для этого, в свою очередь, у тебя должен быть хендл исходного процесса с соответствующими правами. Ну и наконец, полученный в результате копирования хендл уже можно будет использовать в контексте твоего целевого процесса (служба). Что ещё?
Не знал. Спасибо за наводку. Я почему-то полагал что HANDLE уникальны во всей системе.
Я попробовал использовать DuplicateHandle, работает, но эффект не тот который я ожидал. Я сделал так:
1) Из UI приложения передаю в Windows Service handle процесса UI приложения
2) В Windows Service делаю такое
IntPtr tempToken;
IntPtr finalToken = IntPtr.Zero;
if (OpenProcessToken(uiProcessHandle, TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_DUPLICATE, out tempToken))
DuplicateHandle(uiProcessHandle, tempToken, GetCurrentProcess(), out finalToken, 0, false, DuplicateHandleOptions.DuplicateSameAccess);
bool res = ImpersonateLoggedOnUser(finalToken);
if (res)
{
InstallationManager.Instance.WindowsUsername = Environment.UserName;
InstallationManager.Instance.WindowsDomain = Environment.UserDomainName;
RevertToSelf();
}
Т.е. ImpersonateLoggedOnUser то конечно отработало, но имперсонировалось оно в конктесте аккаунта SYSTEM, того в котором крутится Windows Service, а не UI приложение
Re[5]: ImpersonateLoggedOnUser даёт ошибку 6 (ERROR_INVALID_
Здравствуйте, x64, Вы писали:
R>>"Сначала" это где ? На какой HANDLE ?
x64>Хендлы уникальны в пределах процесса, а не системы. Ты передаёшь значение хендла из одного процесса в другой, но этого недостаточно, необходимо скопировать сам хендл из таблицы хендлов исходного процесса (в твоём случае, UI-приложение) в таблицу хендлов целевого процесса (в твоём случае, служба). Для этого следует воспользоваться DuplicateHandle(), а для этого, в свою очередь, у тебя должен быть хендл исходного процесса с соответствующими правами. Ну и наконец, полученный в результате копирования хендл уже можно будет использовать в контексте твоего целевого процесса (служба). Что ещё?
Кароче говоря проблему решил. Правда без использования DuplicateHandle т.к. мне пришлось бы гонять между сервисом и приложением несколько значений типа HANDLE процесса сервиса. Порядок действий был таков:
1) из UI приложения в сервис кидаю process id зовя GetProcessId(GetCurrentProcess())
2) в сервисе по этому id делаю
OpenProcess(processAllAccess, false, (uint) uiProcessId)
OpenProcessToken(uiProcess, (uint) TokenAccessLevels.MaximumAllowed, out tempToken)
Видимо т.к. процесс пользовательского приложения я открывал уже в контексте сервиса handles все рабочие и я смог использовать tempToken в ImpersonateLoggedOnUser.
Спасибо за наводку. Позор конечно что я прочитав когда-то Рихтера не знал что HANDLEs уникальны только в рамках процесса.
Спасибо.
Re[5]: ImpersonateLoggedOnUser даёт ошибку 6 (ERROR_INVALID_
Здравствуйте, x64, Вы писали:
R>>1) из UI приложения в сервис кидаю process id зовя GetProcessId(GetCurrentProcess()) R>>Позор конечно что я прочитав когда-то Рихтера не знал...
x64>Позор №2: открой для себя GetCurrentProcessId().
Сэкономил 12 букв, спасибо
Re: ImpersonateLoggedOnUser даёт ошибку 6 (ERROR_INVALID_HAN
Здравствуйте, ruslanv, Вы писали:
R>полученный token перекидываю по named pipe в мой Windows сервис который крутится под пользователем Local System и пытаюсь вызвать на него ImpersonateLoggedOnUser.
Хм, стесняюсь спросить, а чем не устроил ImpersonateNamedPipeClient ?
"Нормальные герои всегда идут в обход!"
Re: ImpersonateLoggedOnUser даёт ошибку 6 (ERROR_INVALID_HAN
R>1) из UI приложения в сервис кидаю process id зовя GetProcessId(GetCurrentProcess()) R>2) в сервисе по этому id делаю R>
R>OpenProcess(processAllAccess, false, (uint) uiProcessId)
R>OpenProcessToken(uiProcess, (uint) TokenAccessLevels.MaximumAllowed, out tempToken)
R>
Ну и смысл? Если данное действие происходит ради секурити, то вот вам дыра — malicious IPC клиент передает вам не не свой process id, а какого нить системного процесса. И ваш сервис его успешно проимперсонирует.
Для имперсонации клиентов IPC нужно использовать предоставляемые этим самым IPC средства. Для пайпов к примеру вам тут уже правильно говорили это ImpersonateNamedPipeClient .
Как много веселых ребят, и все делают велосипед...
Re[6]: ImpersonateLoggedOnUser даёт ошибку 6 (ERROR_INVALID_
Здравствуйте, ononim, Вы писали:
R>>1) из UI приложения в сервис кидаю process id зовя GetProcessId(GetCurrentProcess()) R>>2) в сервисе по этому id делаю R>>
R>>OpenProcess(processAllAccess, false, (uint) uiProcessId)
R>>OpenProcessToken(uiProcess, (uint) TokenAccessLevels.MaximumAllowed, out tempToken)
R>>
O>Ну и смысл? Если данное действие происходит ради секурити, то вот вам дыра — malicious IPC клиент передает вам не не свой process id, а какого нить системного процесса. И ваш сервис его успешно проимперсонирует. O>Для имперсонации клиентов IPC нужно использовать предоставляемые этим самым IPC средства. Для пайпов к примеру вам тут уже правильно говорили это ImpersonateNamedPipeClient .
По поводу ImpersonateNamedPipeClient мне тут не говорили (кстати до named pipe handle будет сложно добраться, я использую WCF). Я думаю Вы путаете меня с другим участником форума.
Имперсонацию делаю с целью доступа к HKCU.
Re[7]: ImpersonateLoggedOnUser даёт ошибку 6 (ERROR_INVALID_
O>>Ну и смысл? Если данное действие происходит ради секурити, то вот вам дыра — malicious IPC клиент передает вам не не свой process id, а какого нить системного процесса. И ваш сервис его успешно проимперсонирует. O>>Для имперсонации клиентов IPC нужно использовать предоставляемые этим самым IPC средства. Для пайпов к примеру вам тут уже правильно говорили это ImpersonateNamedPipeClient . R>По поводу ImpersonateNamedPipeClient мне тут не говорили (кстати до named pipe handle будет сложно добраться, я использую WCF). Я думаю Вы путаете меня с другим участником форума.
говорили: http://rsdn.ru/forum/winapi/3658072.1.aspx
что до WCF — чтото мне подсказывает что в WFC есть средства для этого, просто вы про них немного не в курсе. Я как человек далекий от мира .нет могу только предложить начать копать отсюда: http://msdn.microsoft.com/en-us/library/ms788971.aspx
R>Имперсонацию делаю с целью доступа к HKCU.
мм.. ну ежели вы оттуда только читаете — может быть и не страшно... но ежели и пишете туда — уже хуже.
Как много веселых ребят, и все делают велосипед...
Re[2]: ImpersonateLoggedOnUser даёт ошибку 6 (ERROR_INVALID_
Здравствуйте, Jolly Roger, Вы писали:
JR>Здравствуйте, ruslanv, Вы писали:
R>>полученный token перекидываю по named pipe в мой Windows сервис который крутится под пользователем Local System и пытаюсь вызвать на него ImpersonateLoggedOnUser.
JR>Хм, стесняюсь спросить, а чем не устроил ImpersonateNamedPipeClient ?
У меня .Net приложение, общение сервисов идёт через WCF. Выковыривать из него handle от named pipe не хотелось бы.
Re[3]: ImpersonateLoggedOnUser даёт ошибку 6 (ERROR_INVALID_