├── .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 | [](https://travis-ci.org/xdavidhu/portSpider)
10 | [](https://github.com/xdavidhu/portSpider)
11 | [](https://github.com/xdavidhu/portSpider/blob/master/LICENSE)
12 | [](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 |
--------------------------------------------------------------------------------