1.0.10 • Published 4 years ago

nodesh-test v1.0.10

Weekly downloads
-
License
GPL-3.0
Repository
github
Last release
4 years ago

NodeSH-Client

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

Table of Contents

Installation

To install this package, simply run :

npm install nodesh-server

To run the client, run npm start

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 machines in order to connect.

Client usage guide

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

Available usages are:

  • cmd : Send Command To Server

    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

  • cmdIn : Write To stdin On Server

    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

  • upload : Upload To Server

    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
  • download : Download From Server

    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

  • tray : Open Tray On Server Machine :)

    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)

API

If you prefer to write a client yourself, here is the API :

Key Exchange

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

Send Requests To Server

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 :

  • Authentication Fields

    • 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
  • cmd , cmdIn , tray

    • 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
  • download , upload

    • 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 Response

Server's respond will differ based on usage type :

  • cmd , cmdIn , tray , screen , upload

    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

  • download

    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

Contribution

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

1.0.10

4 years ago

1.0.7

4 years ago

1.0.5

4 years ago

1.0.4

4 years ago

1.0.3

4 years ago

1.0.1

4 years ago

1.0.0

4 years ago