Сейчас на форуме: user99 (+2 невидимых)

 eXeL@B —› Оффтоп —› Запуск программы из службы с правами админа, а не system.
Посл.ответ Сообщение


Ранг: 450.3 (мудрец), 13thx
Активность: 0.20
Статус: Участник

Создано: 24 мая 2012 23:46
· Личное сообщение · #1

Здравствуйте!
Суть проблемы такова, что есть служба из которой я запускаю некое приложение и оно автоматически запускается от SYSTEM.
Мне необходимо запустить от пользователя, админа (без пароля) либо текущего на компе у которого будут права админа. Система XP.
Запускал из службы FAR, а из него пытался запускать что-нибудь с правами админа с помощью runas или PsExec. На разных компьютерах с этим геморрой, то пустые пароли нельзя, то отказано в доступе, то вторичный вход в службах отключен...
Пишу на DELPHI, буду очень благодарен за подсказку или ссылку на пример.
Спасибо!



Ранг: 85.4 (постоянный), 51thx
Активность: 0.090
Статус: Участник

Создано: 25 мая 2012 09:14
· Личное сообщение · #2

как делает служба обновления nvidia, касперского и другие, создают юзера с рандомным известным паролем, потом службу запускают от имени этого юзера

| Сообщение посчитали полезным: ToBad

Ранг: 85.4 (постоянный), 51thx
Активность: 0.090
Статус: Участник

Создано: 25 мая 2012 09:20
· Личное сообщение · #3

вот тут есть все нужные примеры (только на си)
http://msdn.microsoft.com/en-us/library/windows/desktop/bb540476%28v=vs.85%29.aspx




Ранг: 450.3 (мудрец), 13thx
Активность: 0.20
Статус: Участник

Создано: 25 мая 2012 13:13
· Личное сообщение · #4

drone Спасибо! Нашёл примеры и на delphi через NetUserAdd, но тогда всё равно придется делать Runas, а с ним как я писал выше на определённых компах возникают сложности.

Я так понимаю что system по привилегиям стоит выше админа, неужели породить процесс от его имени такая сложная задача для винды, я же не пытаюсь от имени гостя создать что-то с админ правами?...

У меня из службы налажено взаимодействие с программой через файлмаппинг, так вот, что бы это начало нормально работать, мне тут подсказали делать подобным образом:
Code:
  1. sa.nLength := sizeof(sa);
  2. sa.bInheritHandle := false;
  3. sa.lpSecurityDescriptor := @sd;
  4. if not InitializeSecurityDescriptor(@sd,SECURITY_DESCRIPTOR_REVISION) then
  5.    raise Exception.Create('InitializeSecurityDescriptor'#13#10+SysErrorMessage(GetLastError));
  6. if not SetSecurityDescriptorDacl(@sd,True,nil,False) then
  7.    raise Exception.Create('SetSecurityDescriptorDacl'#13#10+SysErrorMessage(GetLastError));
  8. hFileMapObj:=CreateFileMapping($FFFFFFFF,@sa,PAGE_READWRITE,0,6,'xxxx');


Может подобным образом через установку SECURITY_ATTRIBUTES можно и с CreateProcess поступить, что бы она создавала от имени админа?




Ранг: 450.3 (мудрец), 13thx
Активность: 0.20
Статус: Участник

Создано: 25 мая 2012 14:10
· Личное сообщение · #5

Нашёл целую ветку посвящённую этой проблеме, к сожалению всё на английском и примеры на Си . Вот что мне показалось полезным: I am trying to start an application from the a windows service it's working fine on XP but not on Vista. The application is always started in session 0,but I want it in session 1 because it can show a UI.
Further more it needs to start when windows start and run either the interactive user is logged in or not, it does not need admin rights though.
Here is the entire code I am using, I also tried "winlogon" desktop but I got the same result.


Этот код может помочь мне или это другой случай?:
Code:
  1. int res = LogonUser(User,Dom,Pwd,LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken);
  2. DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityDelegation, TokenPrimary, &hDToken);
  3. hwinstaSave = GetProcessWindowStation();
  4. hwinsta = OpenWindowStation("winsta0", FALSE, READ_CONTROL | WRITE_DAC);
  5. res = SetProcessWindowStation(hwinsta);
  6. hdesk = OpenDesktop("default", 0, FALSE, READ_CONTROL | WRITE_DAC | DESKTOP_WRITEOBJECTS |
  7. DESKTOP_READOBJECTS);
  8. res = SetProcessWindowStation(hwinstaSave);
  9. res = GetLogonSID(hDToken, &pSid);
  10. res = AddAceToWindowStation(hwinsta, pSid);
  11. res = AddAceToDesktop(hdesk, pSid);
  12. res = ImpersonateLoggedOnUser(hDToken);
  13. ZeroMemory(&si, sizeof(STARTUPINFO));
  14. si.cb= sizeof(STARTUPINFO);
  15. si.lpDesktop = TEXT("winsta0\default");
  16. bResult = CreateProcessAsUser(hDToken, NULL, lpCommandLine, NULL,NULL, FALSE, NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE, NULL, currentDirectory.c_str(), &si, &pi );





Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 25 мая 2012 14:19
· Личное сообщение · #6

А зачем имперсонация, если процесс и так запускается от другого токена? Код похож на помойку, куда свалено всё подряд.




Ранг: 450.3 (мудрец), 13thx
Активность: 0.20
Статус: Участник

Создано: 25 мая 2012 14:36
· Личное сообщение · #7

Archer пишет:
А зачем имперсонация, если процесс и так запускается от другого токена?


Не знаю, перебираю все возможности для достижения цели, гуглю уже который день, но безрезультатно....
Сейчас этот вариант прорабатываю. Это может мне помочь?




Ранг: 568.2 (!), 465thx
Активность: 0.550.57
Статус: Участник
оптимист

Создано: 25 мая 2012 16:01
· Личное сообщение · #8

Запуск и изминение сервисов из коммандной строки --> sc config / <--

-----
Чтобы правильно задать вопрос, нужно знать большую часть ответа. Р.Шекли.




Ранг: 0.0 (гость)
Активность: 0.250
Статус: Участник

Создано: 25 мая 2012 16:15
· Личное сообщение · #9

ToBad
Смотри примеры на delphi и да права System выше прав админа.


468d_25.05.2012_EXELAB.rU.tgz - sample.rar




Ранг: 450.3 (мудрец), 13thx
Активность: 0.20
Статус: Участник

Создано: 25 мая 2012 16:22
· Личное сообщение · #10

ClockMan не, я не сервис от админа с привилегиями system хочу запустить, а из запущенного сервиса программу от имени админа...




Ранг: 450.3 (мудрец), 13thx
Активность: 0.20
Статус: Участник

Создано: 25 мая 2012 17:03
· Личное сообщение · #11

F_a_u_s_t Спасибо за код, очень полезный будет, хотя результата я пока не достиг.

run-ass - вроде как то, что нужно, под админом выбираю учётку админа и пустой пароль, запускает под админом. Под системой запускаю, выбираю тоже самое, не запускает, выдаёт ошибку Logon failure: unknown user name or bad password.
То есть CreateProcessWithLogonW выполняется с ошибкой...

run-as-system - работает хорошо для своих задач, то есть под админом запускает программы от system, но это не то, что нужно, нужно наоборот...



Ранг: 0.0 (гость)
Активность: 0.250
Статус: Участник

Создано: 25 мая 2012 17:30
· Личное сообщение · #12

ToBad
Так код я привел что бы было на что опираться, а так гугли теперь функи и параметры к ним и кода будет чуть меньше чем докуя.



Ранг: 369.8 (мудрец), 400thx
Активность: 0.390
Статус: Участник

Создано: 27 мая 2012 07:01
· Личное сообщение · #13

ToBad
Недавно ковырял тему runas чуть более чем плотно. В сервисе нужно использовать LogonUser и CreateProcessAsUser, естественно сервису откуда-то нужно знать пароль пользователя. Запустить от пользователя не зная пароля тоже можно, но это будут глюкавые неполноценные хаки.

-----
PGP key <0x1B6A24550F33E44A>


| Сообщение посчитали полезным: ToBad


Ранг: 450.3 (мудрец), 13thx
Активность: 0.20
Статус: Участник

Создано: 28 мая 2012 03:14
· Личное сообщение · #14

ntldr пишет:
В сервисе нужно использовать LogonUser и CreateProcessAsUser


Спасибо за наводку!

ntldr пишет:
нужно знать пароль пользователя


Это не проблема, там где собираюсь применять паролей нет.

Испытал много разных примеров, ничего не работало как нужно, в итоге нашёл код, который у кого-то не работал, а у меня заработал отлично:

Code:
  1. function RunProcessAsCurrentUser(FileName: string): Boolean;
  2. var
  3.  ProcessId: Integer;
  4.  hWindow, hProcess, TokenHandle: THandle;
  5.  si: Tstartupinfo;
  6.  p: Tprocessinformation;
  7. begin
  8.    Result:= False;
  9.    hWindow:= FindWindow('Progman', 'Program Manager');
  10.    GetWindowThreadProcessID(hWindow, @ProcessID);
  11.    hProcess:= OpenProcess (PROCESS_ALL_ACCESS, FALSE, ProcessID);
  12.    if OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, TokenHandle) then
  13.    begin
  14.  
  15.      FillChar(si,SizeOf(si),0);
  16.      with Si do begin
  17.        cb := SizeOf( Si);
  18.        dwFlags := startf_UseShowWindow;
  19.        wShowWindow := SW_NORMAL;
  20.        lpDesktop := PChar('winsta0\default');
  21.      end;
  22.  
  23.      Result:=CreateProcessAsUser(TokenHandle, nil, PChar(FileName), nil, nil, false, Create_default_error_mode, nil, nil, si, p);
  24.    end;
  25. end;


Напомню, только XP, паролей нет, хотя мне кажется или тут и с паролями сработало бы?



Ранг: 369.8 (мудрец), 400thx
Активность: 0.390
Статус: Участник

Создано: 28 мая 2012 11:07
· Личное сообщение · #15

ToBad пишет:
паролей нет.

Пароль длджен быть. Вход с пустым паролем чаще всего запрещен.

ToBad пишет:
в итоге нашёл код, который у кого-то не работал, а у меня заработал отлично:

Это как раз из серии глюкавых неполноценных хаков. Почему - не буду даже комментировать, думаю это очевидно. Будет работать непредсказуемо или вообще никак в более чем 100500 случаях.

-----
PGP key <0x1B6A24550F33E44A>




Ранг: 0.0 (гость)
Активность: 0.250
Статус: Участник

Создано: 28 мая 2012 15:03 · Поправил: F_a_u_s_t
· Личное сообщение · #16

ToBad
Семпл Run_as_System рабочий, только для твоей задачи нужно поменять две строчки, но опять же там хак.

if (LowerCase(ProcessEntry32.szExeFile) = 'winlogon.exe') then
заменить на
if (LowerCase(ProcessEntry32.szExeFile) = 'explorer.exe') then

if UserName = 'SYSTEM' then
заменить на
if UserName = GetUserName then

Где GetUserName имя текущего пользователя.

Без хаков, чистое решение, создать пользователя с паролем и по окончанию его удалить, так делают большинство, ну или сделать текущему пользователю пароль, но за это надо руки отрывать, при каком нибудь ахтунге учетка может полететь.

Ps. Семпл проверял на трех осях, работало стабильно.

| Сообщение посчитали полезным: ToBad


Ранг: 450.3 (мудрец), 13thx
Активность: 0.20
Статус: Участник

Создано: 28 мая 2012 16:09
· Личное сообщение · #17

F_a_u_s_t - спасибо за то, что всё разжевали! Я тоже пытался вместо SYSTEM вписывать пользователя, но про замену первой строчки не догадался...

ntldr пишет:
Вход с пустым паролем чаще всего запрещен.


Да, это может оказаться проблемой, по этому как посоветовали буду делать LogonUser и CreateProcessAsUser, для созданного пользователя с установленным паролем.



Ранг: 0.0 (гость)
Активность: 0.250
Статус: Участник

Создано: 28 мая 2012 17:17 · Поправил: F_a_u_s_t
· Личное сообщение · #18

ToBad
Не за что.
И еще один маленький хинт, что бы не было хардкора на explorer можешь сделать проверку на тип прав, если не SYSTEM то значит юзер и в самом сервисе проверяй, если процесс исчез, то ищи любой другой процесс юзера, а так вполне рабочее решение.
Add:
Правильно что выбрал второй вариант, первый только годный запускать к к примеру консоль из своей прожки с нужными правами, для использования где то не годится ибо аверы и вирусы, а есчо куча шелов.


 eXeL@B —› Оффтоп —› Запуск программы из службы с правами админа, а не system.

У вас должно быть 20 пунктов ранга, чтобы оставлять сообщения в этом подфоруме, но у вас только 0

   Для печати Для печати