Execute o comando no computador remoto e mostre a interface do usuário para o usuário conectado

3

já que não encontrei nenhuma solução adequada on-line, peço aqui.

Eu tenho um monte de computadores onde eu quero executar um programa e mostrar a GUI do programa para o usuário atualmente logado. Afaik isso não é possível com Powershell (Stop / Start do Windows Services não é problema) e eu não conseguia fazer isso com PsExec.exe.

Meu comando PsExec tem esta aparência - o calc.exe é visível no TaskManager, mas não consigo ver a GUI.

C:\Users\Administrator.DEV\Desktop>PsExec.exe -i \TEST-CLI-01 -u localUser -p userPassword -d calc.exe

Descrição resumida da configuração: Servidor: MS Server2012R2 Clientes: Windows 8.1 Todo sistema faz parte do domínio do AD.

Alguém tem uma ideia de como eu poderia conseguir isso?

Thx muito antecipadamente :)

    
por pinas 17.10.2014 / 11:06

3 respostas

2

Você vai achar isso extremamente difícil, se não impossível, para fazer. Você pensaria que seria fácil, mas não é. A Microsoft tornou isso propositadamente difícil porque expõe um tipo de vulnerabilidade de segurança (ataques de "estilhaçamento") se você puder manipular o gerenciador de janelas no contexto de segurança de outro usuário.

O recurso Isolamento da Sessão 0 , introduzido no Windows Vista, torna É difícil para um programa de serviço (como PsExec ) interagir com o console. Quando o serviço de Detecção de Serviços Interativos estiver em execução, o usuário será solicitado, quando um serviço tentar interagir com o console, a mudar para uma área de trabalho segura para interagir com a GUI do serviço.

Existem algumas discussões sobre o Stackoverflow que detalham os detalhes da arquitetura.

Uma maneira melhor de lidar com isso seria fazer com que o usuário execute um processo que ouça algum tipo de comunicação entre processos e aja de acordo. Se você quisesse realmente hackish, poderia rodar um simples script VBScript ou Powershell que ficava em segundo plano, quando o usuário fazia o login e aguardava por uma entrada de arquivo / registro / conexão TCP / etc e então agia. Você poderia remendar algo assim juntos como uma prova de conceito rapidamente.

    
por 17.10.2014 / 11:18
1

Como Evan disse, isso é propositadamente feito para ser difícil, porque é tão fácil de explorar e usar maliciosamente.

Mas você pode fazer isso, se tiver dedicação suficiente e estiver disposto a sujar as mãos.

Eu criei um Windows Service robusto e confiável que roda em máquinas em um ambiente de produção, que executa aplicativos GUI no contexto de segurança de usuários logados sob condições específicas, para que o aplicativo apareça logo antes dos olhos do usuário. Então, meu ponto é que é possível fazê-lo de maneira robusta e confiável.

A chave é a % função da API CreateProcessAsUser Advapi32.dll .

E para usar essa função, você deve ser capaz de "roubar" o token de acesso primário de um usuário conectado. E para fazer isso, você pode usar a função de API WTSQueryUserToken do Wtsapi32. dll .

Uma das restrições de usar a API mencionada é que ela só pode ser chamada dentro do contexto de segurança do Sistema Local - e é por isso que PsExec.exe -si 2 \Test-CLI-01 calc.exe funciona para você - porque a opção -s diz ao PsExec para executar como sistema local.

Esse é naturalmente um dos momentos em que seu serviço do Windows seria executado como Sistema Local, já que você precisa usá-lo se desejar usar WTSQueryUserToken . Que seja declarado que executar um programa ou serviço como Sistema Local geralmente é uma má idéia, porque o Sistema Local tem acesso ilimitado à máquina na qual está sendo executado, portanto, se um hacker explorar uma falha em seu programa, ele poderá usar que exploram para fazer com que seu código execute alguma ação com todos os privilégios de segurança que o contexto de segurança do Sistema Local confere. (isto é, todos eles .)

É também onde extrema cautela deve ser exercida pelo programador, porque é sua responsabilidade descartar esses tokens de segurança e não vazá-los. Você (ou um mau ator) pode obviamente usar os tokens de segurança para fins nefastos se eles não forem tratados adequadamente.

Alguns exemplos úteis, tirados de algum C # que escrevi há algum tempo:

Como obter o token de acesso principal de um usuário:

WTSQueryUserToken((uint)session.SessionId, out userPrimaryAccessToken) 

Usando esse token de acesso primário para iniciar um processo em sua sessão, como esse usuário:

CreateProcessAsUser(userPrimaryAccessToken, null, cmdLine, ref saProcessAttributes, ref saThreadAttributes, false, 0, IntPtr.Zero, null, ref si, out pi)

Estas são apenas chamadas de API do Windows ... você pode replicá-las em qualquer idioma que desejar.

    
por 17.10.2014 / 15:39
1

thx para você dicas e sugestões - o que eu fiz é o seguinte

function startChromeRemotely($client) {
    $desktopSession = query user /server:$client | Select-String -Pattern Active
    $desktopSessionId = ($desktopSession -split '\s+')[3]
    .\PsExec.exe -i $desktopSessionId -d \$client -u someuser-p somepassword "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"
}

Então, basicamente, o que eu faço é primeiro obter a sessão da área de trabalho do usuário conectado ("ativo") e depois "injetar" a tela do Chrome diretamente na sessão do usuário. Se executado como administrador de domínio, isso parece funcionar bem, mas de alguma forma parece estranho / instável. Alguém pode me dizer o porquê ?

Thx novamente :)

    
por 20.10.2014 / 08:25