├── LICENSE ├── README.md ├── demo.png ├── portforge.cr └── result.png /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Portforge 2 | This script is intended to open as many sockets as you wish (between 1024 - 65535).
3 | Lower than 1024 works too but you have to be a root user for that.
4 | 5 | This can be useful when you don't want people to map out your device
6 | to see what you're running and what not, so it's a small step to defeat reconnaissance.
7 | 8 | ### Technology from the core 9 | Portforge.cr uses a technique built-in the Crystal compiler called Fibers.
10 | They are very much like system threads but Fibers is a lot more lightweight
11 | & the execution is managed through the process [1](https://crystal-lang.org/docs/guides/concurrency.html).
12 | 13 | The larger range you pick, the longer it takes for the script to
14 | load up every socket but I've tried my best to optimize the script
15 | so it should just take a couple of minutes (depending on the system of course).
16 | 17 | ### Under the hood 18 | The script works in 2 steps.
19 | It first performs its own scan on the system to see which port is already open.
20 | The open ports is then put on one list and the closed ports is put on another list.
21 | The next step is opening the closed ports, so the script picks the list with all the closed
22 | ports and opens a socket on every one of them.
23 | 24 | While the main fiber is opening a socket on every port,
25 | another fiber is called under the main one which listens for incoming connections and closes it directly.
26 | This process is repeated indefinitely, or until you interrupt the script.
27 | 28 | ### Getting started (you only need to do this once) 29 | ``` 30 | crystal build portforge.cr 31 | ``` 32 | 33 | ### Requirement 34 | - [The compiler](https://crystal-lang.org/reference/installation/) 35 | 36 | 37 | ### Usage 38 | ``` 39 | ./portforge IP startport endport 40 | ``` 41 | 42 | ### Demo 43 | The first picture is portforge.cr running and the second one is the result from an Nmap scan.
44 | As you can see, Nmap thinks I'm running all these services when in reality, it is just portforge.cr running.
45 | 46 | 47 | -------------------------------------------------------------------------------- /demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Beyarz/Portforge/3fedbf52317e263bae0214da6e4cc9f41b438c99/demo.png -------------------------------------------------------------------------------- /portforge.cr: -------------------------------------------------------------------------------- 1 | # # # # # # 2 | # Created July 23th 2018 3 | # Copyright (c) 2017 Beyar. 4 | # # # # 5 | 6 | # # # 7 | # Name: portforge.cr 8 | # # 9 | 10 | # Library 11 | require "socket" 12 | 13 | # Shows the limit 14 | def limits 15 | puts "[-] The port can't be lower than 1," 16 | puts "[-] nor can it be higher than 65535." 17 | end 18 | 19 | # Shows the usage of this script 20 | def usage 21 | puts "[-] Argument: #{PROGRAM_NAME} host start end" 22 | puts "[-] Example: #{PROGRAM_NAME} localhost 4440 4445" 23 | end 24 | 25 | # Progress update 26 | def progress(update) 27 | update = update.to_f 28 | case update 29 | when update < 25.00 && update > 0.00 30 | puts "[!] 0% started." 31 | when update < 50.00 && update > 25.00 32 | puts "[!] 25% done." 33 | when update < 75.00 && update > 50.00 34 | puts "[!] 50% half of the job completed." 35 | when update < 100.00 && update > 75.00 36 | puts "[!] 75% majority of the work has been done." 37 | when update < 100.00 && update > 90.00 38 | puts "[!] 100% finished task!" 39 | end 40 | end 41 | 42 | # ARGV to VAR 43 | begin 44 | host = ARGV[0] 45 | portStart = ARGV[1].to_i 46 | portEnd = ARGV[2].to_i 47 | rescue IndexError 48 | usage() 49 | exit(1) 50 | end 51 | 52 | # Class used to check 53 | # if run as root 54 | lib LibC 55 | fun getuid : UInt16 56 | end 57 | 58 | # Validating input 59 | approved = 0 60 | if ARGV.size != 3 61 | usage() 62 | else 63 | if portStart > 65535 64 | limits() 65 | elsif portStart < 1 66 | limits() 67 | elsif portEnd > 65535 68 | limits() 69 | elsif portEnd < 1 70 | limits() 71 | elsif portStart > portEnd 72 | usage() 73 | elsif portStart < 1024 74 | if LibC.getuid != 0 75 | puts "[-] Port lower than 1024 detected." 76 | puts "[-] You have to run as root." 77 | exit(1) 78 | end 79 | else 80 | approve = 1 81 | end 82 | end 83 | 84 | openPorts = Array(Int32).new 85 | closedPorts = [] of Int32 86 | portTest = (portStart..portEnd) 87 | notAgain = 0 88 | time = Time.now.second 89 | allowedUpdate = 1 90 | 91 | puts "[!] Scan started." 92 | 93 | # Picks every single port from the array 94 | # and performs the check 95 | portTest.each do |current_port| 96 | 97 | # Checks which port is open by 98 | # trying to open a socket on a port 99 | # and decides wether a error is thrown or not 100 | begin 101 | client = TCPSocket.new(host, current_port, dns_timeout = 5) 102 | openPorts << current_port 103 | client.close 104 | rescue Errno 105 | closedPorts << current_port 106 | end 107 | 108 | # Shows how far the scanning 109 | # have progressed, updates every minute 110 | # but performs the calculations on a 111 | # separate fiber 112 | spawn do 113 | if time == Time.now.second 114 | if allowedUpdate == 1 115 | status = current_port.fdiv(portEnd)*100 116 | puts "[+] #{status.round(2)}% done." 117 | allowedUpdate = 0 118 | sleep 1.second 119 | allowedUpdate = 1 120 | end 121 | end 122 | end 123 | 124 | # Tells the sceduler to continue 125 | Fiber.yield 126 | 127 | end 128 | 129 | puts "[!] Scan finished." 130 | 131 | # Goes through each closed port 132 | puts "[+] Forging started." 133 | 134 | # Infinite loop until interrupted 135 | while(true) 136 | 137 | counter = 0 138 | closedPorts.each do |port| 139 | begin 140 | 141 | # Opens a socket on each port 142 | server = TCPServer.new(port) 143 | 144 | # Accepts incoming connections and closes it 145 | spawn do 146 | server.accept do |incoming| 147 | incoming.gets 148 | incoming << "Message received." 149 | incoming.close 150 | end 151 | end 152 | 153 | # Catching the binding error, assumes it is already open 154 | # Moves over from closed to open as it is open now 155 | rescue Errno 156 | openPorts << closedPorts[counter] 157 | closedPorts.delete_at(counter) 158 | 159 | end 160 | 161 | # Displays when all ports have been moved over to 162 | # the other array 163 | if closedPorts.size < 1 164 | puts "[+] The ports should be open now." 165 | puts "[!] To end this proccess you have to interrupt it." 166 | end 167 | 168 | # Used to count the array index 169 | counter += 1 170 | 171 | end 172 | end 173 | -------------------------------------------------------------------------------- /result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Beyarz/Portforge/3fedbf52317e263bae0214da6e4cc9f41b438c99/result.png --------------------------------------------------------------------------------