├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── modules ├── __init__.py ├── gameserver.py ├── http.py ├── manual.py ├── mongodb.py ├── mysql.py ├── printer.py ├── ssh.py └── template.py ├── portSpider.py └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | __pycache__/ 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "3.3" 4 | - "3.4" 5 | - "3.5" 6 | - "3.6" 7 | install: "pip install -r requirements.txt" 8 | script: ./portSpider.py --test 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 David Schütz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ██████╗ ██████╗ ██████╗ ████████╗███████╗██████╗ ██╗██████╗ ███████╗██████╗ 3 | ██╔══██╗██╔═══██╗██╔══██╗╚══██╔══╝██╔════╝██╔══██╗██║██╔══██╗██╔════╝██╔══██╗ 4 | ██████╔╝██║ ██║██████╔╝ ██║ ███████╗██████╔╝██║██║ ██║█████╗ ██████╔╝ 5 | ██╔═══╝ ██║ ██║██╔══██╗ ██║ ╚════██║██╔═══╝ ██║██║ ██║██╔══╝ ██╔══██╗ 6 | ██║ ╚██████╔╝██║ ██║ ██║ ███████║██║ ██║██████╔╝███████╗██║ ██║ 7 | ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝╚═════╝ ╚══════╝╚═╝ ╚═╝ 8 | v1.0 by David Schütz (@xdavidhu) 9 | [![Build Status](https://travis-ci.org/xdavidhu/portSpider.svg?branch=master)](https://travis-ci.org/xdavidhu/portSpider) 10 | [![Compatibility](https://img.shields.io/badge/python-3.3%2C%203.4%2C%203.5%2C%203.6-brightgreen.svg)](https://github.com/xdavidhu/portSpider) 11 | [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/xdavidhu/portSpider/blob/master/LICENSE) 12 | [![Stars](https://img.shields.io/github/stars/xdavidhu/portSpider.svg)](https://github.com/xdavidhu/portSpider) 13 | 14 | ### ⚠️ Warning! This project is no longer maintained and may not work as excepted. 15 | 16 |

A lightning fast multithreaded network scanner framework with modules.

17 |

portSpider is a tool for scanning huge network ranges to find open ports and vulnerable services. This tool is not intended to scan one target, rather a whole IP range. (eg. 192.168.0.0/24) Most of the time companies/organizations have public information about their owned public IP ranges, so portSpider will help you to scan all of their machines at once for vulnerable devices/services.

18 | 19 | # modules: 20 | * **http** - Scan for open HTTP ports, and get the titles.
21 | * **mysql** - Scan for open MySQL servers, and try to log in with the default credentials.
22 | * **mongodb** - Scan for open MongoDB instances, and check if they are password protected.
23 | * **ssh** - Scan for open SSH ports.
24 | * **printer** - Scan for open printer ports and websites.
25 | * **gameserver** - Scan for open game server ports.
26 | * **manual** - Scan custom ports.
27 | 28 | # commands: 29 | * **modules** - List all modules.
30 | * **use** - Use a module.
31 | * **options** - Show a module's options.
32 | * **set** - Set an option.
33 | * **run** - Run the selected module.
34 | * **back** - Go back to menu.
35 | * **exit** - Shut down portSpider.
36 | 37 | # installing: 38 | 39 |

Debian based systems:

40 | 41 | ``` 42 | $ sudo apt-get update && sudo apt-get install python3 python3-pip -y 43 | 44 | $ git clone https://github.com/xdavidhu/portSpider 45 | 46 | $ cd portSpider/ 47 | 48 | $ python3 -m pip install -r requirements.txt 49 | ``` 50 | 51 |

macOS / OSX:

52 | 53 | ``` 54 | $ brew install python3 55 | 56 | $ git clone https://github.com/xdavidhu/portSpider 57 | 58 | $ cd portSpider/ 59 | 60 | $ python3 -m pip install -r requirements.txt 61 | ``` 62 | **NOTE**: You need to have [Homebrew](http://brew.sh/) installed before running the macOS/OSX installation.
63 | **WARNING**: portSpider is only compatible with Python 3.3 & 3.4 & 3.5 & 3.6 64 | 65 | # usage: 66 | 67 |

Start portSpider with Python3:

68 | 69 | ``` 70 | python3 portSpider.py 71 | ``` 72 | 73 |

Select a module: (eg. 'mysql')

74 | 75 | ``` 76 | portSpider $> use mysql 77 | ``` 78 | 79 |

View the module's options:

80 | 81 | ``` 82 | portSpider/mysql $> options 83 | ``` 84 | 85 |

Set all '[NOT SET]' options: (eg. option 'network' to '192.168.0.0/24')

86 | 87 | ``` 88 | portSpider/mysql $> set network 192.168.0.0/24 89 | ``` 90 | 91 |

(You can also modify already set options, but that is not required.)

92 | 93 |

If you have every option set, run the scan:

94 | 95 | ``` 96 | portSpider/mysql $> run 97 | ``` 98 | 99 |

You will see the results on the screen as well as in a text file in the 'logs/' folder.

100 | 101 | 102 | # developers: 103 | * David Schütz ([@xdavidhu](https://twitter.com/xdavidhu)) 104 | * László Simonffy ([@Letsgo00HUN](https://twitter.com/Letsgo00HUN)) - Multithreading 105 | 106 | # contribution: 107 |

If you have any ideas about new modules and improvements in portSpider, feel free to contribute.

108 | 109 | * Check out the `template` module to get a better understanding of the framework.
110 | * Make sure to include a description about your module in the pull request.
111 | * If you create a module, you will be mentioned here in the readme with a link to your social media. 112 | 113 | # disclaimer: 114 | I'm not responsible for anything you do with this program, so please only use it for good and educational purposes. 115 | 116 | # legal: 117 | Copyright (c) 2017 by David Schütz. Some rights reserved. 118 | 119 | portSpider is under the terms of the [MIT License](https://www.tldrlegal.com/l/mit), following all clarifications stated in the [license file](https://github.com/xdavidhu/portSpider/blob/master/LICENSE). You can also go ahead and email me at xdavid{at}protonmail{dot}com. 120 | -------------------------------------------------------------------------------- /modules/__init__.py: -------------------------------------------------------------------------------- 1 | from os.path import dirname, basename, isfile 2 | import glob 3 | modules = glob.glob(dirname(__file__)+"/*.py") 4 | __all__ = [ basename(f)[:-3] for f in modules if isfile(f)] -------------------------------------------------------------------------------- /modules/gameserver.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import datetime 3 | import sys 4 | import ipaddress 5 | import threading 6 | import os 7 | 8 | BLUE, RED, WHITE, YELLOW, MAGENTA, GREEN, END = '\33[1;94m', '\033[1;91m', '\33[1;97m', '\33[1;93m', '\033[1;35m', '\033[1;32m', '\033[0m' 9 | 10 | class ThreadManager(object): 11 | i = 0 12 | 13 | def __init__(self, ipList): 14 | self.allIps = ipList 15 | self.size = len(ipList) 16 | 17 | def getNextIp(self): 18 | if not (self.i >= self.size - 1): 19 | ip = self.allIps[self.i] 20 | self.i += 1 21 | return ip 22 | return 0 23 | 24 | def getID(self): 25 | return self.i + 1 26 | 27 | def coreOptions(): 28 | options = [["network", "IP range to scan", ""], ["port-timeout", "Timeout (in sec) for port 80.", "0.3"], 29 | ["threads", "Number of threads to run.", "100"], ["verbose", "Show verbose output.", "true"]] 30 | return options 31 | 32 | 33 | def createIPList(network): 34 | net4 = ipaddress.ip_network(network) 35 | ipList = [] 36 | for x in net4.hosts(): 37 | ipList.append(x) 38 | return ipList 39 | 40 | def print1(data): 41 | if verbose: 42 | print("\033[K" + data) 43 | 44 | def checkServer(address, port): 45 | s = socket.socket() 46 | s.settimeout(float(portTimeout)) 47 | try: 48 | s.connect((address, port)) 49 | s.close() 50 | return True 51 | except socket.error: 52 | s.close() 53 | return False 54 | except: 55 | s.close() 56 | return "FAIL" 57 | 58 | def writeToFile(line): 59 | file = open(fileName, "a") 60 | file.write(line) 61 | file.close() 62 | 63 | 64 | def restart_line(): 65 | sys.stdout.write('\r') 66 | sys.stdout.flush() 67 | 68 | 69 | def statusWidget(): 70 | sys.stdout.write(GREEN + "[" + status + "] " + YELLOW + str(threadManager.getID()) + GREEN + " / " + YELLOW + str( 71 | allIPs) + GREEN + " hosts done." + END) 72 | restart_line() 73 | sys.stdout.flush() 74 | 75 | 76 | def scan(i): 77 | global status 78 | global openPorts 79 | global done 80 | while True: 81 | if stop: 82 | sys.exit() 83 | ip = threadManager.getNextIp() 84 | if ip == 0: 85 | break 86 | status = (threadManager.getID() / allIPs) * 100 87 | status = format(round(status, 2)) 88 | status = str(status) + "%" 89 | stringIP = str(ip) 90 | 91 | for port in ports: 92 | port = port[0] 93 | if stop: 94 | sys.exit() 95 | 96 | isUp = checkServer(stringIP, port) 97 | if isUp != "FAIL": 98 | if isUp: 99 | possibleGame = "" 100 | for tempPort in ports: 101 | if tempPort[0] == port: 102 | possibleGame = tempPort[1] 103 | 104 | openPorts = openPorts + 1 105 | print1(GREEN + "[+] Port " + str(port) + " is open on '" + stringIP + "' - " + possibleGame + END) 106 | logLine = stringIP + " - " + str(port) + " OPEN - " + possibleGame + "\n" 107 | logLines.append(logLine) 108 | elif not isUp: 109 | print1(RED + "[-] Port " + str(port) + " is closed on '" + stringIP + "'" + END) 110 | else: 111 | print1(RED + "[!] Failed connecting to '" + stringIP + "'" + END) 112 | done = done + 1 113 | 114 | 115 | def core(moduleOptions): 116 | print( 117 | "\n" + GREEN + "GameServer module by @xdavidhu. Scanning subnet '" + YELLOW + moduleOptions[0][2] + GREEN + "'...\n") 118 | 119 | global status 120 | global fileName 121 | global allIPs 122 | global portTimeout 123 | global ips 124 | global threadCount 125 | global done 126 | global verbose 127 | global stop 128 | global ports 129 | global openPorts 130 | global logLines 131 | global threadManager 132 | logLines = [] 133 | stop = False 134 | done = 0 135 | 136 | portTimeout = moduleOptions[1][2] 137 | network = moduleOptions[0][2] 138 | threadCount = int(moduleOptions[2][2]) 139 | verbose = moduleOptions[3][2] 140 | 141 | if verbose == "true": 142 | verbose = True 143 | else: 144 | verbose = False 145 | 146 | try: 147 | ipList = createIPList(network) 148 | allIPs = len(ipList) 149 | if allIPs == 0: 150 | raise Exception 151 | except: 152 | print(RED + "[!] Invalid subnet. Exiting...\n") 153 | return 154 | allIPs = len(ipList) 155 | 156 | threadManager = ThreadManager(ipList) 157 | 158 | i = datetime.datetime.now() 159 | i = str(i).replace(" ", "_") 160 | i = str(i).replace(":", "-") 161 | script_path = os.path.dirname(os.path.realpath(__file__)) 162 | script_path = script_path.replace("modules", "") 163 | if not os.path.exists(script_path + "logs"): 164 | os.makedirs(script_path + "logs") 165 | fileName = script_path + "logs/log-gameserver-portSpider-" + i + ".log" 166 | 167 | file = open(fileName, 'w') 168 | file.write("subnet: " + network + "\n") 169 | file.close() 170 | 171 | ports = [[25565, "MINECRAFT"], [27015, "STEAM-GAME"], [9987, "TEAMSPEAK"]] 172 | 173 | openPorts = 0 174 | threads = [] 175 | for i in range(threadCount): 176 | i -= 1 177 | t = threading.Thread(target=scan, args=(i,)) 178 | t.daemon = True 179 | threads.append(t) 180 | t.start() 181 | 182 | try: 183 | while True: 184 | if done == threadCount and threadManager.getID() == allIPs: 185 | break 186 | statusWidget() 187 | except KeyboardInterrupt: 188 | stop = True 189 | verbose = False 190 | print("\n" + RED + "[I] Stopping..." + END) 191 | stop = True 192 | verbose = False 193 | 194 | for logLine in logLines: 195 | try: 196 | writeToFile(logLine) 197 | except: 198 | writeToFile("WRITING-ERROR") 199 | 200 | print("\n\n" + GREEN + "[I] GameServer module done. Results saved to '" + YELLOW + fileName + GREEN + "'.\n") 201 | -------------------------------------------------------------------------------- /modules/http.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import requests 3 | from lxml.html import fromstring 4 | import datetime 5 | import sys 6 | import ipaddress 7 | import threading 8 | import os 9 | 10 | BLUE, RED, WHITE, YELLOW, MAGENTA, GREEN, END = '\33[1;94m', '\033[1;91m', '\33[1;97m', '\33[1;93m', '\033[1;35m', '\033[1;32m', '\033[0m' 11 | 12 | class ThreadManager(object): 13 | i = 0 14 | 15 | def __init__(self, ipList): 16 | self.allIps = ipList 17 | self.size = len(ipList) 18 | 19 | def getNextIp(self): 20 | if not (self.i >= self.size - 1): 21 | ip = self.allIps[self.i] 22 | self.i += 1 23 | return ip 24 | return 0 25 | 26 | def getID(self): 27 | return self.i + 1 28 | 29 | def coreOptions(): 30 | options = [["network", "IP range to scan", ""], ["port-timeout", "Timeout (in sec) for port 80.", "0.3"], 31 | ["title-timeout", "Timeout (in sec) for title resolve.", "3"], ["threads", "Number of threads to run.", "50"], 32 | ["verbose", "Show verbose output.", "true"]] 33 | return options 34 | 35 | 36 | def createIPList(network): 37 | net4 = ipaddress.ip_network(network) 38 | ipList = [] 39 | for x in net4.hosts(): 40 | ipList.append(x) 41 | return ipList 42 | 43 | def print1(data): 44 | if verbose: 45 | print("\033[K" + data) 46 | 47 | def checkServer(address, port): 48 | s = socket.socket() 49 | s.settimeout(float(portTimeout)) 50 | try: 51 | s.connect((address, port)) 52 | s.close() 53 | return True 54 | except socket.error: 55 | s.close() 56 | return False 57 | except: 58 | s.close() 59 | return "FAIL" 60 | 61 | 62 | def getHTTP(address, port): 63 | code = None 64 | title = None 65 | 66 | try: 67 | r = requests.get("http://" + address, timeout=float(titleTimeout), allow_redirects=True) 68 | except: 69 | return False 70 | 71 | try: 72 | code = r.status_code 73 | except: 74 | pass 75 | 76 | try: 77 | tree = fromstring(r.content) 78 | title = tree.findtext('.//title') 79 | except: 80 | pass 81 | 82 | return [title, code] 83 | 84 | 85 | def writeToFile(line): 86 | file = open(fileName, "a") 87 | file.write(line) 88 | file.close() 89 | 90 | 91 | def restart_line(): 92 | sys.stdout.write('\r') 93 | sys.stdout.flush() 94 | 95 | 96 | def statusWidget(): 97 | sys.stdout.write(GREEN + "[" + status + "] " + YELLOW + str(threadManager.getID()) + GREEN + " / " + YELLOW + str( 98 | allIPs) + GREEN + " hosts done." + END) 99 | restart_line() 100 | sys.stdout.flush() 101 | 102 | 103 | def scan(i): 104 | global status 105 | global openPorts 106 | global done 107 | while True: 108 | if stop: 109 | sys.exit() 110 | ip = threadManager.getNextIp() 111 | if ip == 0: 112 | break 113 | status = (threadManager.getID() / allIPs) * 100 114 | status = format(round(status, 2)) 115 | status = str(status) + "%" 116 | stringIP = str(ip) 117 | isUp = checkServer(stringIP, port) 118 | 119 | if isUp != "FAIL": 120 | if isUp: 121 | openPorts = openPorts + 1 122 | print1(GREEN + "[+] Port 80 is open on '" + stringIP + "'" + END) 123 | http = getHTTP(stringIP, 80) 124 | if not http: 125 | print1(YELLOW + "[!] Failed to get the HTTP response of '" + stringIP + "'" + END) 126 | title = "NO-TITLE" 127 | code = "NO-CODE" 128 | else: 129 | title = str(http[0]) 130 | code = str(http[1]) 131 | if code is not None: 132 | print1(GREEN + "[+] Response code of '" + stringIP + "': '" + code + "'" + END) 133 | else: 134 | print1(YELLOW + "[!] Failed to get the response code of '" + stringIP + "'" + YELLOW) 135 | code = "NO-CODE" 136 | if title is not None: 137 | title = title.replace("\n", "") 138 | try: 139 | print1(GREEN + "[+] Title of '" + stringIP + "': '" + title + "'" + END) 140 | except: 141 | print1(YELLOW + "[!] Failed to print title of '" + stringIP + "'" + END) 142 | title = "NO-TITLE" 143 | else: 144 | print1(YELLOW + "[!] Failed to get title of '" + stringIP + "'" + YELLOW) 145 | title = "NO-TITLE" 146 | logLine = stringIP + " - " + "80 OPEN" + " - " + code + " - " + title + "\n" 147 | logLines.append(logLine) 148 | elif not isUp: 149 | print1(RED + "[-] Port 80 is closed on '" + stringIP + "'" + END) 150 | else: 151 | print1(RED + "[!] Failed connecting to '" + stringIP + "'" + END) 152 | done = done + 1 153 | 154 | 155 | def core(moduleOptions): 156 | print( 157 | "\n" + GREEN + "HTTP module by @xdavidhu. Scanning subnet '" + YELLOW + moduleOptions[0][2] + GREEN + "'...\n") 158 | 159 | global status 160 | global fileName 161 | global allIPs 162 | global portTimeout 163 | global titleTimeout 164 | global ips 165 | global threadCount 166 | global done 167 | global verbose 168 | global stop 169 | global port 170 | global openPorts 171 | global logLines 172 | global threadManager 173 | logLines = [] 174 | stop = False 175 | done = 0 176 | 177 | portTimeout = moduleOptions[1][2] 178 | titleTimeout = moduleOptions[2][2] 179 | network = moduleOptions[0][2] 180 | threadCount = int(moduleOptions[3][2]) 181 | verbose = moduleOptions[4][2] 182 | 183 | if verbose == "true": 184 | verbose = True 185 | else: 186 | verbose = False 187 | 188 | try: 189 | ipList = createIPList(network) 190 | allIPs = len(ipList) 191 | if allIPs == 0: 192 | raise Exception 193 | except: 194 | print(RED + "[!] Invalid subnet. Exiting...\n") 195 | return 196 | 197 | threadManager = ThreadManager(ipList) 198 | 199 | i = datetime.datetime.now() 200 | i = str(i).replace(" ", "_") 201 | i = str(i).replace(":", "-") 202 | script_path = os.path.dirname(os.path.realpath(__file__)) 203 | script_path = script_path.replace("modules", "") 204 | if not os.path.exists(script_path + "logs"): 205 | os.makedirs(script_path + "logs") 206 | fileName = script_path + "logs/log-http-portSpider-" + i + ".log" 207 | 208 | file = open(fileName, 'w') 209 | file.write("subnet: " + network + "\n") 210 | file.close() 211 | 212 | port = 80 213 | openPorts = 0 214 | threads = [] 215 | for i in range(threadCount): 216 | i -= 1 217 | t = threading.Thread(target=scan, args=(i,)) 218 | t.daemon = True 219 | threads.append(t) 220 | t.start() 221 | 222 | try: 223 | while True: 224 | if done == threadCount and threadManager.getID() == allIPs: 225 | break 226 | statusWidget() 227 | except KeyboardInterrupt: 228 | stop = True 229 | verbose = False 230 | print("\n" + RED + "[I] Stopping..." + END) 231 | stop = True 232 | verbose = False 233 | 234 | for logLine in logLines: 235 | try: 236 | writeToFile(logLine) 237 | except: 238 | writeToFile("WRITING-ERROR") 239 | 240 | print("\n\n" + GREEN + "[I] HTTP module done. Results saved to '" + YELLOW + fileName + GREEN + "'.\n") 241 | -------------------------------------------------------------------------------- /modules/manual.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import datetime 3 | import sys 4 | import ipaddress 5 | import threading 6 | import os 7 | 8 | BLUE, RED, WHITE, YELLOW, MAGENTA, GREEN, END = '\33[1;94m', '\033[1;91m', '\33[1;97m', '\33[1;93m', '\033[1;35m', '\033[1;32m', '\033[0m' 9 | 10 | class ThreadManager(object): 11 | i = 0 12 | 13 | def __init__(self, ipList): 14 | self.allIps = ipList 15 | self.size = len(ipList) 16 | 17 | def getNextIp(self): 18 | if not (self.i >= self.size - 1): 19 | ip = self.allIps[self.i] 20 | self.i += 1 21 | return ip 22 | return 0 23 | 24 | def getID(self): 25 | return self.i + 1 26 | 27 | def coreOptions(): 28 | options = [["network", "IP range to scan", ""], ["ports", "Comma separated list of ports to scan. (e.g: '21,22,53')", ""], 29 | ["port-timeout", "Timeout (in sec) for port 80.", "0.3"], ["threads", "Number of threads to run.", "50"], 30 | ["verbose", "Show verbose output.", "true"]] 31 | return options 32 | 33 | 34 | def createIPList(network): 35 | net4 = ipaddress.ip_network(network) 36 | ipList = [] 37 | for x in net4.hosts(): 38 | ipList.append(x) 39 | return ipList 40 | 41 | def print1(data): 42 | if verbose: 43 | print("\033[K" + data) 44 | 45 | def checkServer(address, port): 46 | s = socket.socket() 47 | s.settimeout(float(portTimeout)) 48 | try: 49 | s.connect((address, port)) 50 | s.close() 51 | return True 52 | except socket.error: 53 | s.close() 54 | return False 55 | except: 56 | s.close() 57 | return "FAIL" 58 | 59 | def writeToFile(line): 60 | file = open(fileName, "a") 61 | file.write(line) 62 | file.close() 63 | 64 | 65 | def restart_line(): 66 | sys.stdout.write('\r') 67 | sys.stdout.flush() 68 | 69 | 70 | def statusWidget(): 71 | sys.stdout.write(GREEN + "[" + status + "] " + YELLOW + str(threadManager.getID()) + GREEN + " / " + YELLOW + str( 72 | allIPs) + GREEN + " hosts done." + END) 73 | restart_line() 74 | sys.stdout.flush() 75 | 76 | 77 | def scan(i): 78 | global status 79 | global openPorts 80 | global done 81 | while True: 82 | if stop: 83 | sys.exit() 84 | ip = threadManager.getNextIp() 85 | if ip == 0: 86 | break 87 | logLine = "" 88 | status = (threadManager.getID() / allIPs) * 100 89 | status = format(round(status, 2)) 90 | status = str(status) + "%" 91 | stringIP = str(ip) 92 | for port in ports: 93 | if stop: 94 | sys.exit() 95 | isUp = checkServer(stringIP, port) 96 | if isUp != "FAIL": 97 | if isUp: 98 | openPorts = openPorts + 1 99 | print1(GREEN + "[+] Port " + str(port) + " is open on '" + stringIP + "'" + END) 100 | logLine = logLine + " " + str(port) 101 | elif not isUp: 102 | print1(RED + "[-] Port " + str(port) + " is closed on '" + stringIP + "'" + END) 103 | else: 104 | print1(RED + "[!] Failed connecting to '" + stringIP + "'" + END) 105 | 106 | if logLine != "": 107 | logLine = str(ip) + " - OPEN:" + logLine + "\n" 108 | logLines.append(logLine) 109 | 110 | done = done + 1 111 | 112 | 113 | def core(moduleOptions): 114 | print( 115 | "\n" + GREEN + "MANUAL module by @xdavidhu. Scanning subnet '" + YELLOW + moduleOptions[0][2] + GREEN + "'...\n") 116 | 117 | global status 118 | global fileName 119 | global allIPs 120 | global portTimeout 121 | global ips 122 | global threadCount 123 | global done 124 | global verbose 125 | global stop 126 | global ports 127 | global openPorts 128 | global logLines 129 | global threadManager 130 | logLines = [] 131 | stop = False 132 | done = 0 133 | 134 | portInput = moduleOptions[1][2] 135 | portTimeout = moduleOptions[2][2] 136 | network = moduleOptions[0][2] 137 | threadCount = int(moduleOptions[3][2]) 138 | verbose = moduleOptions[4][2] 139 | 140 | if verbose == "true": 141 | verbose = True 142 | else: 143 | verbose = False 144 | 145 | try: 146 | ipList = createIPList(network) 147 | allIPs = len(ipList) 148 | if allIPs == 0: 149 | raise Exception 150 | except: 151 | print(RED + "[!] Invalid subnet. Exiting...\n") 152 | return 153 | 154 | threadManager = ThreadManager(ipList) 155 | 156 | i = datetime.datetime.now() 157 | i = str(i).replace(" ", "_") 158 | i = str(i).replace(":", "-") 159 | script_path = os.path.dirname(os.path.realpath(__file__)) 160 | script_path = script_path.replace("modules", "") 161 | if not os.path.exists(script_path + "logs"): 162 | os.makedirs(script_path + "logs") 163 | fileName = script_path + "logs/log-manual-portSpider-" + i + ".log" 164 | 165 | file = open(fileName, 'w') 166 | file.write("subnet: " + network + "\n") 167 | file.close() 168 | 169 | ports = [] 170 | 171 | portInput = portInput.replace(" ", "") 172 | portInput = portInput.split(",") 173 | 174 | strPortList = "" 175 | try: 176 | for port in portInput: 177 | if not port.isdigit(): 178 | raise Exception 179 | ports.append(int(port)) 180 | strPortList = strPortList + " " + YELLOW + str(port) + GREEN + "," 181 | except: 182 | print(RED + "[!] Invalid list of ports! Exiting...\n" + END) 183 | return 184 | strPortList = strPortList[:-1] 185 | 186 | print(GREEN + "[I] PORTS => " + strPortList + END + "\n") 187 | 188 | openPorts = 0 189 | threads = [] 190 | for i in range(threadCount): 191 | i -= 1 192 | t = threading.Thread(target=scan, args=(i,)) 193 | t.daemon = True 194 | threads.append(t) 195 | t.start() 196 | 197 | try: 198 | while True: 199 | if done == threadCount and threadManager.getID() == allIPs: 200 | break 201 | statusWidget() 202 | except KeyboardInterrupt: 203 | stop = True 204 | verbose = False 205 | print("\n" + RED + "[I] Stopping..." + END) 206 | stop = True 207 | verbose = False 208 | 209 | for logLine in logLines: 210 | try: 211 | writeToFile(logLine) 212 | except: 213 | writeToFile("WRITING-ERROR") 214 | 215 | print("\n\n" + GREEN + "[I] MANUAL module done. Results saved to '" + YELLOW + fileName + GREEN + "'.\n") 216 | -------------------------------------------------------------------------------- /modules/mongodb.py: -------------------------------------------------------------------------------- 1 | import pymongo 2 | import socket 3 | import datetime 4 | import sys 5 | import ipaddress 6 | import threading 7 | import os 8 | 9 | BLUE, RED, WHITE, YELLOW, MAGENTA, GREEN, END = '\33[1;94m', '\033[1;91m', '\33[1;97m', '\33[1;93m', '\033[1;35m', '\033[1;32m', '\033[0m' 10 | 11 | class ThreadManager(object): 12 | i = 0 13 | 14 | def __init__(self, ipList): 15 | self.allIps = ipList 16 | self.size = len(ipList) 17 | 18 | def getNextIp(self): 19 | if not (self.i >= self.size - 1): 20 | ip = self.allIps[self.i] 21 | self.i += 1 22 | return ip 23 | return 0 24 | 25 | def getID(self): 26 | return self.i + 1 27 | 28 | def checkMongo(host, port): 29 | try: 30 | con = pymongo.MongoClient(host=host, port=port, connectTimeoutMS=mongoTimeout) 31 | except: 32 | return ["conection-error"] 33 | 34 | hasAuth = True 35 | try: 36 | dbs = con.database_names() 37 | hasAuth = False 38 | except: 39 | return ["permission-error"] 40 | 41 | try: 42 | serverVersion = tuple(con.server_info()['version']) 43 | tempServerVersion = "" 44 | for i in serverVersion: 45 | tempServerVersion = tempServerVersion + i 46 | serverVersion = tempServerVersion 47 | except: 48 | serverVersion = "-" 49 | 50 | return ["success", serverVersion, dbs] 51 | 52 | def coreOptions(): 53 | options = [["network", "IP range to scan", ""], ["port", "Port to scan.", "27017"], 54 | ["port-timeout", "Timeout (in sec) for port 80.", "0.3"], ["mongo-timeout", "Timeout (in sec) for the database connection.", "3"], 55 | ["threads", "Number of threads to run.", "50"], 56 | ["checkauth", "Connect to the server and perform tests.", "true"], ["verbose", "Show verbose output.", "true"]] 57 | return options 58 | 59 | 60 | def createIPList(network): 61 | net4 = ipaddress.ip_network(network) 62 | ipList = [] 63 | for x in net4.hosts(): 64 | ipList.append(x) 65 | return ipList 66 | 67 | def print1(data): 68 | if verbose: 69 | print("\033[K" + data) 70 | 71 | def checkServer(address, port): 72 | s = socket.socket() 73 | s.settimeout(float(portTimeout)) 74 | try: 75 | s.connect((address, port)) 76 | s.close() 77 | return True 78 | except socket.error: 79 | s.close() 80 | return False 81 | except: 82 | s.close() 83 | return "FAIL" 84 | 85 | 86 | def writeToFile(line): 87 | file = open(fileName, "a") 88 | file.write(line) 89 | file.close() 90 | 91 | 92 | def restart_line(): 93 | sys.stdout.write('\r') 94 | sys.stdout.flush() 95 | 96 | 97 | def statusWidget(): 98 | sys.stdout.write(GREEN + "[" + status + "] " + YELLOW + str(threadManager.getID()) + GREEN + " / " + YELLOW + str( 99 | allIPs) + GREEN + " hosts done." + END) 100 | restart_line() 101 | sys.stdout.flush() 102 | 103 | 104 | def scan(i): 105 | global status 106 | global openPorts 107 | global done 108 | while True: 109 | if stop: 110 | sys.exit() 111 | ip = threadManager.getNextIp() 112 | if ip == 0: 113 | break 114 | status = (threadManager.getID() / allIPs) * 100 115 | status = format(round(status, 2)) 116 | status = str(status) + "%" 117 | stringIP = str(ip) 118 | isUp = checkServer(stringIP, port) 119 | 120 | if isUp != "FAIL": 121 | if isUp: 122 | openPorts = openPorts + 1 123 | print1(GREEN + "[+] Port " + str(port) + " is open on '" + stringIP + "'" + END) 124 | 125 | if checkauth: 126 | mongoStatusReason = "UNKNOWN ERROR" 127 | mongo = checkMongo(stringIP, port) 128 | if mongo[0] == "conection-error": 129 | mongoStatus = False 130 | mongoStatusReason = "CONNECTION ERROR" 131 | print1(RED + "[!] Failed connecting to the database on '" + stringIP + "'. ERROR: " + mongoStatusReason + END) 132 | elif mongo[0] == "permission-error": 133 | mongoStatus = False 134 | mongoStatusReason = "PERMISSION ERROR" 135 | print1(RED + "[!] Failed connecting to the database on '" + stringIP + "'. ERROR: " + mongoStatusReason + END) 136 | elif mongo[0] == "success": 137 | mongoStatus = True 138 | version = mongo[1] 139 | dbs = mongo[2] 140 | 141 | dbsList = "" 142 | for db in dbs: 143 | dbsList = dbsList + str(db) + ", " 144 | if dbsList != "": 145 | dbsList = dbsList[:-2] 146 | else: 147 | dbsList = "-" 148 | 149 | print1(GREEN + "[+] Open database found:\n\tIP: " + stringIP + "\n\t" + "MongoDB version: " + str(version) + "\n\tDB's: " + dbsList + "\n") 150 | 151 | else: 152 | print1(RED + "[!] Failed connecting to the database on '" + stringIP + "'. ERROR: " + mongoStatusReason + END) 153 | mongoStatus = False 154 | 155 | if mongoStatus: 156 | logLine = stringIP + " - " + str(port) + " OPEN" + " - " + "OPEN DATABASE - Version: " + version + " - " + " DB's: " + dbsList + "\n" 157 | else: 158 | logLine = stringIP + " - " + str(port) + " OPEN" + " - DB SCAN ERROR: " + mongoStatusReason + "\n" 159 | logLines.append(logLine) 160 | else: 161 | logLine = stringIP + " - " + str(port) + " OPEN\n" 162 | logLines.append(logLine) 163 | elif not isUp: 164 | print1(RED + "[-] Port " + str(port) + " is closed on '" + stringIP + "'" + END) 165 | else: 166 | print1(RED + "[!] Failed connecting to '" + stringIP + "'" + END) 167 | done = done + 1 168 | 169 | 170 | def core(moduleOptions): 171 | print( 172 | "\n" + GREEN + "MONGODB module by @xdavidhu. Scanning subnet '" + YELLOW + moduleOptions[0][2] + GREEN + "'...\n") 173 | 174 | global status 175 | global fileName 176 | global allIPs 177 | global portTimeout 178 | global titleTimeout 179 | global ips 180 | global threadCount 181 | global done 182 | global verbose 183 | global stop 184 | global port 185 | global openPorts 186 | global logLines 187 | global checkauth 188 | global mongoTimeout 189 | global threadManager 190 | logLines = [] 191 | stop = False 192 | done = 0 193 | 194 | try: 195 | port = int(moduleOptions[1][2]) 196 | except: 197 | print(RED + "[!] Invalid port. Exiting...\n") 198 | return 199 | portTimeout = moduleOptions[2][2] 200 | network = moduleOptions[0][2] 201 | mongoTimeout = moduleOptions[3][2] 202 | threadCount = int(moduleOptions[4][2]) 203 | checkauth = moduleOptions[5][2] 204 | verbose = moduleOptions[6][2] 205 | 206 | try: 207 | mongoTimeout = int(mongoTimeout) 208 | mongoTimeout = round(mongoTimeout) 209 | mongoTimeout = mongoTimeout * 1000 210 | except: 211 | print(RED + "[!] Invalid mongo-timeout. Exiting...\n") 212 | return 213 | 214 | if verbose == "true": 215 | verbose = True 216 | else: 217 | verbose = False 218 | 219 | if checkauth == "true": 220 | checkauth = True 221 | else: 222 | checkauth = False 223 | 224 | try: 225 | ipList = createIPList(network) 226 | allIPs = len(ipList) 227 | if allIPs == 0: 228 | raise Exception 229 | except: 230 | print(RED + "[!] Invalid subnet. Exiting...\n") 231 | return 232 | 233 | threadManager = ThreadManager(ipList) 234 | 235 | i = datetime.datetime.now() 236 | i = str(i).replace(" ", "_") 237 | i = str(i).replace(":", "-") 238 | script_path = os.path.dirname(os.path.realpath(__file__)) 239 | script_path = script_path.replace("modules", "") 240 | if not os.path.exists(script_path + "logs"): 241 | os.makedirs(script_path + "logs") 242 | fileName = script_path + "logs/log-mongodb-portSpider-" + i + ".log" 243 | 244 | file = open(fileName, 'w') 245 | file.write("subnet: " + network + "\n") 246 | file.close() 247 | 248 | openPorts = 0 249 | threads = [] 250 | for i in range(threadCount): 251 | i -= 1 252 | t = threading.Thread(target=scan, args=(i,)) 253 | t.daemon = True 254 | threads.append(t) 255 | t.start() 256 | 257 | try: 258 | while True: 259 | if done == threadCount and threadManager.getID() == allIPs: 260 | break 261 | statusWidget() 262 | except KeyboardInterrupt: 263 | stop = True 264 | verbose = False 265 | print("\n" + RED + "[I] Stopping..." + END) 266 | stop = True 267 | verbose = False 268 | 269 | for logLine in logLines: 270 | try: 271 | writeToFile(logLine) 272 | except: 273 | writeToFile("WRITING-ERROR") 274 | 275 | print("\n\n" + GREEN + "[I] MONGODB module done. Results saved to '" + YELLOW + fileName + GREEN + "'.\n") 276 | -------------------------------------------------------------------------------- /modules/mysql.py: -------------------------------------------------------------------------------- 1 | import pymysql 2 | import socket 3 | import datetime 4 | import sys 5 | import ipaddress 6 | import threading 7 | import os 8 | 9 | BLUE, RED, WHITE, YELLOW, MAGENTA, GREEN, END = '\33[1;94m', '\033[1;91m', '\33[1;97m', '\33[1;93m', '\033[1;35m', '\033[1;32m', '\033[0m' 10 | 11 | class ThreadManager(object): 12 | i = 0 13 | 14 | def __init__(self, ipList): 15 | self.allIps = ipList 16 | self.size = len(ipList) 17 | 18 | def getNextIp(self): 19 | if not (self.i >= self.size - 1): 20 | ip = self.allIps[self.i] 21 | self.i += 1 22 | return ip 23 | return 0 24 | 25 | def getID(self): 26 | return self.i + 1 27 | 28 | def checkSQL(host, port): 29 | loginFail = False 30 | try: 31 | con = pymysql.connect(host=host, connect_timeout=sqlTimeout) 32 | except: 33 | loginFail = True 34 | 35 | if loginFail: 36 | try: 37 | con = pymysql.connect(host=host, user='root', passwd='', connect_timeout=sqlTimeout) 38 | except: 39 | return ["login-error"] 40 | 41 | try: 42 | cursor = con.cursor() 43 | cursor.execute("SHOW DATABASES") 44 | dbs = cursor.fetchall() 45 | except: 46 | dbs = ["-"] 47 | 48 | try: 49 | cursor = con.cursor() 50 | cursor.execute("SELECT VERSION()") 51 | serverVersion = str(cursor.fetchone()) 52 | except: 53 | serverVersion = "-" 54 | 55 | return ["success", serverVersion, dbs] 56 | 57 | 58 | def coreOptions(): 59 | options = [["network", "IP range to scan", ""], ["port", "Port to scan.", "3306"], 60 | ["port-timeout", "Timeout (in sec) for port 80.", "0.3"], 61 | ["sql-timeout", "Timeout (in sec) for the database connection.", "3"], 62 | ["threads", "Number of threads to run.", "50"], 63 | ["checkauth", "Connect to the server and perform tests.", "true"], 64 | ["verbose", "Show verbose output.", "true"]] 65 | return options 66 | 67 | 68 | def createIPList(network): 69 | net4 = ipaddress.ip_network(network) 70 | ipList = [] 71 | for x in net4.hosts(): 72 | ipList.append(x) 73 | return ipList 74 | 75 | 76 | def print1(data): 77 | if verbose: 78 | print("\033[K" + data) 79 | 80 | 81 | def checkServer(address, port): 82 | s = socket.socket() 83 | s.settimeout(float(portTimeout)) 84 | try: 85 | s.connect((address, port)) 86 | s.close() 87 | return True 88 | except socket.error: 89 | s.close() 90 | return False 91 | except: 92 | s.close() 93 | return "FAIL" 94 | 95 | 96 | def writeToFile(line): 97 | file = open(fileName, "a") 98 | file.write(line) 99 | file.close() 100 | 101 | 102 | def restart_line(): 103 | sys.stdout.write('\r') 104 | sys.stdout.flush() 105 | 106 | 107 | def statusWidget(): 108 | sys.stdout.write(GREEN + "[" + status + "] " + YELLOW + str(threadManager.getID()) + GREEN + " / " + YELLOW + str( 109 | allIPs) + GREEN + " hosts done." + END) 110 | restart_line() 111 | sys.stdout.flush() 112 | 113 | 114 | def scan(i): 115 | global status 116 | global openPorts 117 | global done 118 | while True: 119 | if stop: 120 | sys.exit() 121 | ip = threadManager.getNextIp() 122 | if ip == 0: 123 | break 124 | status = (threadManager.getID() / allIPs) * 100 125 | status = format(round(status, 2)) 126 | status = str(status) + "%" 127 | stringIP = str(ip) 128 | isUp = checkServer(stringIP, port) 129 | 130 | if isUp != "FAIL": 131 | if isUp: 132 | openPorts = openPorts + 1 133 | print1(GREEN + "[+] Port " + str(port) + " is open on '" + stringIP + "'" + END) 134 | 135 | if checkauth: 136 | mysqlStatusReason = "UNKNOWN ERROR" 137 | mysql = checkSQL(stringIP, port) 138 | if mysql[0] == "login-error": 139 | mysqlStatus = False 140 | mysqlStatusReason = "CONNECTION ERROR" 141 | print1( 142 | RED + "[!] Failed connecting to the database on '" + stringIP + "'. ERROR: " + mysqlStatusReason + END) 143 | elif mysql[0] == "permission-error": 144 | mysqlStatus = False 145 | mysqlStatusReason = "PERMISSION ERROR" 146 | print1( 147 | RED + "[!] Failed connecting to the database on '" + stringIP + "'. ERROR: " + mysqlStatusReason + END) 148 | elif mysql[0] == "success": 149 | mysqlStatus = True 150 | version = mysql[1] 151 | dbs = mysql[2] 152 | 153 | dbsList = "" 154 | for db in dbs: 155 | dbsList = dbsList + str(db) + ", " 156 | if dbsList != "": 157 | dbsList = dbsList[:-2] 158 | else: 159 | dbsList = "-" 160 | 161 | print1(GREEN + "[+] Open database found:\n\tIP: " + stringIP + "\n\t" + "MySQL version: " + str( 162 | version) + "\n\tDB's: " + dbsList + "\n") 163 | 164 | else: 165 | print1( 166 | RED + "[!] Failed connecting to the database on '" + stringIP + "'. ERROR: " + mysqlStatusReason + END) 167 | mysqlStatus = False 168 | 169 | if mysqlStatus: 170 | logLine = stringIP + " - " + str( 171 | port) + " OPEN" + " - " + "OPEN DATABASE - Version: " + version + " - " + " DB's: " + dbsList + "\n" 172 | else: 173 | logLine = stringIP + " - " + str( 174 | port) + " OPEN" + " - DB SCAN ERROR: " + mysqlStatusReason + "\n" 175 | logLines.append(logLine) 176 | else: 177 | logLine = stringIP + " - " + str(port) + " OPEN\n" 178 | logLines.append(logLine) 179 | elif not isUp: 180 | print1(RED + "[-] Port " + str(port) + " is closed on '" + stringIP + "'" + END) 181 | else: 182 | print1(RED + "[!] Failed connecting to '" + stringIP + "'" + END) 183 | done = done + 1 184 | 185 | 186 | def core(moduleOptions): 187 | print( 188 | "\n" + GREEN + "MYSQL module by @xdavidhu. Scanning subnet '" + YELLOW + moduleOptions[0][2] + GREEN + "'...\n") 189 | 190 | global status 191 | global fileName 192 | global allIPs 193 | global portTimeout 194 | global titleTimeout 195 | global ips 196 | global threadCount 197 | global done 198 | global verbose 199 | global stop 200 | global port 201 | global openPorts 202 | global logLines 203 | global checkauth 204 | global sqlTimeout 205 | global threadManager 206 | logLines = [] 207 | stop = False 208 | done = 0 209 | 210 | try: 211 | port = int(moduleOptions[1][2]) 212 | except: 213 | print(RED + "[!] Invalid port. Exiting...\n") 214 | return 215 | portTimeout = moduleOptions[2][2] 216 | network = moduleOptions[0][2] 217 | sqlTimeout = moduleOptions[3][2] 218 | threadCount = int(moduleOptions[4][2]) 219 | checkauth = moduleOptions[5][2] 220 | verbose = moduleOptions[6][2] 221 | 222 | try: 223 | sqlTimeout = int(sqlTimeout) 224 | except: 225 | print(RED + "[!] Invalid sql-timeout. Exiting...\n") 226 | return 227 | 228 | if verbose == "true": 229 | verbose = True 230 | else: 231 | verbose = False 232 | 233 | if checkauth == "true": 234 | checkauth = True 235 | else: 236 | checkauth = False 237 | 238 | try: 239 | ipList = createIPList(network) 240 | allIPs = len(ipList) 241 | if allIPs == 0: 242 | raise Exception 243 | except: 244 | print(RED + "[!] Invalid subnet. Exiting...\n") 245 | return 246 | 247 | threadManager = ThreadManager(ipList) 248 | 249 | i = datetime.datetime.now() 250 | i = str(i).replace(" ", "_") 251 | i = str(i).replace(":", "-") 252 | script_path = os.path.dirname(os.path.realpath(__file__)) 253 | script_path = script_path.replace("modules", "") 254 | if not os.path.exists(script_path + "logs"): 255 | os.makedirs(script_path + "logs") 256 | fileName = script_path + "logs/log-mysql-portSpider-" + i + ".log" 257 | 258 | file = open(fileName, 'w') 259 | file.write("subnet: " + network + "\n") 260 | file.close() 261 | 262 | openPorts = 0 263 | threads = [] 264 | for i in range(threadCount): 265 | t = threading.Thread(target=scan, args=(i,)) 266 | t.daemon = True 267 | threads.append(t) 268 | t.start() 269 | 270 | try: 271 | while True: 272 | if done == threadCount and threadManager.getID() == allIPs: 273 | break 274 | statusWidget() 275 | except KeyboardInterrupt: 276 | stop = True 277 | verbose = False 278 | print("\n" + RED + "[I] Stopping..." + END) 279 | stop = True 280 | verbose = False 281 | 282 | for logLine in logLines: 283 | try: 284 | writeToFile(logLine) 285 | except: 286 | writeToFile("WRITING-ERROR") 287 | print("\n\n" + GREEN + "[I] MYSQL module done. Results saved to '" + YELLOW + fileName + GREEN + "'.\n") 288 | -------------------------------------------------------------------------------- /modules/printer.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import requests 3 | from lxml.html import fromstring 4 | import datetime 5 | import sys 6 | import ipaddress 7 | import threading 8 | import os 9 | 10 | BLUE, RED, WHITE, YELLOW, MAGENTA, GREEN, END = '\33[1;94m', '\033[1;91m', '\33[1;97m', '\33[1;93m', '\033[1;35m', '\033[1;32m', '\033[0m' 11 | 12 | class ThreadManager(object): 13 | i = 0 14 | 15 | def __init__(self, ipList): 16 | self.allIps = ipList 17 | self.size = len(ipList) 18 | 19 | def getNextIp(self): 20 | if not (self.i >= self.size - 1): 21 | ip = self.allIps[self.i] 22 | self.i += 1 23 | return ip 24 | return 0 25 | 26 | def getID(self): 27 | return self.i + 1 28 | 29 | def coreOptions(): 30 | options = [["network", "IP range to scan", ""], ["port-timeout", "Timeout (in sec) for port 80.", "0.3"], 31 | ["title-timeout", "Timeout (in sec) for title resolve.", "3"], ["threads", "Number of threads to run.", "50"], 32 | ["verbose", "Show verbose output.", "true"]] 33 | return options 34 | 35 | 36 | def createIPList(network): 37 | net4 = ipaddress.ip_network(network) 38 | ipList = [] 39 | for x in net4.hosts(): 40 | ipList.append(x) 41 | return ipList 42 | 43 | def print1(data): 44 | if verbose: 45 | print("\033[K" + data) 46 | 47 | def checkServer(address, port): 48 | s = socket.socket() 49 | s.settimeout(float(portTimeout)) 50 | try: 51 | s.connect((address, port)) 52 | s.close() 53 | return True 54 | except socket.error: 55 | s.close() 56 | return False 57 | except: 58 | s.close() 59 | return "FAIL" 60 | 61 | 62 | def getHTTP(address, port): 63 | code = None 64 | title = None 65 | 66 | try: 67 | r = requests.get("http://" + address, timeout=float(titleTimeout), allow_redirects=True) 68 | except: 69 | return False 70 | 71 | try: 72 | code = r.status_code 73 | except: 74 | pass 75 | 76 | try: 77 | tree = fromstring(r.content) 78 | title = tree.findtext('.//title') 79 | except: 80 | pass 81 | 82 | return [title, code] 83 | 84 | 85 | def writeToFile(line): 86 | file = open(fileName, "a") 87 | file.write(line) 88 | file.close() 89 | 90 | 91 | def restart_line(): 92 | sys.stdout.write('\r') 93 | sys.stdout.flush() 94 | 95 | 96 | def statusWidget(): 97 | sys.stdout.write(GREEN + "[" + status + "] " + YELLOW + str(threadManager.getID()) + GREEN + " / " + YELLOW + str( 98 | allIPs) + GREEN + " hosts done." + END) 99 | restart_line() 100 | sys.stdout.flush() 101 | 102 | 103 | def scan(i): 104 | global status 105 | global openPorts 106 | global done 107 | title = "" 108 | while True: 109 | if stop: 110 | sys.exit() 111 | ip = threadManager.getNextIp() 112 | if ip == 0: 113 | break 114 | portsOpen = [] 115 | status = (threadManager.getID() / allIPs) * 100 116 | status = format(round(status, 2)) 117 | status = str(status) + "%" 118 | stringIP = str(ip) 119 | 120 | for port in ports: 121 | if stop: 122 | sys.exit() 123 | if port == 80: 124 | if not portsOpen: 125 | continue 126 | 127 | isUp = checkServer(stringIP, port) 128 | 129 | if isUp != "FAIL": 130 | if isUp: 131 | portsOpen.append(port) 132 | openPorts = openPorts + 1 133 | print1(GREEN + "[+] Port " + str(port) + " is open on '" + stringIP + "'" + END) 134 | 135 | if port == 80: 136 | http = getHTTP(stringIP, 80) 137 | if not http: 138 | print1(YELLOW + "[!] Failed to get the HTTP response of '" + stringIP + "'" + END) 139 | title = "NO-TITLE" 140 | code = "NO-CODE" 141 | else: 142 | title = str(http[0]) 143 | code = str(http[1]) 144 | if code is not None: 145 | print1(GREEN + "[+] Response code of '" + stringIP + "': '" + code + "'" + END) 146 | else: 147 | print1(YELLOW + "[!] Failed to get the response code of '" + stringIP + "'" + YELLOW) 148 | code = "NO-CODE" 149 | if title is not None: 150 | title = title.replace("\n", "") 151 | try: 152 | print1(GREEN + "[+] Title of '" + stringIP + "': '" + title + "'" + END) 153 | except: 154 | print1(YELLOW + "[!] Failed to print title of '" + stringIP + "'" + END) 155 | title = "NO-TITLE" 156 | else: 157 | print1(YELLOW + "[!] Failed to get title of '" + stringIP + "'" + YELLOW) 158 | title = "NO-TITLE" 159 | 160 | logLine = stringIP + " - " + "OPEN:" 161 | for port in portsOpen: 162 | logLine = logLine + " " + str(port) 163 | if title != "": 164 | logLine = logLine + " - HTTP Title: " + title 165 | logLine = logLine + "\n" 166 | logLines.append(logLine) 167 | 168 | elif not isUp: 169 | print1(RED + "[-] Port " + str(port) + " is closed on '" + stringIP + "'" + END) 170 | else: 171 | print1(RED + "[!] Failed connecting to '" + stringIP + "'" + END) 172 | done = done + 1 173 | 174 | 175 | def core(moduleOptions): 176 | print( 177 | "\n" + GREEN + "PRINTER module by @xdavidhu. Scanning subnet '" + YELLOW + moduleOptions[0][2] + GREEN + "'...\n") 178 | 179 | global status 180 | global fileName 181 | global allIPs 182 | global portTimeout 183 | global titleTimeout 184 | global ips 185 | global threadCount 186 | global done 187 | global verbose 188 | global stop 189 | global ports 190 | global openPorts 191 | global logLines 192 | global threadManager 193 | logLines = [] 194 | stop = False 195 | done = 0 196 | 197 | portTimeout = moduleOptions[1][2] 198 | titleTimeout = moduleOptions[2][2] 199 | network = moduleOptions[0][2] 200 | threadCount = int(moduleOptions[3][2]) 201 | verbose = moduleOptions[4][2] 202 | 203 | if verbose == "true": 204 | verbose = True 205 | else: 206 | verbose = False 207 | 208 | try: 209 | ipList = createIPList(network) 210 | allIPs = len(ipList) 211 | if allIPs == 0: 212 | raise Exception 213 | except: 214 | print(RED + "[!] Invalid subnet. Exiting...\n") 215 | return 216 | 217 | threadManager = ThreadManager(ipList) 218 | 219 | i = datetime.datetime.now() 220 | i = str(i).replace(" ", "_") 221 | i = str(i).replace(":", "-") 222 | script_path = os.path.dirname(os.path.realpath(__file__)) 223 | script_path = script_path.replace("modules", "") 224 | if not os.path.exists(script_path + "logs"): 225 | os.makedirs(script_path + "logs") 226 | fileName = script_path + "logs/log-printer-portSpider-" + i + ".log" 227 | 228 | file = open(fileName, 'w') 229 | file.write("subnet: " + network + "\n") 230 | file.close() 231 | 232 | ports = [9100, 515, 631, 80] 233 | openPorts = 0 234 | threads = [] 235 | for i in range(threadCount): 236 | i -= 1 237 | t = threading.Thread(target=scan, args=(i,)) 238 | t.daemon = True 239 | threads.append(t) 240 | t.start() 241 | 242 | try: 243 | while True: 244 | if done == threadCount and threadManager.getID() == allIPs: 245 | break 246 | statusWidget() 247 | except KeyboardInterrupt: 248 | stop = True 249 | verbose = False 250 | print("\n" + RED + "[I] Stopping..." + END) 251 | stop = True 252 | verbose = False 253 | 254 | for logLine in logLines: 255 | try: 256 | writeToFile(logLine) 257 | except: 258 | writeToFile("WRITING-ERROR") 259 | 260 | print("\n\n" + GREEN + "[I] PRINTER module done. Results saved to '" + YELLOW + fileName + GREEN + "'.\n") 261 | -------------------------------------------------------------------------------- /modules/ssh.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import datetime 3 | import sys 4 | import ipaddress 5 | import threading 6 | import os 7 | 8 | BLUE, RED, WHITE, YELLOW, MAGENTA, GREEN, END = '\33[1;94m', '\033[1;91m', '\33[1;97m', '\33[1;93m', '\033[1;35m', '\033[1;32m', '\033[0m' 9 | 10 | class ThreadManager(object): 11 | i = 0 12 | 13 | def __init__(self, ipList): 14 | self.allIps = ipList 15 | self.size = len(ipList) 16 | 17 | def getNextIp(self): 18 | if not (self.i >= self.size - 1): 19 | ip = self.allIps[self.i] 20 | self.i += 1 21 | return ip 22 | return 0 23 | 24 | def getID(self): 25 | return self.i + 1 26 | 27 | def coreOptions(): 28 | options = [["network", "IP range to scan", ""], ["port-timeout", "Timeout (in sec) for port 80.", "0.3"], 29 | ["threads", "Number of threads to run.", "50"], ["verbose", "Show verbose output.", "true"]] 30 | return options 31 | 32 | 33 | def createIPList(network): 34 | net4 = ipaddress.ip_network(network) 35 | ipList = [] 36 | for x in net4.hosts(): 37 | ipList.append(x) 38 | return ipList 39 | 40 | def print1(data): 41 | if verbose: 42 | print("\033[K" + data) 43 | 44 | def checkServer(address, port): 45 | s = socket.socket() 46 | s.settimeout(float(portTimeout)) 47 | try: 48 | s.connect((address, port)) 49 | data = s.recv(4096) 50 | s.close() 51 | return ["True", data] 52 | except socket.error: 53 | s.close() 54 | return "False" 55 | except: 56 | s.close() 57 | return "FAIL" 58 | 59 | def writeToFile(line): 60 | file = open(fileName, "a") 61 | file.write(line) 62 | file.close() 63 | 64 | 65 | def restart_line(): 66 | sys.stdout.write('\r') 67 | sys.stdout.flush() 68 | 69 | 70 | def statusWidget(): 71 | sys.stdout.write(GREEN + "[" + status + "] " + YELLOW + str(threadManager.getID()) + GREEN + " / " + YELLOW + str( 72 | allIPs) + GREEN + " hosts done." + END) 73 | restart_line() 74 | sys.stdout.flush() 75 | 76 | 77 | def scan(i): 78 | global status 79 | global openPorts 80 | global done 81 | while True: 82 | if stop: 83 | sys.exit() 84 | ip = threadManager.getNextIp() 85 | if ip == 0: 86 | break 87 | status = (threadManager.getID() / allIPs) * 100 88 | status = format(round(status, 2)) 89 | status = str(status) + "%" 90 | stringIP = str(ip) 91 | if stop: 92 | sys.exit() 93 | 94 | isUp = checkServer(stringIP, port) 95 | if isUp[0] != "FAIL": 96 | if isUp[0] == "True": 97 | openPorts = openPorts + 1 98 | print1(GREEN + "[+] Port " + str(port) + " is open on '" + stringIP + "' - Connection response: " + str(isUp[1]) + END) 99 | logLine = stringIP + " - " + str(isUp[1]) + "\n" 100 | logLines.append(logLine) 101 | elif not isUp[0] == "True": 102 | print1(RED + "[-] Port " + str(port) + " is closed on '" + stringIP + "'" + END) 103 | else: 104 | print1(RED + "[!] Failed connecting to '" + stringIP + "'" + END) 105 | done = done + 1 106 | 107 | 108 | def core(moduleOptions): 109 | print( 110 | "\n" + GREEN + "SSH module by @xdavidhu. Scanning subnet '" + YELLOW + moduleOptions[0][2] + GREEN + "'...\n") 111 | 112 | global status 113 | global fileName 114 | global allIPs 115 | global portTimeout 116 | global ips 117 | global threadCount 118 | global done 119 | global verbose 120 | global stop 121 | global port 122 | global openPorts 123 | global logLines 124 | global threadManager 125 | logLines = [] 126 | stop = False 127 | done = 0 128 | 129 | portTimeout = moduleOptions[1][2] 130 | network = moduleOptions[0][2] 131 | threadCount = int(moduleOptions[2][2]) 132 | verbose = moduleOptions[3][2] 133 | 134 | if verbose == "true": 135 | verbose = True 136 | else: 137 | verbose = False 138 | 139 | try: 140 | ipList = createIPList(network) 141 | allIPs = len(ipList) 142 | if allIPs == 0: 143 | raise Exception 144 | except: 145 | print(RED + "[!] Invalid subnet. Exiting...\n") 146 | return 147 | 148 | threadManager = ThreadManager(ipList) 149 | 150 | i = datetime.datetime.now() 151 | i = str(i).replace(" ", "_") 152 | i = str(i).replace(":", "-") 153 | script_path = os.path.dirname(os.path.realpath(__file__)) 154 | script_path = script_path.replace("modules", "") 155 | if not os.path.exists(script_path + "logs"): 156 | os.makedirs(script_path + "logs") 157 | fileName = script_path + "logs/log-ssh-portSpider-" + i + ".log" 158 | 159 | file = open(fileName, 'w') 160 | file.write("subnet: " + network + "\n") 161 | file.close() 162 | 163 | port = 22 164 | 165 | openPorts = 0 166 | threads = [] 167 | for i in range(threadCount): 168 | i -= 1 169 | t = threading.Thread(target=scan, args=(i,)) 170 | t.daemon = True 171 | threads.append(t) 172 | t.start() 173 | 174 | try: 175 | while True: 176 | if done == threadCount and threadManager.getID() == allIPs: 177 | break 178 | statusWidget() 179 | except KeyboardInterrupt: 180 | stop = True 181 | verbose = False 182 | print("\n" + RED + "[I] Stopping..." + END) 183 | stop = True 184 | verbose = False 185 | 186 | for logLine in logLines: 187 | try: 188 | writeToFile(logLine) 189 | except: 190 | writeToFile("WRITING-ERROR") 191 | 192 | print("\n\n" + GREEN + "[I] SSH module done. Results saved to '" + YELLOW + fileName + GREEN + "'.\n") 193 | -------------------------------------------------------------------------------- /modules/template.py: -------------------------------------------------------------------------------- 1 | def coreOptions(): 2 | options = [["testvar1", "testvar1 description", ""], ["testvar2", "testvar2 description", "testvar2 pre-set value"], ["var3", "var3 description", ""]] 3 | return options 4 | 5 | def core(moduleOptions): 6 | 7 | testvar1value = moduleOptions[0][2] 8 | testvar2value = moduleOptions[1][2] 9 | var3value = moduleOptions[2][2] 10 | 11 | print("Hello world!") 12 | 13 | print("testvar1: " + str(testvar1value)) 14 | print("testvar2: " + str(testvar2value)) 15 | print("var3: " + str(var3value)) -------------------------------------------------------------------------------- /portSpider.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -.- coding: utf-8 -.- 3 | 4 | BLUE, RED, WHITE, YELLOW, MAGENTA, GREEN, END = '\33[1;94m', '\033[1;91m', '\33[1;97m', '\33[1;93m', '\033[1;35m', '\033[1;32m', '\033[0m' 5 | 6 | 7 | try: 8 | import os 9 | import traceback 10 | import argparse 11 | 12 | # MODULE IMPORT 13 | from modules import * 14 | except KeyboardInterrupt: 15 | print(GREEN + "\n[I] Shutting down..." + END) 16 | raise SystemExit 17 | except: 18 | print(RED + "\n[!] Module input failed. Please make sure to install the dependencies." + END) 19 | raise SystemExit 20 | 21 | allModules = [["http", "Scan for open HTTP ports, and get the titles."], 22 | ["mongodb", "Scan for open MongoDB instances, and check if they are password protected."], 23 | ["mysql", "Scan for open MySQL servers, and try to log in with the default credentials."], 24 | ["ssh", "Scan for open SSH ports."], ["printer", "Scan for open printer ports and websites."], 25 | ["gameserver", "Scan for open game server ports."], 26 | ["manual", "Scan custom ports."], ["template", "Template module for developers."]] 27 | 28 | textToModule = [["http", http], ["template", template], ["printer", printer], ["gameserver", gameserver], ["ssh", ssh], ["manual", manual], ["mongodb", mongodb], ["mysql", mysql]] 29 | 30 | inModule = False 31 | currentModule = "" 32 | moduleOptions = [] 33 | 34 | def commandHandler(command): 35 | command = str(command) 36 | command = command.lower() 37 | 38 | global inModule 39 | global currentModule 40 | global moduleOptions 41 | global currentModuleFile 42 | 43 | # COMMANDS 44 | 45 | # HELP 46 | def helpPrint(name, desc, usage): 47 | print("\t" + YELLOW + name + GREEN + ": " + BLUE + desc + GREEN + " - '" + usage + "'" + END) 48 | if command == "help": 49 | print(GREEN + "\n[I] Available commands:\n" + END) 50 | helpPrint("MODULES", "List all modules", "modules") 51 | helpPrint("USE", "Use a module", "use module_name") 52 | helpPrint("OPTIONS", "Show a module's options", "options") 53 | helpPrint("SET", "Set an option", "set option_name option_value") 54 | helpPrint("RUN", "Run the selected module", "run") 55 | helpPrint("BACK", "Go back to menu", "back") 56 | helpPrint("EXIT", "Shut down portSpider", "exit") 57 | print() 58 | 59 | # USE 60 | elif command.startswith("use "): 61 | if not inModule: 62 | tempModule = command.replace("use ", "") 63 | inModule = False 64 | for module in allModules: 65 | if module[0] == tempModule: 66 | inModule = True 67 | if inModule: 68 | inModule = True 69 | currentModule = tempModule 70 | for text in textToModule: 71 | if text[0] == currentModule: 72 | currentModuleFile = text[1] 73 | getCoreOptions = getattr(currentModuleFile, "coreOptions", None) 74 | moduleOptions = getCoreOptions() 75 | else: 76 | print(RED + "[!] Module '" + YELLOW + tempModule + RED + "' not found." + END) 77 | else: 78 | print(RED + "[!] Module '" + YELLOW + currentModule + RED + "' already selected. Type '" + YELLOW + "back" + RED + "' to go back to the main menu." + END) 79 | elif command == "use": 80 | print(RED + "[!] Usage: 'use " + YELLOW + "module_name" + RED + "'" + END) 81 | 82 | # OPTIONS 83 | elif command == "options": 84 | if inModule: 85 | print(GREEN + "\n Options for module '" + YELLOW + currentModule + GREEN + "':" + END) 86 | for option in moduleOptions: 87 | if option[2] == "": 88 | print("\t" + YELLOW + option[0] + GREEN + " - " + BLUE + option[1] + GREEN + " ==> " + RED + "[NOT SET]" + END) 89 | else: 90 | print("\t" + YELLOW + option[0] + GREEN + " - " + BLUE + option[1] + GREEN + " ==> '" + YELLOW + 91 | option[2] + GREEN + "'" + END) 92 | print() 93 | else: 94 | print(RED + "[!] No module selected." + END) 95 | 96 | # SET 97 | elif command.startswith("set "): 98 | if inModule: 99 | command = command.replace("set ", "") 100 | command = command.split() 101 | error = False 102 | try: 103 | test = command[0] 104 | test = command[1] 105 | except: 106 | print(RED + "[!] Usage: 'set " + YELLOW + "option_name option_value" + RED + "'" + END) 107 | error = True 108 | if not error: 109 | inOptions = False 110 | for option in moduleOptions: 111 | if option[0] == command[0]: 112 | inOptions = True 113 | option[2] = command[1] 114 | print(YELLOW + option[0] + GREEN + " ==> '" + YELLOW + command[1] + GREEN + "'" + END) 115 | if not inOptions: 116 | print(RED + "[!] Option '" + YELLOW + command[0] + RED + "' not found." + END) 117 | else: 118 | print(RED + "[!] No module selected." + END) 119 | elif command == "set": 120 | print(RED + "[!] Usage: 'set " + YELLOW + "option_name option_value" + RED + "'" + END) 121 | 122 | # RUN 123 | elif command == "run": 124 | if inModule: 125 | fail = False 126 | for option in moduleOptions: 127 | if option[2] == "": 128 | fail = True 129 | if not fail: 130 | print(GREEN + "[I] Starting module '" + YELLOW + currentModule + GREEN + "'..." + END) 131 | coreModule = getattr(currentModuleFile, "core") 132 | try: 133 | coreModule(moduleOptions) 134 | except KeyboardInterrupt: 135 | print(GREEN + "[I] Stopping module..." + END) 136 | except Exception as e: 137 | print(RED + "\n[!] Module crashed." + END) 138 | print(RED + "[!] Debug info:\n'") 139 | print(traceback.format_exc()) 140 | print("\n" + END) 141 | else: 142 | print(RED + "[!] Not all options set." + END) 143 | else: 144 | print(RED + "[!] No module selected." + END) 145 | # BACK 146 | elif command == "back": 147 | if inModule: 148 | inModule = False 149 | currentModule = "" 150 | moduleOptions = [] 151 | 152 | # EXIT 153 | elif command == "exit": 154 | print(GREEN + "[I] Shutting down..." + END) 155 | raise SystemExit 156 | 157 | # MODULES 158 | elif command == "modules": 159 | print(GREEN + "\nAvailable modules:" + END) 160 | for module in allModules: 161 | print(YELLOW + "\t" + module[0] + GREEN + " - " + BLUE + module[1] + END) 162 | print() 163 | 164 | # CLEAR 165 | elif command == "clear": 166 | os.system("clear||cls") 167 | 168 | # DEBUG 169 | elif command == "debug": 170 | print("inModule: " + str(inModule)) 171 | print(currentModule) 172 | print(moduleOptions) 173 | 174 | elif command == "": 175 | pass 176 | 177 | else: 178 | print(RED + "[!] Unknown command: '" + YELLOW + command + RED + "'. Type '" + YELLOW + "help" + RED + "' for all available commands." + END) 179 | 180 | parser = argparse.ArgumentParser(description="portSpider") 181 | parser.add_argument("--test", action='store_true') 182 | args, leftovers = parser.parse_known_args() 183 | 184 | if args.test: 185 | print("Test build detected. Exiting...") 186 | exit() 187 | 188 | header = """ 189 | ██████╗ ██████╗ ██████╗ ████████╗███████╗██████╗ ██╗██████╗ ███████╗██████╗ 190 | ██╔══██╗██╔═══██╗██╔══██╗╚══██╔══╝██╔════╝██╔══██╗██║██╔══██╗██╔════╝██╔══██╗ 191 | ██████╔╝██║ ██║██████╔╝ ██║ ███████╗██████╔╝██║██║ ██║█████╗ ██████╔╝ 192 | ██╔═══╝ ██║ ██║██╔══██╗ ██║ ╚════██║██╔═══╝ ██║██║ ██║██╔══╝ ██╔══██╗ 193 | ██║ ╚██████╔╝██║ ██║ ██║ ███████║██║ ██║██████╔╝███████╗██║ ██║ 194 | ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝╚═════╝ ╚══════╝╚═╝ ╚═╝ 195 | """ 196 | 197 | try: 198 | print(GREEN + header + " v1.0 by David Schütz (@xdavidhu)\n" + END) 199 | except: 200 | print(GREEN + header + " v1.0 by @xdavidhu\n" + END) 201 | 202 | moduleList = "" 203 | i = 0 204 | for module in allModules: 205 | i += 1 206 | if i%7 == 0: 207 | moduleList += "\n" 208 | moduleList = moduleList + YELLOW + module[0] + GREEN + ", " 209 | moduleList = moduleList[:-2] 210 | print(GREEN + "Loaded modules: " + moduleList + "\n") 211 | 212 | while True: 213 | if inModule: 214 | inputHeader = BLUE + "portSpider" + RED + "/" + currentModule + BLUE + " $> " + END 215 | else: 216 | inputHeader = BLUE + "portSpider $> " + END 217 | 218 | try: 219 | commandHandler(input(inputHeader)) 220 | except KeyboardInterrupt: 221 | print(GREEN + "\n[I] Shutting down..." + END) 222 | raise SystemExit 223 | except Exception as e: 224 | print(RED + "\n[!] portSpider crashed...\n[!] Debug info: \n") 225 | print(traceback.format_exc()) 226 | print("\n" + END) 227 | exit() 228 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | lxml 2 | requests 3 | pymysql 4 | pymongo 5 | ipaddress 6 | --------------------------------------------------------------------------------