/PowerRemoteDesktop

Remote Desktop entirely coded in PowerShell.

Primary LanguagePowerShellApache License 2.0Apache-2.0

PowerRemoteDesktop

Power Remote Desktop is a fully functional Remote Desktop Application entirely coded in PowerShell.

It doesn't rely on any existing Remote Desktop Application or Protocol to function. A serious advantage of this application is its nature (PowerShell) and its ease of use and installation.

This project demonstrate why PowerShell contains the word Power. It is unfortunately often an underestimated programming language that is not only resumed to running commands or being a more fancy replacement to the old Windows Terminal (cmd).

Tested on:

  • Windows 10 - PowerShell Version: 5.1.19041.1320
  • Windows 11 - PowerShell Version: 5.1.22000.282

Features

  • Captures Remote Desktop Image with support of HDPI.
  • Supports Mouse Click (Left, Right, Middle), Mouse Moves and Mouse Wheel.
  • Supports Keystrokes Simulation (Sending remote key strokes) and few useful shortcuts.
  • Traffic is encrypted by default using TLSv1.2 and optionnally using TLSv1.3 (TLS 1.3 might not be possible on older systems).
  • Challenge-Based Password Authentication to protect access to server.
  • Support custom SSL/TLS Certificate (File or Encoded in base64). If not specified, a default one is generated and installed on local machine (requires Administrator privileges)

What is still beta

I consider this version as stable but I want to do more tests and have more feedback.

I also want to implement few additional features before releasing the version 1.

Installation

You will find multiple ways to use this PowerShell Applications. Recommended method would be to install both Server and Viewer using the PowerShell Gallery but you can also do it manually as an installed module or imported script.

Install as a PowerShell Module from PowerShell Gallery (Recommended)

You can install Power Remote Desktop from PowerShell Gallery. See PowerShell Gallery as the 'equivalent' of Aptitude for Debian or Brew for MacOS.

Run the following commands:

Install-Module -Name PowerRemoteDesktop_Server -AllowPrerelease

Install-Module -Name PowerRemoteDesktop_Viewer -AllowPrerelease

AllowPrerelease is mandatory when current version is marked as a Prerelease

Your command prompt will show the following warning:

Untrusted repository
You are installing the modules from an untrusted repository. If you trust this repository, change its
InstallationPolicy value by running the Set-PSRepository cmdlet. Are you sure you want to install the modules from
'PSGallery'?

Answer Y to proceed installation.

Both modules should now be available, you can verify using the command:

Get-Module -ListAvailable

Example Output:

PS C:\Users\Phrozen\Desktop> Get-Module -ListAvailable


    Directory: C:\Users\Phrozen\Documents\WindowsPowerShell\Modules


ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Manifest   1.0.0      PowerRemoteDesktop_Server           Invoke-RemoteDesktopServer
Manifest   1.0.0      PowerRemoteDesktop_Viewer           Invoke-RemoteDesktopViewer

<..snip..>

If you don't see them, run the following commands and check back.

Import-Module PowerRemoteDesktop_Server

Import-Module PowerRemoteDesktop_Viewer

Install as a PowerShell Module (Manually / Unmanaged)

To be available, the module must first be present in a registered module path.

You can list module paths with following command:

Write-Output $env:PSModulePath

Example Output:

C:\Users\Phrozen\Documents\WindowsPowerShell\Modules;C:\Program Files\WindowsPowerShell\Modules;C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules

Clone PowerRemoteDesktop repository or download a Github release package.

git clone https://github.com/DarkCoderSc/PowerRemoteDesktop.git

Copy both PowerRemoteDesktop_Viewer and PowerRemoteDesktop_Server folders to desired module path (Ex: C:\Users\<USER>\Documents\WindowsPowerShell\Modules)

Both modules should now be available, you can verify using the command:

Get-Module -ListAvailable

Example Output:

PS C:\Users\Phrozen\Desktop> Get-Module -ListAvailable


    Directory: C:\Users\Phrozen\Documents\WindowsPowerShell\Modules


ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Manifest   1.0.0      PowerRemoteDesktop_Server           Invoke-RemoteDesktopServer
Manifest   1.0.0      PowerRemoteDesktop_Viewer           Invoke-RemoteDesktopViewer

<..snip..>

If you don't see them, run the following commands and check back.

Import-Module PowerRemoteDesktop_Server

Import-Module PowerRemoteDesktop_Viewer

Notice: Manifest files are optional (*.psd1) and can be removed.

As a PowerShell Script

It is not mandatory to install this application as a PowerShell module (Even if file extension is *.psm1)

You can also load it as a PowerShell Script. Multiple methods exists including:

  • Invoking Commands Using: IEX (Get-Content .\PowerRemoteDesktop_Viewer.psm1 -Raw) and IEX (Get-Content .\PowerRemoteDesktop_[Server/Viewer].psm1 -Raw)
  • Loading script from a remote location: IEX (New-Object Net.WebClient).DownloadString('http://127.0.0.1/PowerRemoteDesktop_[Server/Viewer].psm1)

etc...

Usage

Client

PowerRemoteDesktop_Viewer.psm1 module first need to be imported / installed on current PowerShell session.

Call Invoke-RemoteDesktopViewer

Supported options:

  • ServerAddress: Remote Server Address.
  • ServerPort: Remote Server Port.
  • DisableInputControl: If set to $true, this option disable control events on form (Mouse Clicks, Moves and Keyboard). This option is generally to true during development when connecting to local machine to avoid funny things.
  • Password: Password used during server authentication.
  • DisableVerbosity: Disable verbosity (not recommended)
  • TLSv1_3: Define whether or not client must use SSL/TLS v1.3 to communicate with remote server.

Example

Invoke-RemoteDesktopViewer -ServerAddress "127.0.0.1" -ServerPort 2801 -Password "Jade"

Server

PowerRemoteDesktop_Server.psm1 module first need to be imported / installed on current PowerShell session.

Call Invoke-RemoteDesktopServer

Supported options:

  • ListenAddress: Define in which interface to listen for new viewer.
  • ListenPort: Define in which port to listen for new viewer.
  • Password: Define password used during authentication process.
  • CertificateFile: A valid X509 Certificate (With Private Key) File. If set, this parameter is prioritize.
  • EncodedCertificate: A valid X509 Certificate (With Private Key) encoded as a Base64 String.
  • TransportMode: (Raw or Base64) Tell server how to send desktop image to remote viewer. Best method is Raw Bytes but I decided to keep the Base64 transport method as an alternative.
  • TLSv1_3: Define whether or not TLS v1.3 must be used for communication with Viewer.
  • DisableVerbosity: Disable verbosity (not recommended)
  • ImageQuality: JPEG Compression level from 0 to 100. 0 = Lowest quality, 100 = Highest quality.

If no certificate option is set, then a default X509 Certificate is generated and installed on local machine (Requires Administrative Privilege)

Example

Invoke-RemoteDesktopServer -ListenAddress "0.0.0.0" -ListenPort 2801 -Password "Jade"

Invoke-RemoteDesktopServer -ListenAddress "0.0.0.0" -ListenPort 2801 -Password "Jade" -CertificateFile "c:\certs\phrozen.p12"

Generate and pass your own X509 Certificate

Passing your own X509 Certificate is very useful if you want to avoid running your PowerShell Instance as Administrator.

You can easily create your own X509 Certificate using OpenSSL Command Line Tool.

Generate your Certificate

openssl req -x509 -sha512 -nodes -days 365 -newkey rsa:4096 -keyout phrozen.key -out phrozen.crt

Then export the new certificate with Private Key Included.

openssl pkcs12 -export -out phrozen.p12 -inkey phrozen.key -in phrozen.crt

Use it as file

Pass the certificate file to parameter CertificateFile.

Use it as Encoded Base64 String

First encode your certificate file as base64 string.

base64 -i phrozen.p12

Then pass the encoded string to parameter EncodedCertificate.

List trusted servers

It is now possible to persistantly trust server using a local storage (Windows User Registry Hive)

Get-TrustedServers

Example output:

PS C:\Users\Phrozen\Desktop\Projects\PowerRemoteDesktop> Get-TrustedServers

Detail                           Fingerprint
------                           -----------
@{FirstSeen=14/01/2022 11:06:16} EA88AADA402864D1864542F7F2A3C49E56F473B0

Delete trusted server (Permanently)

Remove-TrustedServer

Delete all trusted servers (Permanently)

Clear-TrustedServers

Changelog

11 January 2022 (1.0.1 Beta 2)

  • Desktop images are now transported in raw bytes instead of base64 string thus slightly improving performances. Base64 Transport Method is still available through an option but disabled by default.
  • Protocol has drastically changed. It is smoother to read and less prone to errors.
  • TLS v1.3 option added (Might not be supported by some systems).
  • Several code optimization, refactoring and fixes.
  • Password complexity check implemented to avoid lazy passwords.
  • Possibility to disable verbose.
  • Server & Viewer version synchronization. Same version must be used between the two.

12 January 2022 (1.0.2 Beta 3)

  • HDPI is completely supported.

12 January 2022 (1.0.3 Beta 4)

  • Possibility to change desktop image quality.
  • Possibility to choose which screen to capture if multiple screens (Monitors) are present on remote machine.

Multi Screen Selection

Multi Screen Example

14 January 2022 (1.0.4 Beta 5)

  • Password is stored as SecureString on Viewer. I don't see the point of implementing SecureString sever-side, if you do see the point, please change my mind.
  • Server Fingerprint Validation.
  • Possibility to trust a server for current PowerShell Instance or persistantly using a local storage.
  • Possibility to manage trusted servers (List, Remove, Remove All)

Fingerprint Validation

Server Fingerprint Validation

List of ideas and TODO

  • 🟢 Support Password Protected external Certificates.
  • 🟢 Mutual Authentication for SSL/TLS (Client Certificate).
  • 🟢 Synchronize Cursor State.
  • 🟢 Synchronize Clipboard.
  • 🟠 Keep-Alive system to implement Read / Write Timeout.
  • 🟠 Listen for local/remote screen resolution update event.
  • 🔴 Motion Update for Desktop Streaming (Only send and update changing parts of desktop).

🟢 = Easy 🟠 = Medium 🔴 = Hard

Disclaimer

We are doing our best to prepare the content of this app. However, PHROZEN SASU and / or Jean-Pierre LESUEUR cannot warranty the expressions and suggestions of the contents, as well as its accuracy. In addition, to the extent permitted by the law, PHROZEN SASU and / or Jean-Pierre LESUEUR shall not be responsible for any losses and/or damages due to the usage of the information on our app.

By using our app, you hereby consent to our disclaimer and agree to its terms.

Any links contained in our app may lead to external sites are provided for convenience only. Any information or statements that appeared in these sites or app are not sponsored, endorsed, or otherwise approved by PHROZEN SASU and / or Jean-Pierre LESUEUR. For these external sites, PHROZEN SASU and / or Jean-Pierre LESUEUR cannot be held liable for the availability of, or the content located on or through it. Plus, any losses or damages occurred from using these contents or the internet generally.