Powershell: Sudo de suporte<powershell cmdlet=""/>

Criado em 28 fev. 2017  ·  99Comentários  ·  Fonte: PowerShell/PowerShell

Passos para reproduzir

sudo Remove-Item foo.txt onde foo.txt é propriedade do root

Comportamento esperado

foo.txt foi excluído

Comportamento real

sudo: Remove-Item: command not found

Committee-Reviewed Issue-Enhancement WG-Engine

Comentários muito úteis

Mesmo no Windows, seria bom ter capacidade semelhante para executar um cmdlet como outro usuário ou elevado e algo que pudesse contar com scripts portáteis. Pode ser necessária uma RFC para isso.

Todos 99 comentários

Murmurar! Muito interessante. Mas acho que o comportamento real é o esperado. Como no Windows, não temos um comando como sudo.
Mas, você poderia usar 'sudo powershell' e então remover foo.txt (que foi criado usando 'sudo powershell') e então funcionará ao usar Remove-Item. Claro, isso não funcionará em uma permissão não elevada.

Eu só usaria 'sudo' em comandos do Linux ("sudo nautilus") de dentro do PowerShell.

:)

Mesmo no Windows, seria bom ter capacidade semelhante para executar um cmdlet como outro usuário ou elevado e algo que pudesse contar com scripts portáteis. Pode ser necessária uma RFC para isso.

Esta funcionalidade seria útil para contornar o # 3506.

Isso vai se tornar um bloqueador para a adaptação do Linux para mim, se isso não for resolvido. Não temos permissão para fazer sudo bash e da mesma forma não poderemos fazer sudo powershell.

Eu concordo com o Maximo, devemos deixar o sudo para bash e fazer um novo cmdlet para fazer elevação no PowerShell usando o sudo como estrutura na funcionalidade esperada.

@dantraMSFT está investigando isso, Dan, você pode fornecer uma atualização sobre algumas idéias atuais sobre isso?

@pixelrebirth Você pode fornecer mais detalhes sobre o que espera? Você está esperando uma execução simples com uma espera, redirecionamento de saída ou redirecionamento de pipeline?
Alguns exemplos de uso também seriam úteis.

@dantraMSFT Para fins de discussão, vou chamar o novo cmdlet sudo like: Invoke-Elevated
É assim que o sudo funciona e seria traduzido para Invoke-Elevated de uma forma powerhell

$cred = Get-Credential
Invoke-Elevated -credential $cred -command {
        Get-ChildItem ./test | Remove-Item -force
} | Get-SomeCmdlet

Neste exemplo, tudo no scriptblock seria executado elevado e então canalizado para um Get-SomeCmdlet NÃO elevado
Cred pode ser um usuário diferente ou você mesmo como um usuário elevado (as permissões precisam ser mantidas em algum lugar como o arquivo sudoers, também conhecido como uma lista de permissões)

O registro deve ser ativado, por padrão, para instâncias onde Invoke-Elevated é executado:
Usuário | Command | DateTime ou registro de formato semelhante

Talvez parte disso seja estendido ou alterado posteriormente, mas isso é o que removeria meus bloqueadores

Ele também deve funcionar como:

Get-ChildItem ./test | Invoke-Elevated -command {Remove-Item -force}
Onde a credencial é o seu usuário atual e só pede a senha ...

Get-ChildItem não é elevado, Remove-Item é elevado neste exemplo

Eu estava na chamada da comunidade hoje perguntando sobre isso, mas minha esposa se machucou durante a explicação dos desafios para isso e eu perdi muito. Você pode colocar notas aqui para que eu possa repassá-las ao meu chefe?

Ajudarei no que for possível e pressionarei onde for preciso.

@pixelrebirth espero que ela esteja bem! Colocaremos uma gravação da ligação nos próximos um ou dois dias, para que você possa acompanhar se quiser.

O resumo básico é que @dantraMSFT está fazendo uma investigação inicial para descobrir como fazer isso de uma maneira não hacky. Hoje, você pode sudo powershell -c "invoke-foo" de outro shell, mas isso obviamente não funciona.

@dantraMSFT : conforme você trabalha em sua investigação, talvez poste algum status para se certificar de que todos entendam as compensações com diferentes abordagens?

Pode parecer óbvio, mas talvez dê uma olhada no código-fonte do sudo e veja como eles o gerenciam - talvez exija alguma codificação de baixo nível. Eu gostaria de ter um entendimento mais profundo do código para ajudar.

Ela está bem, ela se sente no quadril operado. Obrigado pela resposta rápida sobre isso. Estou trabalhando em uma pequena solução de hack que postarei aqui se conseguir.

@pixelrebirth Para referência, sudo usa o bit setuid, consulte https://unix.stackexchange.com/a/80350/86669 para obter detalhes. Provavelmente seria uma má ideia definir isso em uma casca inteira, no entanto.

O sudo nativo do Windows é obrigatório (portanto, o problema provavelmente não pertence aqui, embora a opção em que seja utilizável apenas via Powershell seja aceitável para mim). Usei o Powershell desde o início e vi 99 variantes do script sudo, como Invoke-Elevated acima (ou o meu próprio que uso todos os dias). Incluir um cmdlet como esse no Powershell seria um avanço, no entanto, todos eles parecem incômodos em relação a como isso funciona no Linux.

Uma das coisas irritantes para mim é que ele inicia uma nova janela de shell (não no Linux) que eu gostaria de ver implementada no Powershell / Windows, não tenho certeza se isso é tecnicamente possível no Windows embora.

Embora eu goste da ideia de outro cmdlet ("Invoke-Elevated") que poderia ser usado no Windows, mas não consigo entender por que não abrir o PowerShell com 'sudo' se você precisa criar um script para executar com alta privilégio?

Especialmente se você estiver automatizando uma tarefa que eventualmente será agendada para ser executada com algum tipo de credenciais de alto privilégio de qualquer maneira.
:)

Porque esse não é o fluxo de trabalho típico. Você não faz 'sudo' e vive lá para sempre, você faz sudo comandos específicos e vive em um mundo não sudo. Não há uma maneira rápida de fazer isso no Windows e o PowerShell em si é terrivelmente lento para iniciar, especialmente com poucos elementos de perfil incluídos.

Em uma sessão diária típica, eu sudo 20 vezes comandos específicos, outros são executados sem privilégios. Esse é o ponto principal do sudo, aumentar o privilégio apenas quando necessário e pode ser necessário com bastante frequência.

Meu fluxo de trabalho era, execute o comando, ele reclama sobre privilégios, I sudo -L que executará o último comando novamente com privilégio. Já que o posh é tão lento para começar, eu apenas ligo o shell do administrador e vivo nele constantemente, o que claramente não é uma boa ideia.

Obrigado @majkinetor!
:)

O sudo deve ser uma variante CLI do prompt do UAC. O Windows, até recentemente, nunca era compatível com CLI, mas agora acho que precisamos disso. Chegou a hora em que você pode fazer coisas 100% Windows apenas no shell - eu pessoalmente uso apenas o shell e o navegador, quase nada mais.

@majkinetor : Pelo que eu sei, a única maneira de iniciar um processo elevado é por meio do prompt do UAC.
FWIW: Você pode fazer isso no Windows sem uma alteração do PowerShell usando ShellExecuteEx.
No entanto, se você está esperando transmitir os resultados; é uma história muito diferente.

Pelo que eu sei, a única maneira de iniciar um processo elevado é por meio do prompt do UAC.

Aplicativos específicos podem ser excluídos do UAC, o que poderia, então, supor, lidar com a elevação em sua própria maneira.

Queria oferecer minha solução / alternativa para o Sudo no Windows. Qualquer feedback / crítica será bem-vindo. Se não é apropriado postar esse tipo de coisa aqui peço desculpas antecipadamente.

https://github.com/pldmgg/misc-powershell/tree/master/MyModules/Sudo

https://www.powershellgallery.com/packages/Sudo

Existem três funções no Módulo Sudo:

  • New-SudoSession
  • Remove-SudoSession
  • Start-SudoSession

Start-SudoSession (também conhecido como "sudo") é para comandos únicos que você precisa elevar. Ele solicitará as credenciais e fornecerá um prompt do UAC antes de executar o comando.

.EXEMPLO

$ModuleToInstall = "PackageManagement"
$LatestVersion = $(Find-Module PackageManagement).Version
# PLEASE NOTE the use of single quotes in the below $InstallModuleExpression string
$InstallModuleExpression = 'Install-Module -Name $ModuleToInstall -RequiredVersion $LatestVersion'
Start-SudoSession -Credentials $MyCreds -Expression $InstallModuleExpression

New-SudoSession se destina a abrir uma ElevatedPSSession na qual comandos elevados podem ser injetados. A ideia é que em um script mais longo com várias operações que exigem elevação, você crie uma ElevatedPSSession no início e receba um prompt UAC UMA VEZ, e então injete esses comandos elevados usando Invoke-Command nessa ElevatedPSSession quando necessário.

.EXEMPLO

PS C:\Users\zeroadmin> $MyElevatedSession = New-SudoSession -UserName zeroadmin -Credentials $MyCreds
PS C:\Users\zeroadmin> Get-PSSession
 Id Name            ComputerName    ComputerType    State         ConfigurationName     Availability
 -- ----            ------------    ------------    -----         -----------------     ------------
  1 ElevatedSess... localhost       RemoteMachine   Opened        Microsoft.PowerShell     Available

PS C:\Users\zeroadmin> Invoke-Command -Session $MyElevatedSession.ElevatedPSSession -Scriptblock {Install-Package Nuget.CommandLine -Source chocolatey}

Por fim, Remove-SudoSession remove a ElevatedPSSession criada pela função New-SudoSession. A ideia é colocar isso no final do seu script, quando você receberá um prompt do UAC. Portanto, no total, para executar qualquer número de operações elevadas em um script específico, você só recebe dois prompts do UAC - um para abrir uma ElevatedPSSession e outro para fechá-la. Uso de Remove-PSSession:

.EXEMPLO

$MyElevatedSession = New-SudoSession -UserName zeroadmin -Credentials $MyCreds
PS C:\Users\zeroadmin> Get-PSSession
 Id Name            ComputerName    ComputerType    State         ConfigurationName     Availability
 -- ----            ------------    ------------    -----         -----------------     ------------
  1 ElevatedSess... localhost       RemoteMachine   Opened        Microsoft.PowerShell     Available

Remove-SudoSession -Credentials $MyCreds -OriginalConfigInfo $MyElevatedSession.OriginalWSManAndRegistryStatus -SessionToRemove $MyElevatedSession.ElevatedPSSession

Nos bastidores, aqui está o que ele faz em uma sessão PowerShell não elevada (se a sessão já estiver elevada, ela não fará nada):

  • Verifica se WinRM / WSMan está habilitado e configurado para permitir autenticação CredSSP (se não, então
    alterações de configuração são feitas)

  • Verifica o objeto de política de grupo local ...

    Configuração do computador -> Modelos administrativos -> Sistema -> Delegação de credenciais -> Permitir delegação de novas credenciais

    ... para certificar-se de que está habilitado e configurado para permitir conexões via WSMAN / LocalHostFQDN

  • Cria uma PSSession elevada usando o cmdlet New-PSSession

  • Executa a expressão passada para o parâmetro -Expression na PSSession elevada

  • Remove a PSSession elevada e reverte todas as alterações feitas (se houver) na Política de Grupo Local e na configuração WSMAN / WinRM.

EDIT: Atualizado erro de digitação de exemplo de Remove-SudoSession.

@pldmgg Não vejo em que licença seu código está, então não podemos nem olhar o que você fez. Você pode adicionar um arquivo de LICENÇA? O MIT seria muito amigável e nos permitiria usar seu código ou derivar dele. Obrigado!

@pldmgg Seguindo o que @ SteveL-MSFT mencionou, um ótimo guia para ajudá-lo neste processo é https://choosealicense.com/.

tl; dr - É difícil dar errado com as seguintes licenças:

  • Apache 2.0
  • MIT

Mais detalhes

O Apache 2.0 tem alguns pontos fortes adicionais sobre o MIT, mas no geral, eles são muito permissivos e facilmente usados ​​com outras licenças de código aberto e muito amigáveis ​​aos negócios. Se você escolher qualquer licença copyleft (GPL), o código não pode ser usado com outras ferramentas sem que essas outras ferramentas mudem para uma licença GPL (também conhecido como licenciamento viral - LGPL sendo a exceção aqui, onde módulos / binários licenciados por LGPL podem ser colocado próximo a outras ferramentas sem exigir uma mudança de licença para o outro código).

@pldmgg também, muito, muito legal!

@ferventcoder Obrigado pela referência https://choosealicense.com! Como vocês (+ @ SteveL-MSFT) provavelmente suspeitaram, eu não tinha certeza de qual licença escolher. Atualizei todo o meu repositório misc-powershell para usar o Apache 2.0 e atualizei o Sudo.psd1 para fazer referência ao Apache 2.0 (no meu repositório git e também na Galeria do PowerShell). Espero que isso possa ser útil para as pessoas! Todos os conselhos / críticas são bem-vindos!

@ SteveL-MSFT Você pode usá-lo se a licença for Apache 2.0? Se você precisa que seja o MIT, me avise e eu irei atualizar.

@pldmgg meu maior problema com sua solução é o uso do CredSSP. Esse é um método menos seguro para tratamento de credenciais e acho que expõe muitos riscos aos limites do UAC.

Para citar o Powershell Magaize ,

"É uma má ideia usar CredSSP para se autenticar na estação de trabalho de um usuário usando uma conta de administrador de domínio; você está essencialmente dando as chaves do reino."

"Não coloque credenciais de alta confiança em computadores de baixa confiança"

O objetivo do UAC é não confiar nos aplicativos do computador. Mesmo que eu consinta com um comando sudo que acaba causando estragos na minha máquina, ele geralmente não terá minhas credenciais. Se o comando sudo agora tem acesso claro às minhas credenciais de domínio, ele poderia causar muito mais danos ao comprometer minha rede.

A sua solução pode funcionar sem o CredSSP? Se não, qual problema você estava tentando resolver ao usar o CredSSP? Essas informações podem ser úteis para a equipe do PowerShell encontrar uma solução mais segura.

@pldmgg Eu acredito que o Apache 2.0 é suficiente. Obrigado!

@ dragonwolf83 Esta é uma preocupação comum. Na verdade, apresentei todo o meu argumento de que está tudo bem nesta situação específica neste tópico:

https://www.reddit.com/r/PowerShell/comments/6c778m/startsudosession_sudo_for_powershell_written_in/dhsretm/

Mas, para resumir, acho que está tudo bem aqui porque:

  • Ele está se conectando ao host local (não remoto)

  • Desde o Windows 8.1 / Server 2012R2, CredSSP não envia mais senhas em texto não criptografado

  • O Remote Desktop Protocol ainda é vulnerável a ataques pass-the-hash, assim como o CredSSP, portanto, se você está preocupado com isso para o CredSSP, também deve se preocupar com o RDP. (Claro, existe o modo RDP Restricted Admin ou o novo "Credential Guard")

PS Este artigo tornou-se minha referência Ir para PowerShell Segurança (e é onde eu aprendi sobre Credencial Guard) .. eu recomendo.

https://blogs.msdn.microsoft.com/daviddasneves/2017/05/25/powershell-security-at-enterprise-customers

Para 6.0.0, acho que vamos terminar:

Uma função de script chamada sudo que só existe no Linux (estamos adiando o suporte de elevação do Windows). Se o argumento for um cmdlet / scriptblock, ele executará sudo powershell com esses argumentos. Isso significa que, por enquanto, os objetos de pipelining não funcionarão. Se o argumento for um comando nativo, simplesmente passamos isso diretamente para o sudo.

Após 6.0.0, gostaríamos de eventualmente obter uma experiência como:

Get-Item foo.txt | sudo Remove-Item

e fazê-lo funcionar no Windows e no Linux. cc @joeyaiello

Com base na discussão do @ PowerShell / powershell-Committee, isso não é necessário para 6.0.0 e a recomendação é investir em um cmdlet do tipo Invoke-AsUser

Para alterar a elevação em geral, você precisaria de algo com o bit setuid no UNIX e que seria o próprio sudo. sudo é um binário especial que não pode ser emulado facilmente e não deve ser emulado por motivos de segurança. Deixe o sudo real ser usado para iniciar uma instância temporária do PowerShell que executa o comando em questão. Além disso, fazer o sudo em um shell inteiro é bastante inseguro, considerando que se pode esquecer o shell aberto em um servidor remoto. sudo tem um mecanismo para esquecer que o usuário eleva depois de alguns minutos o que protege a máquina a longo prazo. A resolução para esse problema permitiria que mais pessoas usassem o PowerShell em produção em servidores Linux. Do jeito que as coisas estão, o PowerShell continuará sendo uma novidade secundária, já que a segurança é fundamental na produção.

@borgdylan hoje, você pode fazer sudo pwsh -c foo dentro do PowerShell Core (ou apenas sudo nativecmd ). Acho que o desejo é poder sudo um cmdlet dentro de uma sessão existente do PowerShell Core. Não estamos tentando recriar sudo aqui, mas sim um pouco de açúcar sintático para torná-lo mais fácil de usar.

Com o # 1527 e este problema sendo empurrado cada vez mais para trás dos marcos, estou começando a me perguntar: Será que todos estão realmente confortáveis ​​fazendo login em sessões de root para fazer coisas de administração? Praticamente não há maneira conveniente de invocar comandos do PowerShell quando o PS está envolvido de alguma forma.

@MathiasMagnus Eu não testei isso completamente, mas você pode configurar comandos comuns ou usados ​​repetidamente para não exigir uma senha no sudo. Para testar eu adicionei isso com visudo:

mark ALL=(ALL:ALL) NOPASSWD: /usr/bin/pwsh

Consegui então chamar sudo pwsh -c 'cat /etc/sudoers' por meio de uma sessão remota SSH do PowerShell. Dependendo de como você está fazendo sua segurança e o que exatamente você configura no sudoers (por exemplo, All=(ALL:ALL) é um pouco aberto ...) isso pode ser seguro ou perigoso.

Se você usar ssh para Linux (ou seja, para bash shell em vez de PowerShell SSH remoting), você pode executar sudo com solicitação de senha normal dentro de pwsh, até onde eu posso dizer.

Não é tanto que seja impossível, apenas que as soluções alternativas atuais vêm com alguma bagagem.

@MathiasMagnus # 1527 ainda está direcionado para 6.1.0, pois não há uma boa solução alternativa para isso. Para cmdlets, o principal problema é a complicação do pipelining de / para um cmdlet sudo. Para operações únicas sudo pwsh -c é viável. Claro, se alguém da comunidade enviar um PR, ficaríamos mais do que felizes em aceitá-lo.

No Windows, esse agora é um problema que não acho que possa ser resolvido sem não elevar as conexões ssh, o que requer uma forma de elevar a partir da linha de comando.

Eu sei que é fácil reclamar sobre coisas que não funcionam e não estão tomando providências, mas minha experiência está em outro lugar. Eu contribuo principalmente com bibliotecas C ++ e GPGPU e Vcpkg fazendo muitos portes CMake. Nunca escrevi C # e acho que não terei capacidade para fazê-lo. No entanto, administro um pequeno cluster de aproximadamente 12 máquinas. Está no limite de ser gerenciável manualmente, mas a capacidade do sudo está ausente, ou seja, se eu não tiver a intenção de criar login para o usuário root no Ubuntu, algo que é desaprovado. DSC Core seria uma solução, mas embora tenha sido anunciado há um ano, recentemente foi adiado indefinidamente.

O PowerShell Core no Linux como está atualmente está meio preso entre a maneira automatizada de fazer as coisas e o estilo ad-hoc que é familiar aos administradores de sistemas Linux. Espero que alguém encontre tempo para tratar desta edição.

@MathiasMagnus isso é algo que todos desejam, mas não é um problema simples de resolver. Observe que o uso de sudo contra comandos nativos funciona bem, mas não está disponível para executar sudo contra cmdlets. A solução alternativa é invocar pwsh dentro de pwsh:

sudo pwsh -c remove-item algo

A principal complicação é quando é algo dentro de um pipeline:

get-item foo * | sudo remove-item

@ SteveL-MSFT Pelo menos o conceito não é tão complexo. Por favor diga-me o que você pensa.

Precisamos simplesmente de uma combinação dos binários sudo, su e login para lidar com todos os casos.

Precisa fazer:

  • Crie um soquete Unix para callbacks e só permita o acesso do usuário de destino a ele.
  • Valide se o autor da chamada tem acesso ao sudo (acho que pode-se simplesmente copiar o código-fonte do su , sudo e login )

    • Se / etc / sudoers existir, ele precisa ser analisado



      • Apenas comandos específicos


      • Usando a senha dos usuários de destino


      • Sem validar credenciais (sem senha)



    • Caso contrário, é necessário invocar o pem para verificar se o usuário "conhece" as credenciais do usuário root diretamente.

    • Se ele também não souber as credenciais dos usuários de destino, negue o acesso e lance uma exceção no PowerShell.

  • Se a validação for aprovada, precisamos mudar o contexto do usuário para root ou para o usuário de destino.
  • Uma vez que mudamos o contexto do usuário, o novo processo precisa estabelecer comunicação de volta com o PowerShell original em execução conectando-o ao soquete Unix.
  • Se o usuário inserir "exit", sinalizaremos através do soquete unix, que terminamos e quando sairmos, o usuário retornará automaticamente aos privilégios do chamador, então só precisamos do PowerShell de hospedagem para exibir um prompt ou executar o próximo instrução.
  • Se, em vez disso, o host powershell for encerrado, o soquete unix será fechado e o powershell elevado deverá interromper a execução e encerrar, como se fechasse o terminal.

O fluxo de execução ficaria assim:
PWSH (cria socket /proc/self/change-user.socket) => PWSH-SU (invocado com o soquete e usuário de destino como parâmetro; PWSH-SU é definido como suid para rodar como root) => PWSH como usuário de destino conecta para o soquete Unix.

A parte mais demorada é permitir que o PowerShell se conecte internamente por meio de um soquete Unix. Apenas redirecionar a entrada e a saída de outras aplicações Unix não é suficiente, já que lidamos com objetos e não apenas com strings ao invocar pipes.

Por que usar todos os três binários?
sudo é necessário para permitir que vários usuários alternem para o contexto raiz sem perder a capacidade de auditoria .
su é usado para mudar para qualquer outro usuário usando as credenciais do usuário de destino.
login é usado para criar uma nova sessão de login.
Ter todas essas funcionalidades também no PowerShell pode ser útil em muitos casos, comparado a ter apenas uma.

Usar pipes pode fazer com que isso funcione no Windows também de uma maneira menos surpreendente e mais conveniente - odeio receber outro shell com todos os scripts "sudo" + cliques do UAC, mas com pipes como esse isso poderia ser feito no mesmo shell como no Linux, comunicando-se por pipe com outro intérprete já em execução como administrador e talvez implementando algum sudo real (tempo limite de prompt, por exemplo, ou arquivo sudoers com comandos como alternativa para endpoints personalizados do PowerShell)

Estou muito feliz em ver os pensamentos sobre isso, mas no que diz respeito à implementação real, parece-me que estamos nos adiantando um pouco. A primeira coisa é que o sistema precisa de uma maneira de criar um processo elevado, thread, seja qual for a partir de um não elevado. Nenhuma das preocupações com o cmdlet pode ser realmente resolvida se não pudermos criar uma instância elevada do PowerShell para começar, sem passar pelo UAC. IMO, o primeiro cenário a ser abordado aqui deve ser - você tem uma sessão SSH limitada - como você executa um exe regular com permissões de administrador?

Comecei a experimentar isso aqui (atualmente interrompido enquanto o refatorava, mas o conceito funciona), mas não acho que um aplicativo de terceiros seja a solução real. Eu gostaria de ver o Windows lançar um exe 'sudo' primeiro. Isso pode ser tão simples quanto habilitar runas para criar um processo elevado com um prompt de credencial, mas sem a primeira etapa, tudo isso é teórico.

Nenhuma das preocupações com o cmdlet pode realmente ser resolvida se não pudermos criar uma instância elevada do PowerShell para começar, sem passar pelo UAC

Uma possibilidade de fazer isso envolve o uso de tarefa agendada com a opção 'executar com maior privilégio'.

Sim, mas para criar isso, você já deve ter permissões de administrador, certo? É isso que o psexec faz. Pelo que eu sei, no momento, você terá que, em algum momento, acessar o UAC. Gostaria de ver essa mudança, e com todas as sessões SSH sendo elevadas, é uma espécie de preocupação de segurança. Se algum software incompleto tentar fazer SSH em minha máquina Windows, digamos de outro computador onde eu tenha uma chave privada configurada (ou o cenário de loopback), ele pode fazer o que quiser.

@parkovski Minha solução era Linux / MacOS e todos os outros * sistemas operacionais NIX apenas. O Windows não oferece suporte a SUID e GUID.
Como sudo atualmente também não existe no Windows, ele está fora do escopo deste problema para mim.

E para resolver o problema do UAC, o Windows deve implementar SUID e GUID no futuro. Todo o resto é apenas uma solução suja para um problema antigo ...

Sim, mas para criar isso, você já deve ter permissões de administrador, certo?

Certo, mas não aciona o pop-up do UAC.

O UAC também pode ser ignorado da maneira oficial com o Application Compatibility Toolkit da Microsoft.

O Windows não oferece suporte a SUID e GUID.

O Windows não precisa ser compatível e o conceito não é válido nesse sistema operacional.
Seu modelo de permissão é baseado em ACLs e não há propriedade de grupo único.

Também não precisa ser uma réplica completa do sudo no Windows, apenas uma maneira mais amigável de invocar comandos de administrador.

Acho que não há problema em adiar o suporte do Windows, pois os usuários do Windows provavelmente estão acostumados a abrir uma sessão elevada do PowerShell hoje, enquanto os usuários do Linux esperam executar como não root e sudo conforme necessário. Queremos apenas ter certeza de que qualquer design não impede o suporte futuro do Windows. Eu provavelmente também me concentraria em simplesmente habilitar o sudo para root, em vez de qualquer usuário arbitrário para simplificá-lo, e acredito que isso é 90% do uso.

@ SteveL-MSFT

provavelmente também se concentraria em simplesmente habilitar o sudo para root ao invés de qualquer usuário arbitrário

Acho que isso não fará uma grande diferença, mas fornecerá a experiência su / sudo completa para o resumo que descrevi acima , já que mudar o contexto do usuário para root é quase o mesmo que mudar para qualquer outro usuário.

Acho que não há problema em adiar o suporte do Windows, pois os usuários do Windows provavelmente estão acostumados a abrir uma sessão elevada do PowerShell hoje

A maioria das pessoas com quem trabalhei simplesmente desabilita o UAC, se possível.

Infelizmente, isso não é realmente uma opção em muitos ambientes, e duvido que o MS vá abrir e abandonar o UAC completamente. 😕

Este problema não é sobre o UAC. Mas, do meu ponto de vista, ele deve ser completamente abandonado e substituído por duas contas estritas, um administrador, um usuário (e o administrador não pode ser usado para logon), filosofia (a instalação padrão obriga você a criá-los) ou para o mesmo conceito * NIX tem, você começa como usuário e eleva conforme necessário usando sudo e SUID / SGID-Flags.

Recentemente, adicionei o seguinte ao meu $profile . Abordei com mais detalhes em https://stackoverflow.com/a/56265080/118098

function Invoke-MySudo { & /usr/bin/env sudo pwsh -command "& $args" }
set-alias sudo invoke-mysudo

Pelo menos aparentemente, isso funciona para mim e permite "sudo". Isso não abrange o caso de" ser capaz de executar sudo em um cmdlet em uma sessão existente do PowerShell Core "por https://github.com/PowerShell/PowerShell/issues/3232#issuecomment -354853084

No entanto, eu me pergunto o quão importante é fornecer ao contexto elevado a sessão inteira do comando de chamada. Em outros shells, sudo ainda executa o comando fornecido em um novo contexto.

Implementei um sudo básico que funciona bem para executar comandos como administrador no Windows. Não tenho certeza se isso também funcionaria em linux / mac, pois não sei se "RunAs" eleva corretamente ou não nessas plataformas.

Edite seu perfil:

PS > notepad $PROFILE

Adicione a seguinte função sudo :

function sudo {
    Start-Process -Verb RunAs -FilePath "pwsh" -ArgumentList (@("-NoExit", "-Command") + $args)
}

Em seguida, invoque em seu shell. Oferece suporte a cmdlets, executáveis, qualquer coisa que normalmente poderia ser digitada em um prompt PS:

PS > sudo Remove-Item .\test.txt  # Remove a file
PS > sudo Copy-Item .\test.txt C:\  # Copy a file
PS > sudo net start w3svc  # Start IIS

Se você deseja passar uma variável ou expressão que será avaliada em tempo de execução, ao invés de pré-avaliada, coloque-a entre colchetes. Por exemplo:

PS > $myvar = "a"
PS > sudo echo $myvar  # $myvar is pre-evaluated, so the command reads: sudo echo "a"
PS > sudo { $PSVersionTable }  # with braces, $PSVersionTable is not evaluated until it is run as administrator

Remova "-NoExit" da função sudo se preferir que a janela do administrador feche quando terminar.

@vsalvino Esta é uma solução alternativa útil quando a GUI está disponível e é útil enquanto isso, mas ainda não é um sudo real porque não funciona sem acesso à GUI. Em um shell remoto (ssh), literalmente, a única maneira de fazer isso funcionar é um serviço e um cliente, como tentei demonstrar aqui .

Para abordar algumas sugestões comuns, porque acredite em mim, eu examinei todas as possibilidades:

  • Desativar o UAC não é uma solução. É uma solução alternativa que pode ser feita como uma escolha pessoal, mas não é uma solução geral para esse problema.
  • Qualquer coisa que apareça UAC (cada script "sudo" que eu vi) não é uma solução, incluindo fazer isso uma vez para iniciar uma sessão remota elevada.
  • Qualquer coisa que requeira GUI _at all_ não é uma solução. Vamos supor que estamos usando ssh aqui e a GUI não está disponível.
  • Qualquer coisa que requeira grandes mudanças no Windows não é uma solução. Não podemos esperar que o UAC se transforme em algo melhor.
  • Mesmo um binário assinado da Microsoft não é uma solução, porque não funcionará quando o UAC estiver definido como alto (entendi errado no readme do wsudo; corrigirei mais tarde).
  • A única solução real para sudo no Windows é um serviço que eleva os processos do usuário na autenticação bem-sucedida. Eu adoraria ouvir outras idéias, mas por favor, faça sua pesquisa primeiro.

Basicamente, alguém vai ter que fazer muito trabalho, não há como evitar. O que queremos é algo que, uma vez que o PowerShell suporta isso no Unix, seja um substituto no Windows e funcione como você espera que o sudo funcione (sem GUI, sem UAC).

Podemos esclarecer o escopo deste problema primeiro? Acho que várias pessoas estão falando sobre diferentes tópicos agora.
Este problema é:
a) Sobre a implementação de sudo dentro do PowerShell para sistemas Linux / Mac?
b) Implementar uma réplica do sudo no Windows?
c) Permitir elevar privilégios ao psremoting?
d) Permitir se passar por outros usuários no Windows?
e) Permitir a mudança de uma conta de usuário não privilegiado para uma conta de usuário privilegiado?
f) algo completamente diferente?

Para a) https://github.com/PowerShell/PowerShell/issues/3232#issuecomment-444849067
Para b) O mesmo que a (o Windows também tem soquetes Unix), mas em vez de um binário suid, ele precisa ser gerado por um serviço (rodando dentro de um usuário que tem privilégio "atuar como parte do sistema operacional", por exemplo, sistema do usuário) e esse serviço também precisa verificar os privilégios. Ou implemente o conceito SUID / GUID no Windows.
Para c) não exigido, você já tem os privilégios mais altos ao remoting. Não há separação de privilégios ao acessar hosts remotos (também já houve alguns desvios de UAC de loopback de host local que funcionaram dessa maneira).
Para d) Também a abordagem de a / b pode ser feita, mas não sei como isso deve funcionar ao tentar acessar recursos de rede, sem saber as credenciais dos usuários ou criar um novo back-end de autenticação do Windows / Active Directory.
Para e) O mesmo que b, mas a verificação de credencial também é necessária, como alternativa, a API runas pode ser afrouxada para permitir que um nome de usuário e senha conhecidos obtenha um novo token de usuário e mantenha o controle sobre esse processo. (Improvável considerando os conceitos e considerações de segurança do UAC, então voltamos a b).

IMO, este problema deve ser sobre como implementar sudo no PowerShell onde a funcionalidade subjacente já existe. A discussão sobre um equivalente sudo para Windows é provavelmente mais apropriada neste problema de terminal .

A discussão sobre um equivalente sudo para Windows é provavelmente mais apropriada neste problema de terminal.

Por que o aplicativo de terminal seria um lugar melhor para discutir o sudo, visto que ele é apenas mais um front-end para o mundo CLI? Pela mesma lógica, você pode registrar um tíquete no repositório ConEmu.

IMO, este problema deve ser sobre como implementar sudo no PowerShell onde a funcionalidade subjacente já existe.

Um dos pontos do próximo Powershell são menos problemas de compatibilidade entre os sistemas que o utilizam. Com relação a isso, fazer algo apenas no sistema X é IMO não aceitável.

Eu, como um usuário CLI, não poderia me importar menos se sudo é um sudo Linux completo usando o arquivo Suders ou algumas janelas semelhantes. Sudo é apenas uma interface para recursos de elevação do sistema operacional. Essa interface pode ser feita para funcionar de forma quase idêntica, independentemente do 'back-end'.

Caso contrário, o ponto @parkovski sobre a GUI permanece - eu apenas acrescentaria o Windows Core entre os motivos.

Por que o aplicativo de terminal seria um lugar melhor para discutir o sudo, visto que ele é apenas mais um front-end para o mundo CLI? Pela mesma lógica, você pode registrar um tíquete no repositório ConEmu.

Porque esse repo não é apenas "um aplicativo de terminal"; a equipe que o executa basicamente possui as partes em modo texto do Windows e já disse que está interessada em implementar o sudo quando puderem. Por outro lado, ninguém da equipe do PowerShell nem do ConEmu ofereceu.

A razão pela qual eu acho que o sudo do Windows está fora do escopo aqui é que já determinamos que fazer isso da maneira certa exige muito trabalho e é ortogonal ao próprio PowerShell. O PowerShell pode usá-lo quando existe, mas na verdade é um componente independente de qualquer shell específico.

Por outro lado, o PowerShell ser capaz de executar cmdlets por meio de um binário sudo, independentemente da plataforma ou de como esse binário realmente funciona, é totalmente uma coisa que precisa ser parte do PowerShell, que pertence bem aqui.

Eu, como um usuário CLI, não poderia me importar menos se o sudo é um sudo Linux completo usando o arquivo suders ou algumas janelas semelhantes. Sudo é apenas uma interface para recursos de elevação do sistema operacional. Essa interface pode ser feita para funcionar de forma quase idêntica, independentemente do 'back-end'.

Sim, com certeza deveria. É que o sudo ainda não existe no Windows, vai dar muito trabalho e provavelmente não vai ser escrito pela equipe do PowerShell. Quando tal coisa existir, esperemos que o PowerShell implemente isso de uma maneira que funcione apenas no Windows também.

De qualquer forma, vou adiar mais comentários até obtermos uma resposta oficial aqui, porque este problema está indo em todos os tipos de direções diferentes.

Alguma opinião sobre isso?
http://blog.lukesampson.com/sudo-for-windows
Instalado com scoop install sudo , é o mais próximo que consigo pensar. Funciona como sudo - execute comandos com elevação. Eu o uso com pip ou Install-Module para todos os usuários.

Sudo para Windows

@ Restia666Ashdoll Se for renomeado para Invoke-ElevatedCommand , estou bem com isso.
Isso porque sudo não é apenas responsável por elevar comandos, mas também por personificar usuários e "descartar" ( sudo -u nobody command ) privilégios. Além disso, reutilizar nomes já existentes provou ser uma má ideia, especialmente se a funcionalidade e os parâmetros forem diferentes.
Já esbocei acima como seria um verdadeiro sudo com personificação e como ele poderia funcionar.

@ Restia666Ashdoll Por favor, leia este comentário neste tópico.

@parkovski Isso é apenas um wrapper para -Verb RunAs, que funciona apenas com alguns comandos. Aquele que vinculei pode ser usado quase com tudo. Por exemplo, eu o uso assim - sudo pip install httpie .

Você não leu minha postagem, leu?

Suponho que não haja como editar o título para incluir algo como "NÃO É UM SUDO NO WINDOWS DISCUSSION". Eu sei que não tenho nenhuma obrigação pessoal de continuar respondendo isso, mas as pessoas continuam aparecendo dizendo a mesma coisa sem fazer suas pesquisas.

Tentei clicar no link de cancelamento de inscrição desse cara e infelizmente não me permite fazer isso sem estar conectado como ele.

denunciei @troymoore ao GitHub

Gostaria de propor uma solução única e diferente da qual não vi falar aqui. Que tal usar algo como pipes nomeados para serializar comandos para um processo elevado que retorna sua saída serializada para o processo de chamada?

Aqui está um módulo funcional que demonstra como isso funcionaria no NT: https://github.com/mmillar-bolis/Invoke-AsAdmin

Não é perfeito, claro, mas realiza elevar tarefas simples e piplines sem abrir outro console. Não pretendo apresentar isso como um sudo semelhante em si, pois não acredito que clonar o design do sudo seja a melhor solução a longo prazo, mas pensei que uma abordagem diferente para esse nebuloso problema de elevação poderia promover uma discussão construtiva.

EDIT: Devo mencionar também que isso não atenderá a solicitação de @parkovski para elevação sem UAC.

Parece JEA.
Quanto à serialização, nem todos os módulos suportam isso.

Parece JEA.

Sim, essa é a ideia.

Quanto à serialização, nem todos os módulos suportam isso.

Como você provavelmente viu no código, isso é mitigado com fluxos de texto que reconstroem o código na outra extremidade do tubo. Admito que isso é lento, mas, ainda assim, uma nova solução alternativa. Sua menção ao JEA foi novamente um fator influente aqui; se alguma parte do código de alguém não precisa ser elevada, não deve ser.

O módulo se destina a resolver um problema muito específico de elevar comandos interativos em sessões de GUI no NT e nada mais. A coisa começou há cinco anos, antes que alguém imaginasse que o ssh nativo pudesse ser uma coisa para o NT. Concordo com @parkovski que este é um problema relacionado a como o NT lida com a elevação, portanto, sem um serviço prestando atenção e fornecendo uma forma contornada de elevação de comando, é bastante difícil obter um caso de uso fácil semelhante a sudo, pkexec ou doas.

No entanto, em vez de ser interrompido por uma falácia do nirvana de que uma implementação do tipo sudo deve existir no NT antes que o PowerShell possa oferecer suporte a qualquer forma de elevação de comando, por que não pressionamos primeiro para qualquer forma de elevação interativa JEA dentro da sessão shell?

Isso pelo menos promoveria melhores práticas de segurança no mundo do NT. Por que não implementar um cmdlet para execução interativa e outro para iniciar uma sessão de console separada? Ou melhor ainda, apenas promover as formas atuais de iniciar uma sessão elevada ao lado de um conjunto mais espartano de cmdlets com diferentes casos de uso? É pelo menos um passo à frente.

Também devo acrescentar que mesmo a biblioteca de elevação Python não pode fazer o que este módulo faz. Você encontrou outro módulo para não funcionar com ele? Porque meu ponto principal é que talvez mentes mais inteligentes do que a minha possam pegar este módulo e suas idéias e executá-lo em uma direção que se encaixe no NT. Depois disso, podemos ter o início de uma plataforma para NT e * nix se encontrarem no meio, o que nos permite revisar uma implementação mais comum para PowerShell para elevar comandos.

São meus dois centavos, pelo menos. Mas, tendo visto o código, se alguém sentir que as ideias dentro dele não são boas, eu entenderei. Eu só não tinha visto ninguém tentar algo assim ainda.

Vou me afastar de minhas lutas frustradas de explicar o ponto do sudo por um minuto porque (a) sim, este é um problema muito difícil, (b) realmente só pode ser resolvido adequadamente pelo MS (obrigado por não ser de código aberto, Windows), (c) é muito legal ver que outras pessoas também são apaixonadas por isso.

Sei como é difícil fazer isso direito porque comecei a trilhar esse caminho. Portanto, se a única coisa que nos impede disso por enquanto é um diálogo do UAC, que seja. Pelo menos desta forma podemos testar uma solução de plataforma cruzada com um mínimo de esforço.

O que eu pessoalmente gostaria de ver do PowerShell é um suporte abrangente para o sudo Unix, mas projetado para oferecer suporte a alguma forma de script "pseudo-sudo" como é agora, bem como um futuro sudo real do Windows em potencial. Meu pensamento é que se alguém criar um protótipo de como um sudo do Windows acabará funcionando, mas deixar a restrição do UAC, deve ser bastante direto, nos dar algo que é basicamente o melhor que pode ser agora, e quando chegarmos ao real, deve ser bonito muito ser apenas um substituto imediato.

Obviamente, isso significa que alguém terá que criar um modelo que entenda ou pelo menos se traduza tanto no modelo Unix uid / gid quanto no modelo Windows sid / acl. Espero que essa pessoa goste de desafios. Adivinhar isso também exigirá algumas conversas com as equipes de segurança do terminal e do Windows dentro da MS.

Acho que, com tantas pessoas criando suas próprias soluções alternativas de melhor esforço, e que apoiar algo como isso poderia muito bem ajudar a projetar uma maneira robusta de fazer isso, por que não?

Sidenote - qualquer pessoa que estiver escrevendo esses scripts de solução alternativa pode considerar o recurso de tempo limite que o sudo possui, por mais irritante que seja esse popup.

Poderíamos pensar em Start-Process pwsh -NoNewWindow -Credential $cred . Não funciona, mas poderia.

Obviamente, isso significa que alguém terá que criar um modelo que entenda ou pelo menos se traduza tanto no modelo Unix uid / gid quanto no modelo Windows sid / acl. Espero que essa pessoa goste de desafios. Adivinhar isso também exigirá algumas conversas com as equipes de segurança do terminal e do Windows dentro da MS.

Unix também tem acls e windows tem compatibilidade posix e pelo menos se for um domínio comum, há também um atributo de grupo primário que poderíamos usar (assim como atributos posix). Ele apenas precisaria ser implementado para clientes do Windows não associados ao domínio (ou, por enquanto, assumido como User ).

O modelo genérico para permissões unix e windows é, portanto, basicamente:
ACLs com um usuário proprietário e um grupo proprietário com algumas ACEs esperadas (usuário, grupo e outro).

Então, poderíamos mapear as permissões unix como:
uid => Proprietário SID
gid => O SID do grupo primário do usuário que criou o objeto.
usuário => ID do proprietário criador S-1-3-0
grupo => ID do Grupo Criador S-1-3-1
outro => Mundo / Todos S-1-1-0
Mapear os uids da lista acl no unix é um pouco mais complicado, pois precisamos considerar que o sistema pode fazer parte de um ldap, diretório ativo ou qualquer outro diretório. Os únicos dois casos que eu consideraria no escopo do PowerShell são sem diretório e ldap / diretório ativo.
No primeiro caso, sugiro usar S-1-6-1-uid e S-1-6-2-gid (assumindo que S-1-6 ainda está disponível e a equipe responsável está disposta a alocá-lo para esta finalidade )
E para o segundo caso, só precisamos resolver o uid através do back-end de autenticação. O servidor ldap / active directory é então responsável por fornecer um sid.
E, finalmente, existem alguns casos especiais para mapear:
uid 0 => S-1-5-32-544
gid 0 => S-1-6-500 (e S-1-5-21 - * - 500)
a maioria dos outros sids conhecidos podem ser gerenciados por meio de um arquivo de configuração ou de algum tipo de api (ou apenas descarte-os, pois provavelmente não serão usados ​​de qualquer maneira)

Se fizermos isso no shell, comandos de construção como Get-Acl / Set-Acl iriam começar a trabalhar em sistemas unix sem saber como as permissões são armazenadas no disco.

@ mmillar-bolis Já sugeri uma abordagem usando sockets aqui: https://github.com/PowerShell/PowerShell/issues/3232#issuecomment -444849067

Poderíamos pensar em Start-Process pwsh -NoNewWindow -Credential $ cred. Não funciona, mas poderia.

Atualização: .Net Core (e acho que a API do Windows também) não permite a execução de novos processos anexados ao mesmo console.

Portanto, a única maneira que podemos usar é um serviço elevado do Windows. Mas temos que criar esse processo de serviço por "sudo" para ser seguro.
Portanto, a solução será New-PSSession (ou invocar em PSSession) para localhost com credenciais de usuário elevadas.

@iSazonov Uma das únicas coisas que permitiriam que você https://github.com/PowerShell/PowerShell/issues/3232#issuecomment -444849067

Agora que o Windows oferece suporte a soquetes Unix, poderíamos usá-los ou pipes nomeados e o serviço privilegiado seria responsável por validar as credenciais e precisaria ser executado o tempo todo (em comparação a ser invocado por suid conforme mencionado na postagem vinculada para * nix oses) .

Talvez o lsas devesse / pudesse precisar ser estendido para fornecer esses recursos de API de autenticação?
Dessa forma, poderíamos obter a representação completa e ainda sermos capazes de nos conectar com segurança ao mesmo console e aceitar entradas.

@ agowa338 Sua proposta "de fato" é comunicação remota do PowerShell. Já está implementado.

Mas

Portanto, a solução será New-PSSession (ou invocar em PSSession) para localhost com credenciais de usuário elevadas.

não funciona para localhost. Ele apenas lança AccessDenied.

Exceto um destes é o caso:

  • UAC está desligado
  • você tenta se conectar a BUILDIN \ Administrador sem que o Modo de aprovação de administrador esteja ativado.
  • o processo (PowerShell) está elevado.

Aqui está uma boa explicação por @ jborean93 : https://github.com/PowerShell/Win32-OpenSSH/issues/1308#issuecomment -448430464

Portanto, precisamos de um serviço privilegiado atuando como um corretor ou uma das APIs precisa ser alterada, mas isso não é algo que poderíamos fazer no PowerShell / PowerShell e precisaríamos ser delegados internamente pelo pessoal da Microsoft.

@ agowa338 O comentário que você fez referência é sobre a API local do Windows, não sobre a comunicação remota do PowerShell, que era uma dúvida.

@iSazonov : Você já tentou fazer remoting PowerShell para localhost? Eu fiz e não funciona pelos motivos descritos acima. A atribuição do accesstoken é bloqueada pelo sistema operacional.

A comunicação remota do PowerShell para localhost não permite obter privilégios elevados no computador local.

No entanto, a comunicação remota do PowerShell concede a você privilégios elevados em todos os outros hosts na rede, exceto localhost (supondo que você seja membro do Domain-Admins, etc).

Essa é a razão pela qual precisamos de um equivalente sudo no Windows. Se a comunicação remota do PowerShell se comportasse dessa maneira, você acha que esse tíquete pode ser fechado escrevendo um exemplo nos documentos, pois a funcionalidade já existe.

@ agowa338 Não funciona para você por causa da proteção de segurança. Não é um recurso do sistema operacional. Você pode configurar o WinRM conforme descrito em docs https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_remote_trou troubleshooting. O problema ao qual você fez referência também diz que isso funciona para SSH (as etapas estão no artigo mencionado).

pois a funcionalidade já existe.

A solicitação é para começar a trabalhar "sudo Remove-Item foo.txt onde foo.txt é propriedade do root".
Não funciona, mas gostaríamos.
O problema consiste em duas partes: sintaxe de açúcar na linguagem e implementação.

Se você pensar mais sobre sua proposta, você descobrirá que precisa ter por usuário / por sessão / por espaço de execução / por escopo de contexto do PowerShell. Em seguida, você deve atender aos requisitos de conformidade de segurança e obterá "acesso negado" na configuração padrão. Depois disso, sua proposta será a mesma que já implementou o PowerShell remoto.

Não funciona para você por causa da proteção de segurança. Não é um recurso do sistema operacional. Você pode configurar o WinRM conforme descrito nos documentos

@iSazonov Você pode explicar um pouco mais? Posso remeter para aquela máquina e de qualquer máquina para qualquer outra máquina da rede, mas de nenhuma para localhost. E sim, eu li essa página.

A solicitação é para começar a trabalhar "sudo Remove-Item foo.txt onde foo.txt é propriedade do root".

Para sistemas não Windows, poderíamos usar a abordagem de soquete unix para implementar representação / elevação para comunicação remota do PowerShell.

Você pode elaborar um pouco mais? Posso remeter para aquela máquina e de qualquer máquina para qualquer outra máquina da rede, mas de nenhuma para localhost. E sim, eu li essa página.

A maioria dos ataques tem como alvo a elevação local. Portanto, todas as configurações são "seguras por padrão". WMI, WinRM, loopback do IIS e etc - todos os subsistemas desabilitam recursos que permitem elevações locais.
Não é tão importante para a discussão. Mesmo que a comunicação remota do PowerShell não nos permita fazer sudo por padrão, poderíamos implementá-lo desligado por padrão ou permitir apenas uma sessão interativa.

Você começou a falar sobre o Windows, para sistemas não Windows, poderíamos usar a abordagem de soquete unix para implementar a representação / elevação para comunicação remota do PowerShell.

Devemos ter o mesmo UX para todas as plataformas. Realmente lá PSRP funciona em um transporte - WinRM ou SSH. A MSFT disse que gosta de SSH, mas não vejo nenhum progresso notável nos últimos dois anos. E é inacreditável que eles queiram um terceiro protocolo no futuro _ próximo_ - muito trabalho (a necessidade de manter a compatibilidade com sistemas antigos).

A maioria dos ataques tem como alvo a elevação local. Portanto, todas as configurações são "seguras por padrão". WMI, WinRM, loopback do IIS e etc - todos os subsistemas desabilitam recursos que permitem elevações locais.
Não é tão importante para a discussão. Mesmo que a comunicação remota do PowerShell não nos permita fazer sudo por padrão, poderíamos implementá-lo desligado por padrão ou permitir apenas uma sessão interativa.

Eu tentei habilitar isso há um tempo atrás, e muitos outros me disseram repetidamente que isso é restrito pelo sistema operacional internamente e não é possível de forma alguma sem um aplicativo conectado profundamente aos internos do Windows. Na verdade, muitos apontaram as restrições da API do Windows referenciadas acima e usaram isso como argumento para explicar por que o PowerShell nunca poderia fornecer tal capacidade. E alguém até fez referência a um CVE em que a elevação de loopback foi removida intencionalmente. Portanto, desculpas por ir mais fundo na toca do coelho, mas o que eu preciso configurar para que funcione? Isso está documentado em algum lugar?

Devemos ter o mesmo UX para todas as plataformas. Realmente lá PSRP funciona em um transporte - WinRM ou SSH. A MSFT disse que gosta de SSH, mas não vejo nenhum progresso notável nos últimos dois anos. E é inacreditável que eles queiram um terceiro protocolo em um futuro próximo - muito trabalho (a necessidade de manter a compatibilidade com sistemas antigos).

Bem, devemos avançar qualquer uma das duas soluções, pois ambas funcionam em qualquer plataforma.

  • PSRP: SSHing para localhost funciona para elevação no Windows e Linux, portanto, usando o subsistema psrp, já temos as permissões corretas, portanto, apenas a camada powershell precisa ser uniformizada para permitir a passagem de objetos. Direito?
  • O uso de soquetes unix também forneceria uma funcionalidade semelhante, como o PowerShell Remoting, mas no momento em que escrevo, presumi que é uma limitação difícil fazer elevação local sem qualquer tipo de serviço adicional rodando como sistema local para realizar troca de tokens ...

Portanto, como o PowerShell Remoting já existe (e meio que já funciona em relação ao ssh), devemos priorizar essa solução, eu acho.

E alguém até fez referência a um CVE em que a elevação de loopback foi removida intencionalmente.

Não posso confirmar. Acho que o CVE poderia simplesmente desativar o loopback por padrão, mas não de todo.
Veja também https://github.com/PowerShell/PowerShell/issues/3874#issuecomment -510715727

@iSazonov : Isso não funciona, ele fornece apenas o token de acesso de baixo privilégio, mas não o token de acesso elevado (por exemplo, Mandatory Label\High Mandatory Level ). Não obtenho permissões administrativas de um PowerShell de baixo privilégio, embora TrustedHosts esteja definido como * para mim. O token de logon é sempre do tipo interativo, mesmo após Enter-PSSession.
Na verdade, posso Enter-PSSession localhost -ScriptBlock {} mas passar as credenciais causa "Acesso negado". , não, sempre exibe "Acesso negado" que outro sistema tinha o uac desabilitado.

Mas agora tentei também usando SSH e funciona como esperado, fornece o token elevado ( Mandatory Label\High Mandatory Level ) com o tipo de logon Network.

Portanto, no PSCore, podemos contar com o psrp para elevação (mesmo localmente por meio de Enter-PSSession -HostName localhost que também funciona com credenciais explícitas sendo passadas.
Onde Enter-PSSession -ComputerName localhost -Credential $foo não (mesmo se $ foo.Username for igual ao usuário atual)

@ agowa338 Acho que não devemos discutir sobre como contornar os recursos de segurança do WinRM aqui (é a área sensível à conformidade). Posso apenas indicar (1) que, independentemente de um protocolo, a segurança deve permanecer no mesmo nível, o que implica que o loopback SSH deve se comportar da mesma forma que para WinRM, levando em consideração como funcionam os internos do Windows, (2) a implementação do PS sudo deve funcionar qualquer transporte.

@iSazonov : Eu não pedi um exploit, mas apenas o que precisa ser configurado para habilitá-lo. Além disso, você parece ser o único que descobriu como configurar o WinRM para permitir a elevação de loopback.
Há muito tempo tento habilitar isso. Todas as perguntas (sobre stackoverflow, reddit, github, ...) acabo em "windows is wird", "não sei o que o windows faz", "não está documentado em nenhum lugar", "Windows não fornece essa capacidade "," Use Linux em vez disso "," Desabilite o UAC "," Você precisa escrever um serviço de corretor que seja executado com privilégios de sistema ". Então, por favor, se você descobriu, compartilhe seu conhecimento.

Posso apenas indicar (1) que, independentemente de um protocolo, a segurança deve permanecer no mesmo nível

O que você quer dizer com isso?

o que implica que o loopback SSH deve se comportar da mesma forma que para WinRM, levando em consideração como o funcionamento interno do Windows

Bem, o SSH tem um serviço de sistema que atua como um corretor em segundo plano para fazer exatamente isso. Ele fornece um token de acesso à rede ...

(2) A implementação do PS sudo deve funcionar em qualquer transporte.

Bem, não supera o WinRM exatamente por esse motivo. Portanto, se for verdade o que você disse, precisamos de documentação sobre como habilitar o loopback do WinRM.

se você descobriu, compartilhe seu conhecimento.

@ agowa338 A equipe MSFT me pediu para não discutir segurança publicamente e eu sigo o CoC. Apoio seu desejo de explorar este tópico profundamente, mas como parte desta discussão, é uma dor de cabeça para a MSFT saber como integrar esta solução no Windows e manter a conformidade de segurança.

Bem, isso não ajuda ninguém.

Para convocá-lo:

  • Você diz que o Windows tem recursos semelhantes ao sudo no WinRM.
  • Não está documentado sua existência nem como habilitá-lo / desabilitá-lo.
  • Divulgar como usá-lo seria um risco à segurança.

Desculpe, mas isso soa como uma porta dos fundos e não um recurso. É inutilizável para ninguém, exceto você.
Além disso, a segurança através da obscuridade também não funcionou no passado ...

Então, estamos de volta ao que ainda não foi implementado e precisamos de um serviço de corretor que ...

@ agowa338 Reunimos informações suficientes para a equipe MSFT concluir. Se encontrarem problemas de segurança, eles nos mostrarão uma forma alternativa aceitável.

Era possível, mas foi corrigido no início deste ano https://devblogs.microsoft.com/powershell/windows-security-change-affecting-powershell/ com o patch KB4480116 e quaisquer atualizações cumulativas subsequentes. Antes desta atualização, era possível elevar seus privilégios se você tiver LocalAccountTokenFilterPolicy definido como 1, que é o que winrm quickconfig faz (e é realmente necessário para WinRM).

Há uma nota dizendo que os endpoints JEA não são afetados, então, potencialmente, você poderia criar sua própria PSSessionConfiguration e conectar-se a ela, mas não testei isso para verificar. Pessoalmente, acho que esse patch é bobo, pois ele apenas impede que o cliente PowerShell se conecte ao localhost, mas você pode contorná-lo facilmente se souber o que está fazendo. Por exemplo, ainda posso ir de limitado a elevado sem tocar no UAC usando SSH ou outro cliente PSRemoting como este

PS C:\Users\vagrant> whoami.exe /groups  # prove the current process is limited

GROUP INFORMATION
-----------------

Group Name                                                    Type             SID          Attributes

============================================================= ================ ============ ============================
======================
Everyone                                                      Well-known group S-1-1-0      Mandatory group, Enabled by
default, Enabled group
NT AUTHORITY\Local account and member of Administrators group Well-known group S-1-5-114    Group used for deny only

BUILTIN\Administrators                                        Alias            S-1-5-32-544 Group used for deny only

BUILTIN\Remote Management Users                               Alias            S-1-5-32-580 Mandatory group, Enabled by
default, Enabled group
BUILTIN\Users                                                 Alias            S-1-5-32-545 Mandatory group, Enabled by
default, Enabled group
BUILTIN\Performance Log Users                                 Alias            S-1-5-32-559 Mandatory group, Enabled by
default, Enabled group
NT AUTHORITY\REMOTE INTERACTIVE LOGON                         Well-known group S-1-5-14     Mandatory group, Enabled by
default, Enabled group
NT AUTHORITY\INTERACTIVE                                      Well-known group S-1-5-4      Mandatory group, Enabled by
default, Enabled group
NT AUTHORITY\Authenticated Users                              Well-known group S-1-5-11     Mandatory group, Enabled by
default, Enabled group
NT AUTHORITY\This Organization                                Well-known group S-1-5-15     Mandatory group, Enabled by
default, Enabled group
NT AUTHORITY\Local account                                    Well-known group S-1-5-113    Mandatory group, Enabled by
default, Enabled group
LOCAL                                                         Well-known group S-1-2-0      Mandatory group, Enabled by
default, Enabled group
NT AUTHORITY\NTLM Authentication                              Well-known group S-1-5-64-10  Mandatory group, Enabled by
default, Enabled group
Mandatory Label\Medium Mandatory Level                        Label            S-1-16-8192

PS C:\Users\vagrant> ssh vagrant<strong i="11">@localhost</strong> whoami.exe /groups  # prove that SSH is elevated
vagrant<strong i="12">@localhost</strong>'s password:

GROUP INFORMATION
-----------------

Group Name                                                    Type             SID          Attributes

============================================================= ================ ============ ============================
===================================
Everyone                                                      Well-known group S-1-1-0      Mandatory group, Enabled by
default, Enabled group
NT AUTHORITY\Local account and member of Administrators group Well-known group S-1-5-114    Mandatory group, Enabled by
default, Enabled group
BUILTIN\Administrators                                        Alias            S-1-5-32-544 Mandatory group, Enabled by
default, Enabled group, Group owner
BUILTIN\Remote Management Users                               Alias            S-1-5-32-580 Mandatory group, Enabled by
default, Enabled group
BUILTIN\Users                                                 Alias            S-1-5-32-545 Mandatory group, Enabled by
default, Enabled group
NT AUTHORITY\NETWORK                                          Well-known group S-1-5-2      Mandatory group, Enabled by
default, Enabled group
NT AUTHORITY\Authenticated Users                              Well-known group S-1-5-11     Mandatory group, Enabled by
default, Enabled group
NT AUTHORITY\This Organization                                Well-known group S-1-5-15     Mandatory group, Enabled by
default, Enabled group
NT AUTHORITY\Local account                                    Well-known group S-1-5-113    Mandatory group, Enabled by
default, Enabled group
NT AUTHORITY\NTLM Authentication                              Well-known group S-1-5-64-10  Mandatory group, Enabled by
default, Enabled group
Mandatory Label\High Mandatory Level                          Label            S-1-16-12288

PS C:\Users\vagrant> python -c "from pypsrp.client import Client; c = Client('localhost', username='vagrant', password='
<password>', ssl=False); print(c.execute_ps('whoami.exe /groups')[0])"

GROUP INFORMATION
-----------------

Group Name                                                    Type             SID          Attributes

============================================================= ================ ============ ============================
===================================
Everyone                                                      Well-known group S-1-1-0      Mandatory group, Enabled by
default, Enabled group
NT AUTHORITY\Local account and member of Administrators group Well-known group S-1-5-114    Mandatory group, Enabled by
default, Enabled group
BUILTIN\Administrators                                        Alias            S-1-5-32-544 Mandatory group, Enabled by
default, Enabled group, Group owner
BUILTIN\Remote Management Users                               Alias            S-1-5-32-580 Mandatory group, Enabled by
default, Enabled group
BUILTIN\Users                                                 Alias            S-1-5-32-545 Mandatory group, Enabled by
default, Enabled group
NT AUTHORITY\NETWORK                                          Well-known group S-1-5-2      Mandatory group, Enabled by
default, Enabled group
NT AUTHORITY\Authenticated Users                              Well-known group S-1-5-11     Mandatory group, Enabled by
default, Enabled group
NT AUTHORITY\This Organization                                Well-known group S-1-5-15     Mandatory group, Enabled by
default, Enabled group
NT AUTHORITY\Local account                                    Well-known group S-1-5-113    Mandatory group, Enabled by
default, Enabled group
NT AUTHORITY\NTLM Authentication                              Well-known group S-1-5-64-10  Mandatory group, Enabled by
default, Enabled group
Mandatory Label\High Mandatory Level                          Label            S-1-16-12288

Podemos ver que usando SSH temos um token elevado, também podemos ver que usando uma biblioteca de terceiros ainda podemos usar PSRemoting localhost que cria um token elevado e que o patch não é um bloqueio total dessa funcionalidade.

Eu não vejo isso como um problema de segurança ou cruzando um limite de segurança, já que a MS disse repetidamente que o UAC não é um limite de segurança

Pode ser próximo ou semelhante a um, mas não é à prova de falhas. Uma dessas maneiras de contornar o UAC é a propriedade de registro LocalAccountTokenFilterPolicy conhecida e documentada. O propósito explícito desta propriedade para garantir que os logons de rede sejam sempre elevados e não o token filtrado e diz explicitamente que não ter isso ativado evita ataques de "loopback"

Para proteger melhor os usuários que são membros do grupo Administradores local, implementamos restrições de UAC na rede. Este mecanismo ajuda a prevenir contra ataques de "loopback". Esse mecanismo também ajuda a evitar que softwares mal-intencionados locais sejam executados remotamente com direitos administrativos.

Em última análise, o que isso significa é que não existe uma maneira realmente oficial no Windows de elevar seus privilégios de limitados para um administrador de uma forma não interativa. É muito simples usar Start-Process ... -Verb Runas mas isso requer um logon interativo para exibir o prompt do UAC. Ter um mecanismo semelhante ao sudo ajudaria a aliviar esse problema, mas para fazê-lo corretamente, seria necessário trabalhar no próprio Windows e não ser específico do PowerShell. Existem "soluções alternativas", mas eu não as chamaria de oficiais e são apenas um subproduto conhecido da ativação do WinRM.

PowerShell
Mudança na segurança do Windows afetando o PowerShell 9 de janeiro de 2019 O patch de segurança CVE-2019-0543 do Windows recente (1/8/2019) introduziu uma mudança importante para um cenário de comunicação remota do PowerShell. É um cenário de escopo restrito que deve ter baixo impacto para a maioria dos usuários. A alteração de interrupção afeta apenas a comunicação remota de loopback local,
Blog do Mark
Eu introduzi a opção -l para PsExec há cerca de um ano e meio como uma maneira fácil de executar processos com direitos de usuário padrão de uma conta administrativa no Windows XP. Em Running as Limited User - The Easy Way, descrevi como PsExec usa a API CreateRestrictedToken para criar um contexto de segurança que é ...
Engenharia do Windows 7
Olá, Jon DeVaan aqui para falar com você sobre o feedback recente do UAC que estamos recebendo. A maior parte do nosso trabalho de finalização do Windows 7 concentra-se em responder aos comentários. O feedback do UAC é interessante em algumas dimensões do processo de tomada de decisão de engenharia. Achei que explorar essas dimensões seria um e7 interessante ...

@iSazonov Nenhuma dessas sugestões realizará uma elevação do comando _usuário-interativo_ de _ dentro da mesma sessão de console_, especialmente em um ambiente que _não tenha UAC_. Parece que você pode falar em nome da Microsoft sobre esses assuntos, então você poderia esclarecer se eles simplesmente não estão interessados ​​em apresentar tal recurso como eu o descrevi?

Se for esse o caso, como eu ter interpretado a partir dos posts acima, parece prudente para fechar esta discussão, como o resto de nós usuários terão que procurar outro lugar para soluções como @parkovski 's TokenServer idéia.

Parece que você pode falar em nome da Microsoft sobre esses assuntos

Sou um mantenedor da comunidade do projeto, não sou membro da MSFT e não posso falar em nome da Microsoft.

você poderia esclarecer se eles simplesmente não estão interessados ​​em introduzir tal recurso como eu o descrevi?

_Todas as propostas têm valor; nenhum deles é rejeitado. A discussão é apenas para coletar todas as propostas possíveis._

Atualmente estou tentando resumir todas as propostas para que possamos seguir em frente e não estagnar.

Isso eu vejo.
O cenário principal é a adoção de usuários Unix no Windows.

  • Historicamente, os usuários Unix trabalham em um console e sudo nativamente os ajuda a fazer um trabalho com direitos elevados no _same_ console
  • Historicamente, os usuários do Windows abrem uma nova janela com console de direitos elevados, se necessário. Isso funciona bem por muitos anos porque é conveniente em um ambiente com várias janelas. (Os usuários do Windows também podem se beneficiar do pssudo, levando em consideração o Windows Core e o Nano)

Portanto, as expectativas são:

  • pssudo funciona apenas em sessões interativas
  • pssudo não abre um novo console (a janela UAC é aceitável no Windows, não queremos quebrar a segurança e o espírito do Windows)
  • pssudo credenciais de cache oportunas
  • pssudo não armazena em cache um estado de sessão para segurança
  • o mesmo UX (se possível) está em todas as plataformas
  • pssudo executa comandos nativos
  • pssudo executa blocos / arquivos de script do PowerShell

Detalhes de implementação:

  • A comunicação remota do PowerShell é a solução mais poderosa e funcional. Já está implantado e funciona. Outros teriam que emular essa funcionalidade também para executar blocos de script do PowerShell por usuário / por sessão / por espaço de execução / por estado de escopo.
  • O transporte preferido é WinRM porque toda a infraestrutura do Windows é baseada nele. É necessário algum investimento no WinRM, embora a MSFT não queira isso porque é baseado em SOAP.
  • O transporte SSH pode ser. Este ainda não é o padrão do Windows. Requer um grande investimento para implementação e manutenção. E há um problema de suporte a sistemas mais antigos.
  • Outros transportes como soquetes Unix. Requer grandes investimentos não apenas em infraestrutura, mas também em PowerShell.

@ mklement0 Eu me pergunto o que eu acho aqui que você geralmente faz bem :-) Você me rouba de ser um oponente :-)

Por que não escrever um binário do Windows que requer privilégios para iniciar uma instância do PowerShell com quaisquer comandos passados ​​a ela Teria que ser um aplicativo de modo de console para funcionar corretamente. Em seguida, para o Linux, escrevemos um script que requer permissões que inicia uma instância do PowerShell com os comandos fornecidos. Se isso funcionar na prática como funciona na teoria, o PowerShell será iniciado com permissões elevadas, executa os comandos e sai.

Por que não escrever um binário do Windows que requer privilégios para iniciar uma instância do PowerShell com quaisquer comandos passados ​​a ela Teria que ser um aplicativo de modo de console para funcionar corretamente.

Porque a API do Windows impede isso e o aplicativo de console abriria em uma nova janela. Já conversamos sobre possíveis soluções alternativas.

Uma coisa a ter em mente é que não importa como isso seja implementado, sempre há um salto de processo de e para um processo elevado. Isso significa que você sempre terá objetos desserializados no pipeline e essas limitações serão aplicadas. Em muitos casos, isso não será um problema, mas se um cmdlet espera um objeto .NET ativo, ele não funcionará.

Para suportar JEA com SSH, eventualmente precisaríamos de um daemon / serviço generalizado que substituísse a necessidade de WinRM como esse serviço de qualquer maneira. Naquela época, avaliaríamos o uso disso para elevar uma parte do pipeline.

FYI: https://github.com/gerardog/gsudo

GitHub
Um Sudo para Windows - executado elevado sem abranger uma nova janela do host do console - gerardog / gsudo

FYI: https://github.com/gerardog/gsudo

GitHub gerardog / gsudo Um Sudo para Windows - execute elevado sem abranger uma nova janela do host do console - gerardog / gsudo

Melhor ainda
http://blog.lukesampson.com/sudo-for-windows

GitHub
Um Sudo para Windows - executado elevado sem abranger uma nova janela do host do console - gerardog / gsudo
Sudo para Windows

Melhor ainda

Não.

Gsudo não solicita a senha todas as vezes e é visivelmente mais rápido de instalar e usar.

Parece-me que este assunto deve ser aceito (o que significa que mais algum tempo e organização deve ser dado a ele) a julgar pelo interesse não apenas por este ticket. Não é correto não reconhecê-lo oficialmente como uma tarefa de trabalho, uma vez que as dificuldades técnicas percebidas atualmente não serão resolvidas sem um envolvimento ativo.

Estou usando o gsudo há alguns meses e não consigo me imaginar voltando ao tradicional UAC do Windows o tempo todo horrorizado.

@majkinetor, este problema foi https://github.com/PowerShell/PowerShell/issues/11343 para uma discussão mais aprofundada sobre o design

Esta página foi útil?
0 / 5 - 0 avaliações