Powershell: Soporte sudo<powershell cmdlet=""/>

Creado en 28 feb. 2017  ·  99Comentarios  ·  Fuente: PowerShell/PowerShell

pasos para reproducir

sudo Remove-Item foo.txt donde foo.txt es propiedad de root

Comportamiento esperado

foo.txt se borra

Comportamiento real

sudo: Remove-Item: command not found

Committee-Reviewed Issue-Enhancement WG-Engine

Comentario más útil

Incluso en Windows, sería bueno tener una capacidad similar para ejecutar un cmdlet como otro usuario o elevado y algo en lo que se pueda confiar en los scripts portátiles. Puede necesitar una RFC para esto.

Todos 99 comentarios

¡Tararear! Muy interesante. Pero creo que el comportamiento real es el esperado. Como en Windows, no tenemos un comando como sudo.
Pero, puede usar 'sudo powershell' y luego eliminar foo.txt (que se creó usando 'sudo powershell') y luego funciona cuando se usa Remove-Item. Por supuesto, no funcionará con un permiso no elevado.

Solo usaría 'sudo' en comandos de Linux ("sudo nautilus") desde PowerShell.

:)

Incluso en Windows, sería bueno tener una capacidad similar para ejecutar un cmdlet como otro usuario o elevado y algo en lo que se pueda confiar en los scripts portátiles. Puede necesitar una RFC para esto.

Esta funcionalidad sería útil para solucionar el problema # 3506.

Esto se convertirá en un obstáculo para adaptar Linux para mí si no se resuelve. No podemos hacer sudo bash y, de manera similar, no podremos hacer sudo powershell.

Estoy de acuerdo con Maximo, deberíamos dejar sudo para bash y crear un nuevo cmdlet para hacer elevación en powershell usando sudo como andamio en la funcionalidad esperada.

@dantraMSFT ha estado investigando esto, Dan, ¿puedes proporcionar una actualización sobre algunas ideas actuales para esto?

@pixelrebirth ¿Puede proporcionar más detalles sobre lo que espera? ¿Espera una ejecución simple con una espera, redirección de salida o redirección de canalización?
También sería útil algún ejemplo de uso.

@dantraMSFT Por el bien del argumento, voy a llamar al nuevo sudo como cmdlet: Invoke-Elevated
Así es como funciona sudo y se traduciría a Invoke-Elevated de una manera powershell

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

En este ejemplo, todo en el scriptblock se ejecutaría elevado y luego se canalizaría a un Get-SomeCmdlet NO elevado
Cred puede ser un usuario diferente o usted mismo como un usuario elevado (los permisos deben mantenerse en algún lugar como lo hace el archivo sudoers, también conocido como lista blanca)

El registro debe estar habilitado de forma predeterminada para las instancias en las que se ejecuta Invoke-Elevated:
Usuario | Comando | Registro de fecha y hora o formato similar

Tal vez algo de esto se extienda o cambie más tarde, pero esto es lo que eliminaría mis bloqueadores

También debería funcionar como:

Get-ChildItem ./test | Invoke-Elevated -command {Remove-Item -force}
Donde la credencial es su usuario actual y solo le pide la contraseña ...

Get-ChildItem no está elevado, Remove-Item está elevado en este ejemplo

Estuve en la llamada de la comunidad hoy preguntando sobre esto, pero mi esposa se lastimó durante la explicación de los desafíos y me perdí mucho. ¿Puede poner notas aquí para que pueda transmitirlas a mi jefe?

Ayudaré en todo lo posible y presionaré donde sea necesario.

@pixelrebirth espero que esté bien! Pondremos una grabación de la llamada en el próximo día o dos, para que pueda ponerse al día si lo desea.

El resumen básico es que @dantraMSFT está haciendo una investigación inicial para descubrir cómo hacer esto de una manera no pirata. Hoy, puedes sudo powershell -c "invoke-foo" desde otro shell, pero obviamente eso no funciona.

@dantraMSFT : a medida que

Puede parecer obvio, pero tal vez eche un vistazo al código fuente de sudo y vea cómo lo manejan, tal vez requiera un código de bajo nivel. Desearía tener una comprensión más profunda del código para ayudar.

Está bien, se siente en la cadera de la cirugía. Gracias por la rápida respuesta a esto. Estoy trabajando en un pequeño truco que publicaré aquí si lo logro.

@pixelrebirth Como referencia, sudo usa el bit setuid; consulte https://unix.stackexchange.com/a/80350/86669 para obtener más detalles. Sin embargo, probablemente sería una mala idea configurarlo en un shell completo.

Se debe tener un sudo nativo de Windows (por lo que el problema probablemente no pertenezca aquí, aunque la opción en la que solo se puede usar a través de Powershell es aceptable para mí). He usado Powershell desde el principio y he visto 99 variantes de script sudo, como Invoke-Elevated arriba (o el mío que uso todos los días). Incluir cmdlet como ese en Powershell sería un paso adelante, sin embargo, todos se sienten engorrosos en relación con cómo funciona esto en Linux.

Una de las cosas que me molestan es que inicia una nueva ventana de shell (no en Linux) que me gustaría ver implementada en Powershell / Windows, aunque no estoy seguro de si esto es técnicamente posible en Windows.

Aunque me gusta la idea de otro cmdlet ("Invoke-Elevated") que posiblemente podría usarse en Windows, pero no puedo entender por qué no seguir abriendo PowerShell con 'sudo' si necesita crear un script para ejecutar con alto ¿privilegio?

Especialmente si está automatizando una tarea que eventualmente se programará para ejecutarse con algún tipo de credenciales de alto privilegio de todos modos.
:)

Porque ese no es el flujo de trabajo típico. No 'sudo' y vive allí para siempre, sudo comandos específicos y vive en un mundo no sudo. No hay una manera rápida de hacerlo en Windows y el inicio de PowerShell es terriblemente lento, especialmente con pocos elementos de perfil incluidos.

En una sesión típica de todos los días, sudo 20 veces comandos específicos, otros se ejecutan sin privilegios. Ese es el objetivo de sudo, aumentar los privilegios solo cuando sea necesario y podría ser necesario con bastante frecuencia.

Mi flujo de trabajo fue, ejecutar comando, se queja de privilegios, I sudo -L que ejecutará el último comando nuevamente con privilegios. Dado que elegante es tan lento para comenzar, simplemente enciendo el shell de administración y vivo en él constantemente, claramente no es una buena idea.

¡Gracias @majkinetor!
:)

El sudo debe ser una variante CLI del indicador UAC. Windows, hasta hace poco, nunca fue compatible con CLI, pero ahora creo que lo necesitamos. Ha llegado el momento en que puedes hacer cosas 100% Windows solo en shell; yo personalmente solo uso shell y el navegador, casi nada más.

@majkinetor : Hasta donde yo sé, la única forma de iniciar un proceso elevado es a través del indicador de UAC.
FWIW: puede lograr esto en Windows sin un cambio de PowerShell usando ShellExecuteEx.
Sin embargo, si espera transmitir los resultados; es una historia muy diferente.

Hasta donde yo sé, la única forma de iniciar un proceso elevado es a través del indicador de UAC.

Las aplicaciones específicas se pueden excluir de UAC, que supongo que podrían manejar la elevación a su manera.

Quería ofrecer mi solución / solución alternativa para Sudo en Windows. Cualquier comentario / crítica será bienvenida. Si no es apropiado publicar este tipo de cosas aquí, me disculpo de antemano.

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

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

Hay tres funciones en el módulo Sudo:

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

Start-SudoSession (alias "sudo") es para comandos únicos que necesita elevar. Le solicitará las credenciales y le dará un mensaje de UAC antes de ejecutar el comando.

.EJEMPLO

$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 es para abrir una ElevatedPSSession en la que se pueden inyectar comandos elevados. La idea es que en un script más largo con múltiples operaciones que requieren elevación, creas una ElevatedPSSession al principio y recibes un mensaje UAC UNA VEZ, y luego inyectas esos comandos elevados usando Invoke-Command en esa ElevatedPSSession cuando sea necesario.

.EJEMPLO

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}

Finalmente, Remove-SudoSession elimina la ElevatedPSSession creada por la función New-SudoSession. La idea es colocar esto al final de su guión, momento en el que recibirá un mensaje de UAC. Entonces, en total, para ejecutar cualquier cantidad de operaciones elevadas en un script en particular, solo recibe dos indicaciones de UAC: una para abrir una ElevatedPSSession y otra para cerrarla. Uso de Remove-PSSession:

.EJEMPLO

$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

Debajo del capó, esto es lo que hace desde una sesión de PowerShell no elevada (si la sesión ya está elevada, no hace nada):

  • Comprueba que WinRM / WSMan esté habilitado y configurado para permitir la autenticación CredSSP (si no es así,
    se realizan cambios de configuración)

  • Comprueba el objeto de política de grupo local ...

    Configuración de la computadora -> Plantillas administrativas -> Sistema -> Delegación de credenciales -> Permitir la delegación de credenciales nuevas

    ... para asegurarse de que esté habilitado y configurado para permitir conexiones a través de WSMAN / LocalHostFQDN

  • Crea una PSSession elevada con el cmdlet New-PSSession

  • Ejecuta la expresión pasada al parámetro -Expression en la sesión PSSession elevada

  • Elimina la sesión PSSession elevada y revierte todos los cambios realizados (si los hay) en la política de grupo local y la configuración de WSMAN / WinRM.

EDITAR: error tipográfico actualizado de Remove-SudoSession.

@pldmgg No veo en qué licencia se encuentra su código, así que ni siquiera podemos ver lo que ha hecho. ¿Puede agregar un archivo de LICENCIA? El MIT sería muy amigable y nos permitiría usar su código o derivar de él. ¡Gracias!

@pldmgg Siguiendo con lo que mencionó @ SteveL-MSFT, una excelente guía para ayudarlo en este proceso es https://choosealicense.com/.

tl; dr : es difícil equivocarse con las siguientes licencias:

  • Apache 2.0
  • MIT

Más detalles

Apache 2.0 tiene algunas fortalezas adicionales sobre MIT, pero en general, son muy permisivos y fáciles de usar con otras licencias de código abierto y muy amigables para los negocios. Si elige cualquier licencia copyleft (GPL), el código no se puede usar con otras herramientas sin que esas otras herramientas pasen a una licencia GPL (también conocida como licencia viral, siendo LGPL la excepción aquí, donde los módulos / binarios con licencia LGPL pueden colocarse junto a otras herramientas sin requerir un cambio de licencia al otro código).

@pldmgg también, ¡muy, muy genial!

@ferventcoder ¡ Gracias por la referencia https://choosealicense.com! Como probablemente sospecharon ustedes (+ @ SteveL-MSFT), no estaba realmente seguro de qué licencia elegir. Actualicé todo mi repositorio misc-powershell para usar Apache 2.0, y actualicé el Sudo.psd1 para hacer referencia a Apache 2.0 (en mi repositorio de git y en la Galería de PowerShell). ¡Espero que esto pueda ser útil para la gente! ¡Todos los consejos / críticas son bienvenidos!

@ SteveL-MSFT ¿Puede usarlo si la licencia es Apache 2.0? Si necesita que sea del MIT, avíseme y lo actualizaré.

@pldmgg mi mayor problema con su solución es el uso de CredSSP. Ese es un método menos seguro para el manejo de credenciales y creo que expone un gran riesgo al límite de UAC.

Para citar de Powershell Magaize ,

"Es una mala idea usar CredSSP para autenticarse en la estación de trabajo de un usuario usando una cuenta de administrador de dominio; básicamente está regalando las llaves del reino".

"No coloque credenciales de alta confianza en equipos de baja confianza"

El objetivo de UAC es no confiar en las aplicaciones de la computadora. Aunque puedo dar mi consentimiento a un comando sudo que termina causando estragos en mi máquina, por lo general no tendrá mis credenciales. Si el comando sudo ahora tiene acceso claro a las credenciales de mi dominio, podría hacer mucho más daño al comprometer mi red.

¿Se puede hacer que su solución funcione sin CredSSP? Si no es así, ¿qué problema estaba tratando de resolver al usar CredSSP? Esa información podría ser útil para que el equipo de PowerShell encuentre una solución más segura.

@pldmgg Creo que Apache 2.0 es suficiente. ¡Gracias!

@ dragonwolf83 Esta es una preocupación común. De hecho, expuse todo mi argumento de que está bien en esta situación específica en este hilo:

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

Pero, para resumir, creo que está bien aquí porque:

  • Se conecta al host local (no remoto)

  • Desde Windows 8.1 / Server 2012R2, CredSSP ya no envía contraseñas en texto sin cifrar

  • El Protocolo de escritorio remoto sigue siendo vulnerable a los ataques de paso del hash, al igual que CredSSP, por lo que si le preocupa eso para CredSSP, también debería preocuparse por eso para RDP. (Por supuesto, existe el modo de administrador restringido de RDP o el nuevo "Credential Guard")

PS Este artículo se ha convertido en mi referencia Goto para PowerShell de Seguridad (y es donde aprendí sobre Credencial de Guardia) .. Me altamente recomiendo.

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

Para 6.0.0, creo que donde terminaremos es:

Una función de script llamada sudo que solo existe en Linux (aplazaremos el soporte de elevación de Windows). Si el argumento es un cmdlet / scriptblock, sudo powershell con esos argumentos. Esto significa que, por ahora, la canalización de objetos no funcionará. Si el argumento es un comando nativo, simplemente lo pasamos directamente a sudo.

Después de 6.0.0, nos gustaría llegar eventualmente a una experiencia como:

Get-Item foo.txt | sudo Remove-Item

y que funcione tanto en Windows como en Linux. cc @joeyaiello

Según la discusión de @ PowerShell / powershell-Committee, esto no es necesario para 6.0.0 y la recomendación es invertir en un cmdlet de tipo Invoke-AsUser

Para cambiar la elevación en general, necesitaría algo con setuid bit en UNIX y ese sería sudo. sudo es un binario especial que no se puede emular fácilmente y no debe emularse por motivos de seguridad. Deje que el sudo real se use para lanzar una instancia temporal de powershell que ejecuta el comando en cuestión. Además, sudar un shell completo es bastante inseguro considerando que uno puede olvidar el shell abierto en un servidor remoto. sudo tiene un mecanismo para olvidar que el usuario eleva después de unos minutos lo que protege la máquina a largo plazo. La resolución de este problema permitiría a más personas usar powershell en producción en servidores Linux. Tal como están las cosas, PowerShell seguirá siendo una novedad secundaria ya que la seguridad es primordial en la producción.

@borgdylan hoy, puede hacer sudo pwsh -c foo dentro de PowerShell Core (o solo sudo nativecmd ). Creo que el deseo es poder sudo un cmdlet dentro de una sesión de PowerShell Core existente. No estamos tratando de recrear sudo aquí, sino que tenemos algo de azúcar sintáctico para que sea más fácil de usar.

Con el n. ° 1527 y este problema avanzando cada vez más hacia atrás en los hitos, estoy empezando a preguntarme: ¿Todos se sienten realmente cómodos al iniciar sesión en sesiones raíz para hacer cosas de administración? Prácticamente no existe una forma conveniente de invocar comandos de PowerShell cuando PS está involucrado de alguna manera.

@MathiasMagnus No lo he probado a fondo, pero puede configurar comandos comunes o usados ​​repetidamente para no requerir una contraseña en sudo. Para probar agregué esto con visudo:

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

Luego pude llamar a sudo pwsh -c 'cat /etc/sudoers' través de una sesión remota de PowerShell SSH. Dependiendo de cómo esté haciendo su seguridad y qué configure exactamente en sudoers (por ejemplo, All=(ALL:ALL) está un poco abierto ...) esto podría ser seguro o peligroso.

Si usa ssh en Linux (es decir, para bash shell en lugar de la comunicación remota SSH de PowerShell), puede ejecutar sudo con la solicitud de contraseña normal dentro de pwsh, por lo que puedo decir.

No es tanto que sea imposible, solo que las soluciones actuales vienen con algo de equipaje.

@MathiasMagnus # 1527 todavía está dirigido a 6.1.0 ya que no hay una buena solución para eso. Para los cmdlets, el problema principal es la complicación de la canalización hacia / desde un cmdlet sudo. Para operaciones únicas sudo pwsh -c es viable. Por supuesto, si alguien de la comunidad envía un PR, estaremos más que felices de aceptarlo.

En Windows, este es ahora un problema que no creo que pueda resolverse sin no elevar las conexiones ssh, que luego requiere una forma de elevarse desde la línea de comando.

Sé que es fácil quejarse de cosas que no funcionan y no se toman medidas, pero mi experiencia está en otra parte. Principalmente contribuyo a las bibliotecas C ++ y GPGPU y Vcpkg haciendo muchas migraciones de CMake. Nunca he escrito C # y no creo que tenga la capacidad para hacerlo. Sin embargo, administro un pequeño grupo de ~ 12 máquinas. Está en el límite de ser manejable a mano, pero la capacidad de sudo falta gravemente, es decir, si no tengo la intención de crear un inicio de sesión para el usuario root en Ubuntu, algo que está mal visto. DSC Core sería una solución, pero aunque se anunció hace un año, recientemente se retrasó indefinidamente.

PowerShell Core en Linux, tal como está actualmente, está un poco atrapado entre la forma automatizada de hacer las cosas y el estilo ad-hoc que es familiar para los administradores de sistemas de Linux. Espero que alguien encuentre tiempo para atender este número.

@MathiasMagnus esto es algo que todo el mundo quiere, pero no es un problema simple de resolver. Tenga en cuenta que usar sudo contra comandos nativos funciona bien, realmente no está disponible para ejecutar sudo contra cmdlets. La solución alternativa es invocar pwsh dentro de pwsh:

sudo pwsh -c eliminar-elemento algo

La principal complicación es cuando se trata de algo dentro de una tubería:

get-item foo * | sudo remove-item

@ SteveL-MSFT Al menos el concepto no es tan complejo. Por favor, dígame lo que usted piensa.

Simplemente necesitamos una combinación de los binarios sudo, su y de inicio de sesión, para manejar todos los casos.

Necesita hacer:

  • Cree un socket Unix para devoluciones de llamada y solo permita que el usuario de destino acceda a él.
  • Valide que la persona que llama tenga acceso a sudo (creo que uno puede simplemente copiar el código fuente de su , sudo e iniciar sesión )

    • Si existe / etc / sudoers, es necesario analizarlo



      • Solo comandos específicos


      • Utilizando la contraseña de los usuarios de destino


      • Sin validar credenciales (sin contraseña)



    • Si no es así, es necesario invocar pem para verificar si el usuario "conoce" las credenciales del usuario root directamente.

    • Si tampoco conoce las credenciales de los usuarios de destino, deniegue el acceso y genere una excepción en PowerShell.

  • Si la validación pasó, debemos cambiar el contexto del usuario a la raíz o al usuario de destino.
  • Una vez que cambiamos el contexto del usuario, el nuevo proceso necesita establecer comunicación con el PowerShell original en ejecución conectándolo al socket Unix.
  • Si el usuario ingresa "salir", le indicamos a través del socket Unix que hemos terminado y cuando salimos, el usuario regresará automáticamente a los privilegios de las personas que llaman, por lo que solo necesitamos que el servidor de PowerShell muestre un mensaje o ejecute el siguiente. instrucción.
  • Si, en cambio, el PowerShell del host termina, el socket Unix se cierra y el PowerShell elevado debería detener la ejecución y terminar, como si uno cerrara el terminal.

El flujo de ejecución se vería así:
PWSH (crea socket /proc/self/change-user.socket) => PWSH-SU (invocado con el socket y el usuario de destino como parámetro; PWSH-SU está configurado como suid para ejecutarse como root) => PWSH cuando el usuario de destino se conecta al zócalo de Unix.

La parte que lleva más tiempo es permitir que el PowerShell se conecte internamente a través de un socket Unix. Simplemente redirigir los enlaces de entrada y salida que hacen otras aplicaciones Unix no es suficiente, ya que tratamos con objetos y no solo con cadenas cuando invocamos tuberías.

¿Por qué utilizar los tres binarios?
sudo es necesario para permitir que varios usuarios cambien al contexto raíz sin perder la capacidad de auditación .
su se utiliza para cambiar a cualquier otro usuario utilizando las credenciales de los usuarios de destino.
login se utiliza para crear una sesión de inicio de sesión completamente nueva.
Tener todas estas funciones también en powershell puede ser útil en muchos casos, en comparación con tener solo una.

El uso de tuberías también podría hacer que esto funcione en Windows de una manera que sea menos sorprendente y más conveniente. Odio tener otro shell con todos los scripts "sudo" + clic en UAC, pero con tuberías como esta se podría hacer dentro del mismo shell simplemente como en Linux comunicándose a través de la tubería con otro intérprete que ya se está ejecutando como administrador y tal vez implementando algunas cosas de sudo reales (tiempo de espera de solicitud, por ejemplo, o archivo sudoers con comandos como alternativa a los puntos finales personalizados de PowerShell)

Estoy muy feliz de ver los pensamientos sobre esto, pero en cuanto a la implementación real, me parece que nos estamos adelantando un poco. Lo primero es que el sistema necesita una forma de crear un proceso elevado, hilo, lo que sea a partir de uno no elevado. Ninguna de las preocupaciones de los cmdlet se puede resolver realmente si no podemos crear una instancia elevada de PowerShell para empezar, sin pasar por UAC. En mi opinión, el primer escenario que se debe abordar aquí debería ser: tiene una sesión SSH limitada, ¿cómo ejecuta un archivo ejecutable regular con permisos de administrador?

Comencé a experimentar con esto aquí (actualmente está roto porque lo he estado refactorizando, pero el concepto funciona), pero no creo que una aplicación de terceros sea la solución real. Me gustaría ver que Windows envíe un exe 'sudo' primero. Esto podría ser tan simple como habilitar runas para crear un proceso elevado con una solicitud de credencial, pero sin el primer paso, todo esto es teórico.

Ninguno de los problemas de cmdlet se puede resolver realmente si no podemos crear una instancia elevada de PowerShell para empezar, sin pasar por UAC

Una posibilidad para hacer esto implica el uso de la tarea programada con la opción 'ejecutar con el mayor privilegio'.

Sí, pero para crear eso, ya debes tener permisos de administrador, ¿verdad? Eso es lo que hace psexec. Hasta donde yo sé, en este momento, en algún momento tienes que pasar por UAC. Me gustaría ver ese cambio, y con todas las sesiones SSH elevadas, es una especie de problema de seguridad. Si algún software incompleto intenta SSH en mi máquina con Windows, digamos desde otra computadora donde tengo una clave privada configurada (o el escenario de loopback), puede hacer lo que quiera.

@parkovski Mi solución fue Linux / MacOS y todos los demás sistemas operativos * NIX solamente. Windows no es compatible con SUID y GUID.
Como sudo actualmente tampoco existe en Windows, para mí está fuera del alcance de este problema.

Y para resolver el problema de UAC, Windows debería implementar SUID y GUID en el futuro. Todo lo demás es solo una solución sucia para un problema de larga data ...

Sí, pero para crear eso, ya debes tener permisos de administrador, ¿verdad?

Correcto, pero no activa la ventana emergente UAC.

UAC también se puede omitir de manera oficial con el kit de herramientas de compatibilidad de aplicaciones de Microsoft.

Windows no es compatible con SUID y GUID.

Windows no tiene que admitirlo y el concepto no es válido en ese sistema operativo.
Su modelo de permisos se basa en ACL y no existe una propiedad de un solo grupo.

Tampoco tiene que ser una réplica completa de sudo en Windows, solo una forma más amigable de invocar comandos de administrador.

Creo que está bien posponer el soporte de Windows, ya que los usuarios de Windows probablemente estén acostumbrados a abrir una sesión elevada de PowerShell hoy, mientras que los usuarios de Linux esperan ejecutar como no root y sudo según sea necesario. Solo queremos asegurarnos de que ningún diseño excluya el soporte futuro de Windows. Probablemente también me centraría en habilitar sudo para root en lugar de cualquier usuario arbitrario para simplificarlo y creo que esto es más del 90% del uso.

@ SteveL-MSFT

probablemente también se centraría en habilitar sudo para root en lugar de cualquier usuario arbitrario

Creo que esto no hará una gran diferencia, pero proporcionará la experiencia completa de su / sudo para el resumen que describí anteriormente , ya que cambiar el contexto del usuario a root es casi lo mismo que cambiar a cualquier otro usuario.

Creo que está bien posponer el soporte de Windows ya que los usuarios de Windows probablemente estén acostumbrados a abrir una sesión elevada de PowerShell hoy

La mayoría de las personas con las que trabajé simplemente deshabilitan UAC si pueden.

Desafortunadamente, esa no es realmente una opción en muchos entornos, y dudo mucho que MS vaya a deshacerse de UAC por completo. 😕

Este problema no se trata de UAC. Pero desde mi punto de vista, debería abandonarse por completo y reemplazarse con una estricta filosofía de dos cuentas, un administrador y un usuario (y el administrador no se puede usar para iniciar sesión) (la instalación predeterminada lo obliga a crearlos) o para el mismo concepto que tiene * NIX, usted comienza como usuario y lo eleva según sea necesario usando sudo y SUID / SGID-Flags.

Recientemente agregué lo siguiente a mi $profile . Lo cubrí con más detalle en https://stackoverflow.com/a/56265080/118098

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

Al menos a primera vista, esto funciona para mí y permite "sudo". Esto no cubre el caso de" poder sudo un cmdlet dentro de una sesión de PowerShell Core existente "según https://github.com/PowerShell/PowerShell/issues/3232#issuecomment -354853084

Sin embargo, me pregunto qué tan importante es darle al contexto elevado toda la sesión del comando de llamada. En otros shells, sudo aún ejecuta el comando proporcionado en un nuevo contexto.

Implementé un sudo básico que funciona bien para ejecutar comandos como administrador en Windows. No estoy seguro de si esto también funcionaría en linux / mac, ya que no sé si "RunAs" se eleva correctamente o no en esas plataformas.

Edite su perfil:

PS > notepad $PROFILE

Agregue la siguiente función sudo :

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

Luego invoca en tu caparazón. Admite cmdlets, ejecutables, cualquier cosa que normalmente se pueda escribir en un indicador 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

Si desea pasar una variable o expresión que se evaluará en tiempo de ejecución, en lugar de evaluarla previamente, envuélvala entre llaves. Por ejemplo:

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

Elimine "-NoExit" de la función sudo si prefiere que la ventana del administrador se cierre cuando se complete.

@vsalvino Esta es una solución útil cuando la GUI está disponible y es útil mientras tanto, pero esto todavía no es un sudo real porque no funciona sin acceso a la GUI. En un shell remoto (ssh), literalmente, la única forma de hacer que esto funcione es un servicio y un cliente, como intenté demostrar aquí .

Para abordar algunas sugerencias comunes, créanme, he analizado todas las posibilidades:

  • Deshabilitar UAC no es una solución. Es una solución alternativa que puede tomarse como una elección personal, pero no es una solución general para este problema.
  • Cualquier cosa que aparezca UAC (cada secuencia de comandos "sudo" que he visto) no es una solución, incluido hacerlo una vez para iniciar una sesión remota elevada.
  • Cualquier cosa que requiera GUI _en absoluto_ no es una solución. Supongamos que estamos usando ssh aquí y la GUI no está disponible.
  • Todo lo que requiera cambios importantes en Windows no es una solución. No podemos contar con que UAC se convierta en algo mejor.
  • Incluso un binario firmado de Microsoft no es una solución, porque no funcionará cuando UAC esté configurado en alto (me equivoqué en el archivo léame de wsudo; lo corregiré más tarde).
  • La única solución real para sudo en Windows es un servicio que eleva los procesos de usuario en una autenticación exitosa. Me encantaría escuchar otras ideas, pero primero investigue.

Básicamente, alguien tendrá que hacer mucho trabajo, no hay forma de evitarlo. Lo que queremos es algo que, una vez que PowerShell admita esto en Unix, sea un reemplazo directo en Windows y funcione como esperaría que funcione sudo (sin GUI, sin UAC).

¿Podemos aclarar primero el alcance de este problema? Creo que varias personas están hablando de diferentes temas en este momento.
Es este problema:
a) ¿Acerca de la implementación de sudo dentro de powershell para sistemas linux / mac?
b) ¿Implementar una réplica de sudo en Windows?
c) ¿Permitir elevar privilegios al hacer psremoting?
d) ¿Permitir hacerse pasar por otros usuarios en Windows?
e) ¿Permitir cambiar de una cuenta de usuario sin privilegios a una cuenta de usuario con privilegios?
f) ¿algo completamente diferente?

Para a) https://github.com/PowerShell/PowerShell/issues/3232#issuecomment-444849067
Para b) Igual que a (Windows también tiene sockets Unix), pero en lugar de un binario suid, debe ser generado por un servicio (que se ejecuta dentro de un usuario que tiene el privilegio "actuar como parte del sistema operativo", por ejemplo, el sistema de usuario) y ese servicio también necesita verificar privilegios. O implemente el concepto SUID / GUID en Windows.
Para c) no es necesario, ya tiene los privilegios más altos al realizar la comunicación remota. No hay separación de privilegios al acceder a hosts remotos (también ha habido algunas omisiones de UAC de bucle de retorno de host local que funcionaron de esta manera).
Para d) También se puede tomar el enfoque de a / b, pero no sé cómo debería funcionar cuando se intenta acceder a los recursos de la red, sin conocer las credenciales de los usuarios o sin crear un nuevo backend de autenticación de Windows / directorio activo.
Para e) Igual que b, pero también se requiere verificación de credenciales, alternativamente, la api de runas podría aflojarse para permitir que un nombre de usuario y contraseña conocidos obtenga un nuevo token de usuario y mantenga el control sobre ese proceso. (Es poco probable considerando los conceptos y consideraciones de seguridad de UAC, por lo que estamos de vuelta en b).

En mi opinión, este problema debería ser sobre la implementación de sudo en PowerShell donde la funcionalidad subyacente ya existe. La discusión sobre un equivalente de sudo para Windows es probablemente más apropiada en este tema de terminal .

La discusión sobre un equivalente de sudo para Windows es probablemente más apropiada en este tema de terminal.

¿Por qué la aplicación de terminal sería un mejor lugar para discutir sudo, dado que es solo otra interfaz más para el mundo CLI? Con la misma lógica, podría presentar un ticket en el repositorio de ConEmu.

En mi opinión, este problema debería ser sobre la implementación de sudo en PowerShell donde la funcionalidad subyacente ya existe.

Uno de los puntos del próximo Powershell es menos problemas de compatibilidad entre los sistemas que lo utilizan. Con respecto a eso, hacer algo solo en el sistema X es IMO no aceptable.

A mí, como usuario de CLI, no me podría importar menos si sudo es un sudo de linux completo usando el archivo suders o algunas ventanas por igual. Sudo es solo una interfaz para las funciones de elevación del sistema operativo. Una interfaz de este tipo podría funcionar de manera casi idéntica independientemente del "backend".

De lo contrario, @parkovski señala sobre los soportes de GUI: solo agregaría Windows Core entre las razones.

¿Por qué la aplicación de terminal sería un mejor lugar para discutir sudo, dado que es solo otra interfaz más para el mundo CLI? Con la misma lógica, podría presentar un ticket en el repositorio de ConEmu.

Porque ese repositorio no es solo "una aplicación de terminal"; el equipo que lo ejecuta básicamente posee las partes en modo texto de Windows y ya ha dicho que están interesados ​​en implementar sudo cuando puedan encontrar el tiempo. Por otro lado, nadie del equipo de PowerShell ni ConEmu lo ha ofrecido.

La razón por la que creo que el sudo de Windows está fuera del alcance aquí es que ya hemos determinado que hacerlo bien es una gran cantidad de trabajo y es ortogonal al propio PowerShell. PowerShell puede usarlo cuando existe, pero en realidad es un componente independiente de cualquier shell en particular.

Por otro lado, PowerShell puede ejecutar cmdlets a través de un binario sudo, independientemente de la plataforma o de cómo funciona ese binario, es algo que tiene que ser parte de PowerShell, que pertenece aquí.

A mí, como usuario de CLI, no me podría importar menos si sudo es linux sudo completo usando el archivo suders o algunas ventanas por igual. Sudo es solo una interfaz para las funciones de elevación del sistema operativo. Una interfaz de este tipo podría funcionar de manera casi idéntica independientemente del "backend".

Sí, absolutamente debería. Es solo que sudo aún no existe en Windows, requerirá mucho trabajo y probablemente no lo escribirá el equipo de PowerShell. Cuando exista algo así, esperemos que PowerShell lo implemente de una manera en la que también funcione en Windows.

De todos modos, postergaré más comentarios hasta que obtengamos una respuesta oficial aquí porque este problema va en todo tipo de direcciones diferentes.

¿Alguna opinión sobre esto?
http://blog.lukesampson.com/sudo-for-windows
Instalado con scoop install sudo , es lo más cercano que puedo pensar. Funciona como unix sudo: ejecuta comandos con elevación. Lo uso con pip o Install-Module para todos los usuarios.

Sudo para Windows

@ Restia666Ashdoll Si se le cambia el nombre a Invoke-ElevatedCommand Estoy bien con eso.
Eso es porque sudo no solo es responsable de elevar los comandos, sino también de hacerse pasar por usuarios y "eliminar" ( sudo -u nobody command ) privilegios. También se ha demostrado que reutilizar nombres ya existentes es una mala idea, especialmente si la funcionalidad y los parámetros difieren.
Ya describí anteriormente cómo se vería un verdadero sudo con suplantación y cómo podría funcionar.

@ Restia666Ashdoll Por favor, lea este comentario en este hilo.

@parkovski Eso es solo un contenedor para -Verb RunAs, que solo funciona con unos pocos comandos. El que me vinculé se puede usar casi con todo. Por ejemplo, lo uso así: sudo pip install httpie .

No leíste mi publicación, ¿verdad?

Supongo que no hay forma de editar el título para incluir algo como "NO ES UN SUDO EN WINDOWS DISCUSSION" Sé que personalmente no tengo ninguna obligación de seguir respondiendo esto, pero la gente sigue apareciendo diciendo lo mismo sin hacer su investigación.

Intenté hacer clic en el enlace para cancelar la suscripción de este tipo y, lamentablemente, no me dejará hacerlo sin haber iniciado sesión como él.

Ya he informado de @troymoore a GitHub

Me gustaría proponer una solución única y diferente de la que no he visto hablar aquí. ¿Qué pasa con el uso de algo como tuberías con nombre para serializar comandos en un proceso elevado que luego devuelve su salida serializada al proceso de llamada?

Aquí hay un módulo funcional que demuestra cómo funcionaría esto en NT: https://github.com/mmillar-bolis/Invoke-AsAdmin

No es perfecto, por supuesto, pero logra elevar tareas simples y líneas de conducción sin abrir otra consola. No tengo la intención de presentar esto como un sudo similar per se, ya que no creo que clonar el diseño de sudo sea la mejor solución a largo plazo, pero pensé que un enfoque diferente a este nebuloso problema de elevación podría promover una discusión constructiva.

EDITAR: También debo mencionar que esto no cumplirá con la solicitud de @parkovski para la elevación sin UAC.

Parece JEA.
En cuanto a la serialización, no todos los módulos lo admiten.

Parece JEA.

Sí, esa es la idea.

En cuanto a la serialización, no todos los módulos lo admiten.

Como probablemente vio en el código, esto se mitiga con flujos de texto que reconstruyen el código en el otro extremo de la tubería. Admito que esto es lento, pero no obstante, una solución novedosa. Su mención de JEA fue nuevamente un factor influyente aquí; si alguna parte del código de uno no necesita ser elevado, no debería serlo.

El módulo está destinado a resolver un problema muy específico de elevar comandos interactivos dentro de sesiones GUI en NT y nada más. La cosa comenzó como hace cinco años antes de que alguien imaginara que el ssh nativo podría ser algo para NT. Estoy de acuerdo con @parkovski en que este es un problema relacionado con la forma en que NT maneja la elevación, por lo que sin un servicio que escuche y proporcione una forma contorneada de elevación de comandos, es bastante difícil lograr un caso de facilidad de uso similar a sudo, pkexec o doas.

Sin embargo, en lugar de ser detenido por una falacia de nirvana de que debe existir una implementación similar a sudo en NT antes de que PowerShell pueda admitir cualquier forma de elevación de comando, ¿por qué no presionamos primero por cualquier forma de elevación interactiva de JEA dentro de la sesión de shell?

Esto al menos promovería mejores prácticas de seguridad en el mundo NT. ¿Por qué no implementar un cmdlet para que se ejecute de forma interactiva y otro para iniciar una sesión de consola independiente? O mejor aún, ¿simplemente promover las formas actuales de iniciar una sesión elevada junto con un conjunto de cmdlets más espartano con diferentes casos de uso? Es al menos un paso adelante.

También podría agregar que incluso la biblioteca Python elevate no puede hacer lo que hace este módulo. ¿Ha encontrado otro módulo para no trabajar con él? Porque mi punto principal es que tal vez mentes más inteligentes que la mía puedan tomar este módulo y sus ideas y ejecutarlo en una dirección que se ajuste a NT. Después de eso, es posible que tengamos los inicios de una plataforma para que NT y * nix se encuentren en el medio, lo que nos permitirá revisar una implementación más común de PowerShell para elevar los comandos.

Esos son mis dos centavos, al menos. Pero después de haber visto el código, si uno siente que las ideas que contiene no son buenas, lo entenderé. Simplemente no había visto a nadie intentar algo como esto todavía.

Voy a dar un paso atrás de mis lamentos frustrados de explicar el punto de sudo por un minuto porque (a) sí, este es un problema muy difícil, (b) realmente solo puede ser resuelto correctamente por MS (gracias por no ser de código abierto, Windows), (c) es realmente genial ver que a otros también les apasiona esto.

Sé lo difícil que es hacer esto correctamente porque comencé por ese camino. Entonces, si lo único que nos impide eso por ahora es un diálogo de UAC, que así sea. Al menos de esta manera podemos probar una solución multiplataforma con un esfuerzo menor.

Lo que personalmente me gustaría ver de PowerShell es un soporte completo para el sudo de Unix, pero diseñado para admitir alguna forma de script "pseudo-sudo" tal como es ahora, así como un sudo de Windows real y potencial futuro. Mi pensamiento es que si alguien crea un prototipo de cómo funcionará un sudo de Windows, pero deja la restricción de UAC, debería ser bastante sencillo, darnos algo que sea básicamente tan bueno como lo es por ahora, y cuando obtengamos lo real, debería ser bonito. mucho más ser un reemplazo directo.

Obviamente, esto significa que alguien tendrá que encontrar un modelo que comprenda o al menos se traduzca tanto en el modelo Unix uid / gid como en el modelo Windows sid / acl. Ojalá a esta persona le gusten los desafíos. Adivinar esto también requerirá algunas conversaciones con la terminal y los equipos de seguridad de Windows dentro de MS.

Supongo que con tantas personas que han creado sus propias soluciones alternativas con el mejor esfuerzo y que apoyar algo como esto podría ayudar a diseñar una forma sólida de hacer esto, ¿por qué no?

Nota al margen: cualquiera que escriba estos scripts de solución alternativa podría considerar la función de tiempo de espera que tiene sudo, por molesta que sea esa ventana emergente.

Podríamos pensar en Start-Process pwsh -NoNewWindow -Credential $cred . No funciona pero podría.

Obviamente, esto significa que alguien tendrá que encontrar un modelo que comprenda o al menos se traduzca tanto en el modelo Unix uid / gid como en el modelo Windows sid / acl. Ojalá a esta persona le gusten los desafíos. Adivinar esto también requerirá algunas conversaciones con la terminal y los equipos de seguridad de Windows dentro de MS.

Unix también tiene acls y windows tiene compatibilidad con posix y al menos si es un dominio conjunto, también hay un atributo de grupo primario que podríamos usar (así como atributos posix). Solo debería implementarse para clientes de Windows no unidos a un dominio (o por ahora se supone que es User ).

El modelo genérico para permisos de Unix y Windows es básicamente:
ACL con un usuario propietario y un grupo propietario con algunas ACE esperadas (usuario, grupo y otras).

De lo que podríamos mapear los permisos de Unix como:
uid => SID del propietario
gid => El SID del grupo primario del usuario que creó el objeto.
usuario => ID de propietario del creador S-1-3-0
group => ID de grupo creador S-1-3-1
otro => Mundo / Todos S-1-1-0
Mapear los uids de la lista acl en unix es un poco más complicado ya que debemos considerar que el sistema puede ser parte de un ldap, directorio activo o cualquier otro directorio. Los únicos dos casos que consideraría dentro del alcance de powershell son sin directorio y directorio ldap / active.
En el primer caso, sugeriría usar S-1-6-1-uid y S-1-6-2-gid (suponiendo que S-1-6 todavía esté disponible y el equipo responsable esté dispuesto a asignarlo para este propósito ).
Y para el segundo caso, solo necesitamos tener algún tipo de resolución del uid a través del backend de autenticación. El servidor de directorio activo / ldap es responsable de proporcionar un sid.
Y finalmente hay algunos casos especiales para mapear:
uid 0 => S-1-5-32-544
gid 0 => S-1-6-500 (y S-1-5-21 - * - 500)
la mayoría de los otros sids conocidos se pueden administrar a través de un archivo de configuración o mediante una API de algún tipo (o simplemente elimínelos, ya que lo más probable es que no se usen de todos modos)

Si hacemos esto en el shell, comandos como Get-Acl / Set-Acl comenzarían a funcionar en sistemas Unix sin saber cómo se almacenan los permisos en el disco.

@ mmillar-bolis Ya sugerí un enfoque usando sockets aquí: https://github.com/PowerShell/PowerShell/issues/3232#issuecomment -444849067

Podríamos pensar en Start-Process pwsh -NoNewWindow -Credential $ cred. No funciona pero podría.

Actualización: .Net Core (y supongo que la API de Windows también) no permite ejecutar un nuevo proceso adjunto a la misma consola.

Entonces, la única forma en que podemos usar es un servicio de Windows elevado. Pero tenemos que crear dicho proceso de servicio por "sudo" para estar seguros.
Entonces, la solución será New-PSSession (o invocar en PSSession) a localhost con credenciales de usuario elevadas.

@iSazonov Una de las únicas cosas que le permitiría conectarlo a la misma consola es lo que ya mencioné aquí: https://github.com/PowerShell/PowerShell/issues/3232#issuecomment -444849067

Ahora que Windows admite sockets Unix, podríamos usarlos o canalizaciones con nombre y el servicio privilegiado sería responsable de validar las credenciales y necesitaría ejecutarse todo el tiempo (en comparación con ser invocado sobre suid como se menciona en la publicación vinculada para * nix oses) .

¿Quizás lsas necesitaría / podría ser extendido para proporcionar tales capacidades de API de autenticación?
De esa manera, podríamos obtener una suplantación completa y, al mismo tiempo, poder conectarnos de forma segura a la misma consola y aceptar entradas.

@ agowa338 Su propuesta "de facto" es la comunicación remota de PowerShell. Ya está implementado.

Pero

Entonces, la solución será New-PSSession (o invocar en PSSession) a localhost con credenciales de usuario elevadas.

no funciona para localhost. Solo arroja AccessDenied.

Excepto que uno de estos es el caso:

  • UAC está apagado
  • intenta conectarse a BUILDIN \ Administrator sin habilitar el modo de aprobación de administrador.
  • el proceso (powershell) ya está elevado.

Aquí hay una buena explicación de por qué es de @ jborean93 : https://github.com/PowerShell/Win32-OpenSSH/issues/1308#issuecomment -448430464

Por lo tanto, necesitamos un servicio privilegiado que actúe como intermediario o una de las API debe cambiar, pero eso no es algo que podamos hacer dentro de PowerShell / PowerShell y tendría que ser delegado por la gente de Microsoft internamente.

@ agowa338 El comentario al que hizo referencia es sobre la API local de Windows, no sobre la comunicación remota de PowerShell que era una pregunta allí.

@iSazonov : ¿Ha intentado siquiera hacer una comunicación remota de PowerShell con localhost? Lo hice y no funciona por las razones descritas anteriormente. El sistema operativo bloquea la asignación del token de acceso.

La comunicación remota de PowerShell a localhost no permite obtener privilegios elevados en la computadora local.

Sin embargo, la comunicación remota de PowerShell le otorga privilegios elevados en todos los demás hosts de la red, excepto localhost (asumiendo que es miembro de Domain-Admins, etc.).

Esa es la razón por la que necesitamos un equivalente de sudo en Windows. Si la comunicación remota de PowerShell se comportara de esa manera, usted cree que lo hace, este ticket podría cerrarse escribiendo un ejemplo en los documentos, ya que la funcionalidad ya existe.

@ agowa338 No funciona para usted debido a la protección de seguridad. No es una característica del sistema operativo. Puede configurar WinRM como se describe en los documentos https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_remote_troubleshooting . El problema al que hizo referencia también dice que esto funciona para SSH (los pasos se encuentran en el artículo mencionado).

ya que la funcionalidad ya existe.

La solicitud es que funcione "sudo Remove-Item foo.txt donde foo.txt es propiedad de root".
No funciona pero quisiéramos.
El problema consta de dos partes: azúcar de sintaxis en el lenguaje e implementación.

Si piensa más en su propuesta, descubre que necesita tener por usuario / por sesión / por espacio de ejecución / por alcance el contexto de PowerShell. Luego, debe abordar los requisitos de cumplimiento de seguridad y obtendrá "acceso denegado" en la configuración predeterminada. Después de eso, su propuesta será la misma que la comunicación remota de PowerShell ya implementada.

No funciona para usted debido a la protección de seguridad. No es una característica del sistema operativo. Puede configurar WinRM como se describe en los documentos

@iSazonov ¿Puedes explicarlo un poco más? Puedo remotamente a esa máquina y desde cualquier máquina a cualquier otra máquina en la red, pero desde ninguna de ellas a localhost. Y sí, leí esa página.

La solicitud es que funcione "sudo Remove-Item foo.txt donde foo.txt es propiedad de root".

Para los sistemas que no son de Windows, podríamos usar el enfoque de socket Unix para implementar la suplantación / elevación para la comunicación remota de PowerShell allí.

¿Puedes explicarlo un poco más? Puedo remotamente a esa máquina y desde cualquier máquina a cualquier otra máquina en la red, pero desde ninguna de ellas a localhost. Y sí, leí esa página.

La mayoría de los ataques tienen como objetivo la elevación local. Así que todas las configuraciones son "seguras por defecto". WMI, WinRM, IIS loopback, etc., todos los subsistemas desactivan funciones que permiten elevaciones locales.
No es tan importante para la discusión. Incluso si la comunicación remota de PowerShell no nos permite hacer sudo de forma predeterminada, podríamos implementarlo desactivado de forma predeterminada o permitir solo una sesión interactiva.

Comenzó a hablar de Windows, para los sistemas que no son Windows, podríamos usar el enfoque de socket Unix para implementar la suplantación / elevación para la comunicación remota de PowerShell allí.

Deberíamos tener la misma UX para todas las plataformas. Realmente, PSRP funciona sobre un transporte: WinRM o SSH. MSFT dijo que les gusta SSH, pero no veo ningún progreso notable en los últimos dos años. Y es increíble que quieran un tercer protocolo en el futuro cercano: demasiado trabajo (la necesidad de mantener la compatibilidad con sistemas antiguos).

La mayoría de los ataques tienen como objetivo la elevación local. Así que todas las configuraciones son "seguras por defecto". WMI, WinRM, IIS loopback, etc., todos los subsistemas desactivan funciones que permiten elevaciones locales.
No es tan importante para la discusión. Incluso si la comunicación remota de PowerShell no nos permite hacer sudo de forma predeterminada, podríamos implementarlo desactivado de forma predeterminada o permitir solo una sesión interactiva.

Traté de habilitar eso hace un tiempo, y muchos otros me dijeron repetidamente que esto está restringido por el sistema operativo internamente y que no es posible de ninguna manera sin una aplicación que se conecte profundamente a las partes internas de Windows. De hecho, muchos han señalado las restricciones de la API de Windows mencionadas anteriormente y las han utilizado como argumento de por qué PowerShell nunca podría proporcionar tal capacidad. Y alguien incluso hizo referencia a un CVE donde la elevación de bucle invertido se eliminó intencionalmente. Por lo tanto, las disculpas por ir un poco más profundo por ese agujero de conejo, pero ¿qué necesito configurar para que funcione? ¿Eso está documentado en alguna parte?

Deberíamos tener la misma UX para todas las plataformas. Realmente, PSRP funciona sobre un transporte: WinRM o SSH. MSFT dijo que les gusta SSH, pero no veo ningún progreso notable en los últimos dos años. Y es increíble que quieran un tercer protocolo en un futuro cercano: demasiado trabajo (la necesidad de mantener la compatibilidad con sistemas antiguos).

Bueno, entonces deberíamos impulsar cualquiera de las dos soluciones, ya que ambas funcionan en cualquier plataforma.

  • PSRP: SSHing a localhost funciona para la elevación en Windows y Linux, por lo tanto, al usar el subsistema psrp ya tenemos los permisos correctos, por lo que solo la capa de powershell debe uniformarse para permitir el paso de objetos. ¿Correcto?
  • El uso de sockets Unix también proporcionaría una funcionalidad similar como la comunicación remota de PowerShell, pero en el momento de escribir, asumí que es una limitación difícil hacer elevación local sin ningún tipo de servicio adicional ejecutándose como sistema local para realizar el intercambio de tokens ...

Por lo tanto, como powershell remoting ya está allí (y también funciona un poco sobre ssh), creo que deberíamos priorizar esa solución.

Y alguien incluso hizo referencia a un CVE donde la elevación de bucle invertido se eliminó intencionalmente.

No puedo confirmar. Supongo que el CVE podría simplemente deshabilitar el loopback de forma predeterminada, pero no en absoluto.
Consulte también https://github.com/PowerShell/PowerShell/issues/3874#issuecomment -510715727

@iSazonov : Eso no funciona, solo proporciona el token de acceso de privilegios bajos pero no el token de acceso elevado (por ejemplo, Mandatory Label\High Mandatory Level ). No obtengo permisos administrativos de un powershell con privilegios bajos a pesar de que TrustedHosts está configurado en * para mí. El token de inicio de sesión siempre es de tipo interactivo, incluso después de Enter-PSSession.
De hecho, puedo Enter-PSSession localhost -ScriptBlock {} pero pasar las credenciales provoca "Acceso denegado". , no, siempre arroja "Acceso denegado" que otro sistema tenía uac deshabilitado.

Pero ahora lo probé también usando SSH y eso funciona como se esperaba, proporciona el token elevado ( Mandatory Label\High Mandatory Level ) con el tipo de inicio de sesión Network.

Por lo tanto, en PSCore podemos confiar en psrp para la elevación (incluso localmente a través de Enter-PSSession -HostName localhost que también funciona con credenciales explícitas que se pasan.
Donde Enter-PSSession -ComputerName localhost -Credential $foo no lo hace (incluso si $ foo.Username es el mismo que el usuario actual)

@ agowa338 Creo que no deberíamos discutir eludir las características de seguridad de WinRM aquí (es un área sensible al cumplimiento). Solo puedo indicar (1) que, independientemente de un protocolo, la seguridad debe permanecer al mismo nivel, lo que implica que el bucle de retorno SSH debe comportarse igual que para WinRM teniendo en cuenta cómo funcionan los componentes internos de Windows, (2) la implementación de PS sudo debe funcionar cualquier transporte.

@iSazonov : No pedí un exploit, sino solo lo que se debe configurar para habilitarlo. También parece que eres el único que descubrió cómo configurar WinRM para permitir la elevación de bucle invertido.
He intentado habilitar eso durante mucho tiempo. Todas las preguntas (sobre stackoverflow, reddit, problemas de github, ...) me encuentro con "windows is wird", "no sé qué hace Windows allí", "no está documentado en ninguna parte", "Windows no proporciona esa capacidad "," Use Linux en su lugar "," Desactive UAC "," Necesita escribir un servicio de agente que se ejecute con privilegios del sistema ". Así que, por favor, si lo resolvió, comparta sus conocimientos.

Solo puedo indicar (1) que independientemente de un protocolo, la seguridad debe permanecer al mismo nivel

¿Que quieres decir con eso?

lo que implica que SSH loopback debería comportarse igual que para WinRM teniendo en cuenta cómo funcionan los componentes internos de Windows

Bueno, SSH tiene un servicio de sistema que actúa como un corredor en segundo plano para hacer exactamente eso. Proporciona un token de acceso a la red ...

(2) La implementación de PS sudo debería funcionar en cualquier transporte.

Bueno, no supera a WinRM exactamente por esa razón. Entonces, si es cierto lo que dijo, necesitamos documentación sobre cómo habilitar el bucle invertido de WinRM.

si lo descubrió, comparta sus conocimientos.

@ agowa338 El equipo de MSFT me pidió que no discutiera la seguridad públicamente y sigo el CoC. Apoyo su deseo de explorar este tema en profundidad, pero como parte de esta discusión, es un dolor de cabeza para MSFT cómo integrar esta solución en Windows y mantener el cumplimiento de seguridad.

Bueno, eso no ayuda a nadie.

Para convocarlo:

  • Dices que Windows tiene capacidades similares a sudo dentro de WinRM.
  • No está documentado que exista ni cómo habilitarlo / deshabilitarlo.
  • Revelar cómo usarlo sería un riesgo de seguridad.

Lo siento, pero eso suena como una puerta trasera y no como una característica. Es inutilizable para nadie excepto para usted.
Además, la seguridad a través de la oscuridad tampoco ha funcionado en el pasado ...

Así que estamos de vuelta en que actualmente no está implementado y necesitamos un servicio de corredor que ...

@ agowa338 Hemos recopilado suficiente información para que el equipo de MSFT concluya. Si encuentran problemas de seguridad, nos mostrarán una forma alternativa aceptable.

Fue posible, pero se parcheó a principios de este año https://devblogs.microsoft.com/powershell/windows-security-change-affecting-powershell/ con el parche KB4480116 y cualquier actualización acumulativa posterior. Antes de esta actualización, era posible elevar sus privilegios si tiene LocalAccountTokenFilterPolicy establecido en 1, que es lo que hace winrm quickconfig (y es realmente necesario para WinRM).

Hay una nota allí que dice que los puntos finales de JEA no se ven afectados, por lo que potencialmente podría crear su propia configuración de PSSessionConfiguration y conectarse a eso, pero no lo he probado para verificar. Personalmente, creo que este parche es una tontería ya que este parche simplemente evita que el cliente de PowerShell se conecte a localhost, pero puede omitirlo fácilmente si sabe lo que está haciendo. Por ejemplo, todavía puedo pasar de limitado a elevado sin tocar UAC usando SSH u otro cliente PSRemoting como ese

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 tenemos un token elevado, también podemos ver que usando una biblioteca de terceros todavía podemos usar localhost PSRemoting que crea un token elevado y que el parche no es un bloque total de esta funcionalidad.

No veo esto como un problema de seguridad o cruzar un límite de seguridad, ya que MS ha dicho repetidamente que UAC no es un límite de seguridad.

Puede estar cerca o actuar de manera similar a uno, pero no es infalible. Una de esas formas de eludir UAC es la propiedad de registro conocida y documentada LocalAccountTokenFilterPolicy . El propósito explícito de esta propiedad es garantizar que los inicios de sesión de la red sean siempre elevados y no el token filtrado y dice explícitamente que no tener esto habilitado evita los ataques de "bucle invertido".

Para proteger mejor a los usuarios que son miembros del grupo de administradores locales, implementamos restricciones de UAC en la red. Este mecanismo ayuda a prevenir ataques de "bucle invertido". Este mecanismo también ayuda a evitar que el software malintencionado local se ejecute de forma remota con derechos administrativos.

En última instancia, lo que eso significa es que no existe una forma realmente oficial en Windows de elevar sus privilegios de limitados a administradores de una manera no interactiva. Es bastante simple usar Start-Process ... -Verb Runas pero requiere un inicio de sesión interactivo para mostrar el indicador de UAC. Tener un mecanismo similar a sudo ayudaría a aliviar este problema, pero hacerlo correctamente requeriría trabajar en Windows y no ser específico de PowerShell. Hay "soluciones alternativas", pero yo no las llamaría oficiales y son solo un subproducto conocido de habilitar WinRM.

Potencia Shell
Cambio de seguridad de Windows que afecta a PowerShell 9 de enero de 2019 El reciente parche de seguridad de Windows (8/1/2019) CVE-2019-0543 ha introducido un cambio radical para un escenario de comunicación remota de PowerShell. Es un escenario de ámbito limitado que debería tener un impacto bajo para la mayoría de los usuarios. El cambio de ruptura solo afecta a la comunicación remota de loopback local,
Blog de Mark
Introduje el cambio -l a PsExec hace aproximadamente un año y medio como una forma fácil de ejecutar procesos con derechos de usuario estándar desde una cuenta administrativa en Windows XP. En Ejecutar como usuario limitado: la forma fácil, describí cómo PsExec usa la API CreateRestrictedToken para crear un contexto de seguridad que es un ...
Ingeniería de Windows 7
Hola, Jon DeVaan está aquí para hablar con usted sobre los comentarios recientes de UAC que hemos estado recibiendo. La mayor parte de nuestro trabajo para terminar Windows 7 se centra en responder a los comentarios. La retroalimentación de UAC es interesante sobre algunas dimensiones del proceso de toma de decisiones de ingeniería. Pensé que explorar esas dimensiones sería un e7 interesante ...

@iSazonov Ninguna de estas sugerencias logrará una elevación del comando _user-interactive_ desde _dentro de la misma sesión de consola_, especialmente en un entorno que _carece de UAC_. Parece que puede hablar en nombre de Microsoft en estos asuntos, entonces, ¿podría aclarar si simplemente no están interesados ​​en presentar una característica como la que he descrito?

Si ese es el caso, como he interpretado desde los puestos de arriba, parece prudente cerrar este hilo, como el resto de nosotros los usuarios tendrán que buscar otro lugar para soluciones como @parkovski 's TokenServer idea.

Parece que puede hablar en nombre de Microsoft en estos asuntos.

Soy un mantenedor de la comunidad del proyecto, no miembro de MSFT y no puedo hablar en nombre de Microsoft.

¿Podría aclarar si simplemente no están interesados ​​en presentar una característica como la que he descrito?

_Todas las propuestas tienen valor; ninguno de ellos es rechazado. La discusión es solo para recopilar todas las propuestas posibles.

Actualmente estoy intentando resumir todas las propuestas para que podamos avanzar y no estancarnos.

Que veo.
El escenario principal es la adopción de usuarios de Unix en Windows.

  • Históricamente, los usuarios de Unix trabajan en una consola y sudo les ayuda de forma nativa a realizar un trabajo con derechos elevados en la misma consola.
  • Históricamente, los usuarios de Windows abren una nueva ventana con una consola de derechos elevados si es necesario. Esto funciona bien durante muchos años porque es conveniente en un entorno de múltiples ventanas. (Los usuarios de Windows también podrían beneficiarse de pssudo teniendo en cuenta Windows Core y Nano)

Entonces las expectativas son:

  • pssudo funciona solo en sesiones interactivas
  • pssudo no abre una nueva consola (la ventana UAC es aceptable en Windows, no queremos romper la seguridad y el espíritu de Windows)
  • credenciales de caché pssudo oportunas
  • pssudo no almacena en caché un estado de sesión por seguridad
  • la misma UX (como sea posible) está en todas las plataformas
  • pssudo ejecuta comandos nativos
  • pssudo ejecuta bloques / archivos de secuencias de comandos de PowerShell

Detalles de implementacion:

  • La comunicación remota de PowerShell es la solución más potente y funcional. Ya está implementado y funciona. Otros también tendrían que emular esta funcionalidad para ejecutar bloques de script de PowerShell en por usuario / por sesión / por espacio de ejecución / por estado de alcance.
  • El transporte preferido es WinRM porque toda la infraestructura de Windows se basa en él. Se requiere cierta inversión en WinRM, aunque MSFT no quiere esto porque está basado en SOAP.
  • El transporte SSH podría ser. Este todavía no es el estándar para Windows. Requiere una gran inversión para implementación y mantenimiento. Y existe un problema al admitir sistemas más antiguos.
  • Otros transportes como sockets Unix. Requiere grandes inversiones no solo en infraestructura sino también en PowerShell.

@ mklement0 Me pregunto si lo que hago aquí suele ser genial :-) Me robas ser un oponente :-)

¿Por qué no escribir un binario de Windows que requiera privilegios que inicie una instancia de PowerShell con los comandos que se le pasen? Tendría que ser una aplicación en modo consola para funcionar correctamente. Luego, para Linux, escribimos un script que requiere permisos que inicia una instancia de PowerShell con los comandos proporcionados. Si esto funciona en la práctica como lo hace en teoría, powershell se ejecutará con permisos elevados, ejecutará los comandos y se cerrará.

¿Por qué no escribir un binario de Windows que requiera privilegios que inicie una instancia de PowerShell con los comandos que se le pasen? Tendría que ser una aplicación en modo consola para funcionar correctamente.

Porque la API de Windows lo impide y la aplicación de consola se abriría en una nueva ventana. Ya hablamos de posibles soluciones.

Una cosa a tener en cuenta es que no importa cómo se implemente, siempre hay un salto de proceso hacia y desde un proceso elevado. Esto significa que siempre tendrá objetos deserializados en la canalización y se aplicarán esas limitaciones. En muchos casos, esto no será un problema, pero si un cmdlet espera un objeto .NET activo, no funcionará.

Para admitir JEA con SSH, eventualmente necesitaríamos un demonio / servicio generalizado que reemplace la necesidad de WinRM como ese servicio de todos modos. En ese momento, evaluaríamos usar eso para elevar una parte de la tubería.

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

GitHub
Un Sudo para Windows: ejecute elevado sin abarcar una nueva ventana del host de la consola - gerardog / gsudo

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

GitHub gerardog / gsudo A Sudo para Windows: ejecutar elevado sin abarcar una nueva ventana del host de la consola - gerardog / gsudo

Aun mejor
http://blog.lukesampson.com/sudo-for-windows

GitHub
Un Sudo para Windows: ejecute elevado sin abarcar una nueva ventana del host de la consola - gerardog / gsudo
Sudo para Windows

Aun mejor

No.

Gsudo no solicita la contraseña cada vez y es notablemente más rápido de instalar y usar.

Me parece que este tema debería ser aceptado (lo que significa que se le debería dedicar más tiempo y organización) a juzgar no solo por el interés de este boleto. No es correcto no reconocerlo oficialmente como una tarea de trabajo, ya que las dificultades técnicas que se perciben actualmente no se van a resolver sin una participación activa.

Estoy usando gsudo desde hace unos meses y no puedo imaginar volver a Windows UAC tradicional todo el tiempo, horror.

@majkinetor este problema se https://github.com/PowerShell/PowerShell/issues/11343 para una mayor discusión sobre el diseño

¿Fue útil esta página
0 / 5 - 0 calificaciones