A Node.js CLI to communicate with NodeSH-Server which provides :
- Secure Shell Access
- Encrypted Download
- Encrypted Upload
using Nodejs + Diffie-Hellman key exchange + AES encryption
wroks on Windows, macOS, Linux
Download code source and run npm install
in project directory to install dependencies
After installation, run npm start
to client CLI
Do not forget to set the host IP address or domain name in configuration file ('./config/index.js'), Consider that username and password in this file, should be the same on server and client machine in order to connect.
You might prefer using the sample CLI client instead of writing one yourself.
To use client, first run npm run client
or node client
command in project directory and wait for secure connection to establish...
Once connection estableshed, you can set usage type first.
To set usage type, type change
, press Enter and enter the type you wish to use
-
This usage will send your terminal commands to server, start a child process, execute the command and send stdout data (or errrors) back to client. Consider this child process will stay open untill you send next command using this usage type.
Remember you should first set type to "cmd" (if it's not current type) for this usage. After that, you can type commands just like you type in terminal and send them to server to be executed, by pressing Enter
You can also add " ==> FILE_PATH" to save output to a file. Example :
ping 8.8.8.8 ==> ./out.txt
-
This will write to stdin of the last child process started on server, usefull for interactive commands
Set type to "cmdIn" to do this.
Example:
Imagine we've started a child process on server by entering "nslookup" in "cmd" usage type, now we can change type to "cmdIn" and enter :
set type=A
and then enter:
google.com
-
Will obviously upload files to server
First set type to "upload" and then enter origin path on client and destination path on server where the file will be saved with the following syntax :
'PATH_TO_ORIGIN''PATH_TO_DESTINATION'
This will encrypt file and write it to a temporary file, then start sending it to server, then server will receive it and write on a temporary file, and finally decrypt it to destination file
Consider if you enter relative path, the path will be relative to the execution path of client or server. Also if the origin path does not exist, the program will search for a file with the filename entered as origin and in the default upload path, setted in configuration file
While this method will encrypt and send files of any size, there is an option to send files without encryption. To do this, use a 'no' at the end of command like so:
'PATH_TO_ORIGIN''PATH_TO_DESTINATION'no
-
Will obviously download files from server
First set type to "download" and then enter destination path on client to save file and origin path on server with the following syntax :
'PATH_TO_DESTINATION''PATH_TO_ORIGIN'
This will encrypt file and write it to a temporary file on server, then start sending it to client, then client will receive it and write on a temporary file, and finally decrypt it to destination file
Consider if you enter relative path, the path will be relative to the execution path of client or server. Also if the destination path does not exist, downloaded file will be saved in default download path, setted in configuration file, with the same file name entered as destination
While this method will encrypt and download files of any size, there is an option to download files without encryption. To do this, use a 'no' at the end of command like so:
'PATH_TO_DESTINATION''PATH_TO_ORIGIN'no
-
This is not actually a independent type since it can be done with existing types but it's added because it's kind of fun
Just change type to 'tray' and enter
open
to open tray on server (which typically does not exist on servers but since I first used this projcet on my home PC and did not have plan to put this on Github, having fun was the most important aim so this was one of the first things I implemented !)
There is also a screenshot server implemented, to use it, after secure connection established and client program is running, open your browser and type localhost
(port is 80 by default but can be changed in configuration file), this will send a request to screen port of server and get an screenshot of server (Will be transfered Encrypted)
If you prefer to write a client yourself, here is the API :
Since client is the connection starter, first you should calculate Generator, Prime and Client Public Key and post them to Key Exchange Port of server setted in configuration file, field names should be as follows :
P = PRIME
G = GENERATOR
public = CLIENT_PUBLIC
Server will calculate its own public key and send back a JSON object containing Generator (you sent), Prime (you sent) and Server Public Key as response
{
public: SERVER_PUBLIC,
P: PRIME,
G: Generator
}
Finally you grab the Server Public Key, calculate Secret Key and keep it somewhere, now secure connection is established
Consider the Prime BitLength and Encryption Algorithm setted in configuration file should be the same on both sides
To send requests to server, you should send a POST Request with values Encrypted using the secret key you exchanged in 'Key Exchange' API
First three fields are authentication fields. You should send user and pass fields together or sessionCode field. The rest are based on the Usage Type :
-
- user : The username. Will be compared with username setted in configuration file on server. consider this is not necessary if a session code exists
- pass : The password. Will be compared with password setted in configuration file on server. consider this is not necessary if a session code exists
- sessionCode : The session code. Will be compared with the session code stored in a variable server side. Session code will be returned in response after every time you send a request to server. So you should use user and pass fields at first requests and grab the session code from response. Once you caught session code, you can send it instead of user and pass
-
- type : Command type. Should be one of valid Command Usage Types mentioned in Client Guide (cmd, cmdIn and tray)
- command : The command to be executed on server
-
- path : A file path on server to be downloaded
- dest : A file path on server to save uploaded file
- enc : Determines if file should be encrypted during transfer
- file : Supplies a readable stream to send file to server. Consider you should use multipart/form-data to send stream and necessary fields beside
Consider, To request server to take an screenshot and send it back Encrypted, only Authentication Fields are necessary
Also Remember that any request should be sendt to its own port setted in configuration file
Server's respond will differ based on usage type :
-
Response will be a JSON object in the following format :
{ sessionCode: SESSION_CODE, auth: TRUE|FALSE, message: RESPONSE_MESSAGE }
sessionCode is the session code to use in further requests for authentication
auth says whether authentication succeeded (true) or failed (false)
message is the main response from server, it contains response data
Consider you might get several JSON objects during a connection until it ends. So you might want to add chunks to a string until it become a valid JSON, then do whatever you want with JSON object (after decryption), empty the string and do these again until connection ends
-
Response will be a JSON object first, formatted in the exact same way as above. Then if the message in response JSON is the string __'stream'__then next chunks will be the file from server, otherwise, something has went wrong and message describes the problem, no further chunks will arrive and connection will end
This project was born in my very first days in node.js and at first, was actually something fun to do after I studied more and earned a better understanding of computer networks and network security. Recently I beautified it, changed some algorithms, added some new features and finally uploaded on Github. it might still have some bugs or issues to be solved so feel free to open issues if detected
Besides, there are many other cool features to add to this project