démarrage d'un processus UAC élevé à partir d'un service non interactif (win32 / .net / powershell)
Je suis à l'aide d'une tierce partie service Windows qui gère les tâches d'automatisation en exécutant des scripts et exécutables à l'aide de CreateProcessAsUser(). Je suis en cours d'exécution dans les problèmes sur Windows Server 2008 en raison de l'UAC et de la façon dont le LUA élévation est gérée par le biais d'une Api.
Le service s'exécute en tant que système local et n'a pas de "Interagir Avec le Bureau" enabled". Les processus sont en cours d'exécution en tant qu'utilisateurs dans le groupe Administrateurs, mais pas le compte Administrateur (qui est exempté de nombreux UAC restrictions). Tout le contrôle de compte d'utilisateur paramètres par défaut.
Je peux passer des commandes arbitraires ou powershell code pour le service, mais je n'arrive pas à "sortir" de la non-élevée, non-processus interactif qui obtient lancé par le service.
Le nœud du problème semble être que la seule (public) de l'API option pour le démarrage d'un processus élevés est ShellExecute() avec le "runas" de verbe, mais aussi loin que je peux dire qui ne peut pas être appelée à partir d'un non-interactive de service ou si vous obtenez des erreurs du type "Cette opération nécessite une station windows interactive".
La seule solution que j'ai trouvé est mentionné ici:
http://www.eggheadcafe.com/software/aspnet/29620442/how-to-proper-use-sendinp.aspx
Dans Vista, le fonctionnaire documentés
pour élever un processus est seulement à l'aide de la
shell API ShellExecute(Ex -) (pas
CreateProcess ou CreateProcessAsUser).
Si votre application doit appeler
ShellExecute(Ex) pour le lancement d'un helper
élevées pour appeler SendInput.
En outre, en raison de la Session 0
l'isolement, un service peut uniquement utiliser
CreateProcessAsUser ou
CreateProcessWithLogonW(ne peut pas utiliser
ShellExecute(Ex -)) pour spécifier le
bureau interactif...Je pense qu'il n'y a pas de moyen direct d'
frayer un taux élevé de processus à partir d'une
service windows. Nous ne pouvons que la première utilisation
CreateProcessAsUser ou
CreateProcessWithLogonW pour frayer un
non élevés processus de l'utilisateur
session interactive(bureau). Puis dans
le non-élevée, on peut utiliser
ShellExecute(Ex) pour frayer un taux élevé de
processus de la tâche réelle.
Pour ce faire .net/powershell code, on dirait que je devrais faire quelques élaborer P/Invoke trucs pour appeler CreateProcessAsUser ou CreateProcessWithLogonW depuis le .Net Système.Diagnostics.ProcessStartInfo n'a pas un équivalent de lpDesktop que je pourrais le mettre à "winsta0\par défaut". Et je ne suis pas clair si LocalSystem a même le droit d'appeler CreateProcessAsUser ou CreateProcessWithLogonW.
J'ai aussi regardé
http://blogs.msdn.com/alejacma/archive/2007/12/20/how-to-call-createprocesswithlogonw-createprocessasuser-in-net.aspx
et
Processus.Démarrer avec les informations d'identification différentes avec contrôle de compte d'utilisateur
Basé sur tout, je suis parvenu à la conclusion qu'il n'y a pas de façon simple de le faire. Ai-je raté quelque chose? Ce n'est pas vraiment sembler comme il devrait être si dur. Il se sent comme contrôle de compte d'utilisateur a juste jamais été conçu pour gérer les non-interactive de cas d'utilisation.
Et si tout des personnes de Microsoft fin de cette lecture, j'ai remarqué que la façon ShellExecute gère en interne l'élévation est en appeler à l'Application de l'Information de Service (AIS). Pourquoi n'est-ce pas ce même appel à l'AIS certains Win32 ou .NET API?
http://msdn.microsoft.com/en-us/library/bb756945.aspx
Désolé, qui a couru un peu long. Merci pour toutes les idées.
source d'informationauteur Chris Sears
Vous devez vous connecter pour publier un commentaire.
La "officielle" de la façon de briser la session zéro isolement est d'utiliser une combinaison de services terminal server API et
CreateProcessAsUser()
de lancer un processus au sein d'une session d'un utilisateur. Dans mon ancien travail, nous avons fait juste que, comme nous le nécessaire pour afficher une boîte de dialogue à l'utilisateur à partir d'un service avant d'installer une mise à jour téléchargée, Donc, je sais que ça fonctionne, sur WinXP, Win2K3, Vista et Win7, au moins, mais je ne vous attendez pas à Gagner 2K8 serait trop différents. Fondamentalement, le processus se déroule comme suit:WTSGetActiveConsoleSessionId()
pour obtenir la console active id de session (TRÈS important, que la session interactive est PAS toujours la session 1, même sur des systèmes client). Cette API est également de retour d'un -1 si il n'y a aucun utilisateur connecté à la session interactive (qui est connecté localement à la machine physique, par opposition à l'aide de RDP).WTSQueryUserToken()
pour ouvrir une jeton reprents l'utilisateur connecté à la console.DuplicateTokenEx()
pour convertir le jeton d'emprunt d'identité (à partir deWTSQueryUserToken
) dans un jeton principal.CreateEnvironmentBlock()
pour créer un nouvel environnement pour le processus (facultatif, mais si vous ne le faites pas, le processus ne pas en avoir un).CreateProccessAsUser()
le long de la ligne de commande pour le fichier exécutable. Si vous avez créé un bloc d'environnement à partir de l'étape #4, vous devez passer leCREATE_UNICODE_ENVIRONMENT
drapeau (toujours). Cela peut paraître idiot, mais l'API échoue lamentablement si vous n'avez pas (avecERROR_INVALID_PARAMTER
).DestroyEnvironmentBlock
sinon, vous allez générer une fuite de mémoire. Le processus est donné une copie de l'environnement de bloc quand il lance, de sorte que vous êtes seulement de détruire des données locales.Et le tour est joué! Windows ne l'interne de la magie, et vous voyez le lancement de l'application. Cependant, bien que cette va lancer et processus interactif à partir d'un service, je ne sais pas si il va contourner l'UAC (mais ne me citez pas moi). En d'autres termes, il ne peut pas lancer un processus élevés, à moins que le registre ou interne manifeste dit de le faire, et même alors, vous pourriez encore avoir une invite UAC. Si le jeton que vous obtenez à partir de l'étape #3 est un jeton restreint, vous pouvez être en mesure d'utiliser
AdjustTokenPrivileges()
pour restaurer l'élévation de la (pleine) jeton, mais ne me citez pas sur moi, que ce soit. Toutefois, comme indiqué dans la MSDN docs, veuillez noter qu'il n'est pas possible pour "ajouter" des privilèges sur un jeton qui n'a pas déjà (par exemple, vous ne pouvez pas transformer une restriction de jeton de l'utilisateur en tant qu'administrateur en utilisantAdjustTokenPrivileges
; le sous-jacent de l'utilisateur devrait être un admin pour commencer).Il est techniquement possible de faire tout cela à partir de Win2K de l'avant. Cependant, il est vraiment possible de commencer avec WinXP, comme Win2K manque de
WTSGetActiveConsoleSessionId()
etWTSQueryUserToken()
l'API (avecWTSEnumerateProcesses()
pour Win2K Pro). Vous pouvez coder en dur 0 à l'id de session (puisque c'est toujours le cas dans Win2K), et je suppose que vous pourriez être en mesure d'obtenir le jeton d'utilisateur par l'énumération des processus en cours d'exécution et la duplication de l'un de leurs pions (il doit être celui qui a le interactive SID présent). Peu importe, leCreateProcessAsUser()
va se comportent de la même manière lorsqu'il est passé d'un utilisateur interactif jeton, même si vous ne sélectionnez pas "Interagir avec le Bureau" dans les paramètres de service. Il est également plus sûr que de lancer directement à partir du service de toute façon, en tant que le processus n'hériteront pas le pieuxLocalSystem
jeton d'accès.Maintenant, je ne sais pas si votre application tierce n'est tout de cela quand il exécute le script/processus, mais si vous voulez le faire à partir d'un service, qui est de savoir comment (et avec Vista ou Win7, c'est la seule façon de surmonter la session 0 isolement).
Selon votre cas d'utilisation, vous pouvez faire ce que je fais. Je traque le processus winlogon pour la session active et voler son jeton. Si il n'y a pas de session active (API renvoyé -1), utiliser 1 si WINVER >= 6 0 sinon. Cette résultats dans le SYSTÈME de la session active.