lanscape 1.2.9a1__tar.gz → 1.2.9a2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of lanscape might be problematic. Click here for more details.
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/MANIFEST.in +1 -0
- {lanscape-1.2.9a1/src/lanscape.egg-info → lanscape-1.2.9a2}/PKG-INFO +2 -2
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/pyproject.toml +1 -1
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/libraries/app_scope.py +12 -1
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/libraries/ip_parser.py +1 -1
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/libraries/mac_lookup.py +1 -2
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/libraries/net_tools.py +9 -1
- lanscape-1.2.9a2/src/lanscape/libraries/service_scan.py +51 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/libraries/subnet_scan.py +47 -13
- lanscape-1.2.9a2/src/lanscape/resources/services/definitions.jsonc +456 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/blueprints/api/scan.py +2 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/static/js/main.js +5 -1
- {lanscape-1.2.9a1 → lanscape-1.2.9a2/src/lanscape.egg-info}/PKG-INFO +2 -2
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape.egg-info/SOURCES.txt +2 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/LICENSE +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/README.md +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/setup.cfg +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/__init__.py +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/__main__.py +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/libraries/decorators.py +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/libraries/errors.py +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/libraries/logger.py +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/libraries/port_manager.py +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/libraries/runtime_args.py +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/libraries/version_manager.py +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/resources/mac_addresses/convert_csv.py +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/resources/mac_addresses/mac_db.json +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/resources/ports/convert_csv.py +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/resources/ports/full.json +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/resources/ports/large.json +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/resources/ports/medium.json +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/resources/ports/small.json +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/tests/__init__.py +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/tests/_helpers.py +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/tests/test_api.py +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/tests/test_env.py +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/tests/test_library.py +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/app.py +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/blueprints/__init__.py +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/blueprints/api/__init__.py +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/blueprints/api/port.py +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/blueprints/api/tools.py +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/blueprints/web/__init__.py +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/blueprints/web/routes.py +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/main.py +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/static/css/style.css +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/static/img/ico/android-chrome-192x192.png +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/static/img/ico/android-chrome-512x512.png +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/static/img/ico/apple-touch-icon.png +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/static/img/ico/favicon-16x16.png +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/static/img/ico/favicon-32x32.png +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/static/img/ico/favicon.ico +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/static/img/ico/site.webmanifest +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/static/js/core.js +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/static/js/layout-sizing.js +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/static/js/quietReload.js +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/static/js/shutdown-server.js +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/static/js/subnet-info.js +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/static/js/subnet-selector.js +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/static/lanscape.webmanifest +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/templates/base.html +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/templates/core/head.html +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/templates/core/scripts.html +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/templates/error.html +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/templates/info.html +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/templates/main.html +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/templates/scan/export.html +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/templates/scan/ip-table-row.html +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/templates/scan/ip-table.html +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/templates/scan/overview.html +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/templates/scan/scan-error.html +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/templates/scan.html +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/templates/shutdown.html +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape.egg-info/dependency_links.txt +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape.egg-info/requires.txt +0 -0
- {lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: lanscape
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.9a2
|
|
4
4
|
Summary: A python based local network scanner
|
|
5
5
|
Author-email: Michael Dennis <michael@dipduo.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/mdennis281/py-lanscape
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
|
-
import
|
|
2
|
+
import json
|
|
3
3
|
import sys
|
|
4
|
+
import re
|
|
4
5
|
|
|
5
6
|
class ResourceManager:
|
|
6
7
|
"""
|
|
@@ -17,6 +18,16 @@ class ResourceManager:
|
|
|
17
18
|
with open(self.asset_dir / asset_name, 'r') as f:
|
|
18
19
|
return f.read()
|
|
19
20
|
|
|
21
|
+
def get_json(self, asset_name: str):
|
|
22
|
+
return json.loads(self.get(asset_name))
|
|
23
|
+
|
|
24
|
+
def get_jsonc(self, asset_name: str):
|
|
25
|
+
" Get JSON content with comments removed "
|
|
26
|
+
content = self.get(asset_name)
|
|
27
|
+
cleaned_content = re.sub(r'//.*', '', content)
|
|
28
|
+
return json.loads(cleaned_content)
|
|
29
|
+
|
|
30
|
+
|
|
20
31
|
def update(self, asset_name: str, content: str):
|
|
21
32
|
with open(self.asset_dir / asset_name, 'w') as f:
|
|
22
33
|
f.write(content)
|
|
@@ -28,7 +28,7 @@ def parse_ip_input(ip_input):
|
|
|
28
28
|
|
|
29
29
|
# If no CIDR or range, assume a single IP
|
|
30
30
|
else:
|
|
31
|
-
ip_ranges.append(ipaddress.IPv4Address(entry
|
|
31
|
+
ip_ranges.append(ipaddress.IPv4Address(entry))
|
|
32
32
|
if len(ip_ranges) > MAX_IPS_ALLOWED:
|
|
33
33
|
raise SubnetTooLargeError(ip_input)
|
|
34
34
|
return ip_ranges
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import re
|
|
2
|
-
import json
|
|
3
2
|
import logging
|
|
4
3
|
import platform
|
|
5
4
|
import subprocess
|
|
@@ -7,7 +6,7 @@ from typing import List
|
|
|
7
6
|
|
|
8
7
|
from .app_scope import ResourceManager
|
|
9
8
|
|
|
10
|
-
DB =
|
|
9
|
+
DB = ResourceManager('mac_addresses').get_json('mac_db.json')
|
|
11
10
|
|
|
12
11
|
log = logging.getLogger('MacLookup')
|
|
13
12
|
|
|
@@ -8,9 +8,10 @@ import ipaddress
|
|
|
8
8
|
import traceback
|
|
9
9
|
import subprocess
|
|
10
10
|
from time import sleep
|
|
11
|
-
from typing import List
|
|
11
|
+
from typing import List, Dict
|
|
12
12
|
from scapy.all import ARP, Ether, srp
|
|
13
13
|
|
|
14
|
+
from .service_scan import scan_service
|
|
14
15
|
from .mac_lookup import lookup_mac, get_macs
|
|
15
16
|
from .ip_parser import get_address_count, MAX_IPS_ALLOWED
|
|
16
17
|
|
|
@@ -73,6 +74,7 @@ class Device(IPAlive):
|
|
|
73
74
|
self.manufacturer: str = None
|
|
74
75
|
self.ports: List[int] = []
|
|
75
76
|
self.stage: str = 'found'
|
|
77
|
+
self.services: Dict[str,List[int]] = {}
|
|
76
78
|
self.log = logging.getLogger('Device')
|
|
77
79
|
|
|
78
80
|
def get_metadata(self):
|
|
@@ -100,6 +102,12 @@ class Device(IPAlive):
|
|
|
100
102
|
return True
|
|
101
103
|
return False
|
|
102
104
|
|
|
105
|
+
def scan_service(self,port:int):
|
|
106
|
+
service = scan_service(self.ip,port)
|
|
107
|
+
service_ports = self.services.get(service,[])
|
|
108
|
+
service_ports.append(port)
|
|
109
|
+
self.services[service] = service_ports
|
|
110
|
+
|
|
103
111
|
def get_mac(self):
|
|
104
112
|
if not self.macs:
|
|
105
113
|
self.macs = self._get_mac_addresses()
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import logging
|
|
3
|
+
import traceback
|
|
4
|
+
from .app_scope import ResourceManager
|
|
5
|
+
|
|
6
|
+
log = logging.getLogger('ServiceScan')
|
|
7
|
+
SERVICES = ResourceManager('services').get_jsonc('definitions.jsonc')
|
|
8
|
+
|
|
9
|
+
# skip printer ports because they cause blank pages to be printed
|
|
10
|
+
PRINTER_PORTS = [9100, 631]
|
|
11
|
+
|
|
12
|
+
def scan_service(ip: str, port: int, timeout=10) -> str:
|
|
13
|
+
"""
|
|
14
|
+
Synchronous function that attempts to identify the service running on a given port.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
async def _async_scan_service(ip: str, port: int, timeout) -> str:
|
|
18
|
+
if port in PRINTER_PORTS:
|
|
19
|
+
return "Printer"
|
|
20
|
+
|
|
21
|
+
try:
|
|
22
|
+
# Add a timeout to prevent hanging
|
|
23
|
+
reader, writer = await asyncio.wait_for(asyncio.open_connection(ip, port), timeout=5)
|
|
24
|
+
|
|
25
|
+
# Send a probe appropriate for common services
|
|
26
|
+
probe = "GET / HTTP/1.1\r\nHost: {}\r\n\r\n".format(ip).encode("utf-8")
|
|
27
|
+
writer.write(probe)
|
|
28
|
+
await writer.drain()
|
|
29
|
+
|
|
30
|
+
# Receive the response with a timeout
|
|
31
|
+
response = await asyncio.wait_for(reader.read(1024), timeout=timeout)
|
|
32
|
+
writer.close()
|
|
33
|
+
await writer.wait_closed()
|
|
34
|
+
|
|
35
|
+
# Analyze the response to identify the service
|
|
36
|
+
response_str = response.decode("utf-8", errors="ignore")
|
|
37
|
+
for service, hints in SERVICES.items():
|
|
38
|
+
if any(hint.lower() in response_str.lower() for hint in hints):
|
|
39
|
+
return service
|
|
40
|
+
except asyncio.TimeoutError:
|
|
41
|
+
log.warning(f"Timeout scanning {ip}:{port}")
|
|
42
|
+
except Exception as e:
|
|
43
|
+
log.error(f"Error scanning {ip}:{port}: {str(e)}")
|
|
44
|
+
log.debug(traceback.format_exc())
|
|
45
|
+
return "Unknown"
|
|
46
|
+
|
|
47
|
+
# Use asyncio.run to execute the asynchronous logic synchronously
|
|
48
|
+
return asyncio.run(_async_scan_service(ip, port,timeout=timeout))
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
@@ -32,8 +32,31 @@ class ScanConfig:
|
|
|
32
32
|
t_cnt_port_test: int = 128
|
|
33
33
|
t_cnt_isalive: int = 256
|
|
34
34
|
|
|
35
|
+
task_scan_ports: bool = True
|
|
36
|
+
# below wont run if above false
|
|
37
|
+
task_scan_port_services: bool = True
|
|
38
|
+
|
|
35
39
|
def t_cnt(self, id: str) -> int:
|
|
36
40
|
return int(int(getattr(self, f't_cnt_{id}')) * float(self.t_multiplier))
|
|
41
|
+
|
|
42
|
+
@staticmethod
|
|
43
|
+
def from_dict(data: dict) -> 'ScanConfig':
|
|
44
|
+
return ScanConfig(
|
|
45
|
+
subnet = data['subnet'],
|
|
46
|
+
port_list = data['port_list'],
|
|
47
|
+
t_multiplier = data.get('parallelism',1.0),
|
|
48
|
+
t_cnt_port_scan = data.get('t_cnt_port_scan',10),
|
|
49
|
+
t_cnt_port_test = data.get('t_cnt_port_test',128),
|
|
50
|
+
t_cnt_isalive = data.get('t_cnt_isalive',256),
|
|
51
|
+
task_scan_ports = data.get('task_scan_ports',True),
|
|
52
|
+
task_scan_port_services = data.get('task_scan_port_services',True)
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
def get_ports(self) -> List[int]:
|
|
56
|
+
return PortManager().get_port_list(self.port_list).keys()
|
|
57
|
+
|
|
58
|
+
def parse_subnet(self) -> List[ipaddress.IPv4Network]:
|
|
59
|
+
return parse_ip_input(self.subnet)
|
|
37
60
|
|
|
38
61
|
|
|
39
62
|
|
|
@@ -43,13 +66,13 @@ class SubnetScanner:
|
|
|
43
66
|
self,
|
|
44
67
|
config: ScanConfig
|
|
45
68
|
):
|
|
46
|
-
self.
|
|
47
|
-
self.
|
|
48
|
-
self.ports:
|
|
69
|
+
self.cfg = config
|
|
70
|
+
self.subnet = config.parse_subnet()
|
|
71
|
+
self.ports: List[int] = config.get_ports()
|
|
49
72
|
self.running = False
|
|
50
73
|
self.subnet_str = config.subnet
|
|
51
74
|
|
|
52
|
-
|
|
75
|
+
|
|
53
76
|
self.job_stats = JobStats()
|
|
54
77
|
self.uid = str(uuid.uuid4())
|
|
55
78
|
self.results = ScannerResults(self)
|
|
@@ -81,7 +104,8 @@ class SubnetScanner:
|
|
|
81
104
|
|
|
82
105
|
|
|
83
106
|
self._set_stage('testing ports')
|
|
84
|
-
self.
|
|
107
|
+
if self.cfg.task_scan_ports:
|
|
108
|
+
self._scan_network_ports()
|
|
85
109
|
self.running = False
|
|
86
110
|
self._set_stage('complete')
|
|
87
111
|
|
|
@@ -134,17 +158,23 @@ class SubnetScanner:
|
|
|
134
158
|
|
|
135
159
|
|
|
136
160
|
|
|
137
|
-
def debug_active_scan(self):
|
|
161
|
+
def debug_active_scan(self,sleep_sec=1):
|
|
138
162
|
"""
|
|
139
163
|
Run this after running scan_subnet_threaded
|
|
140
164
|
to see the progress of the scan
|
|
141
165
|
"""
|
|
142
166
|
while self.running:
|
|
167
|
+
percent = self.calc_percent_complete()
|
|
168
|
+
t_elapsed = time() - self.results.start_time
|
|
169
|
+
t_remain = int((100-percent) * (t_elapsed / percent)) if percent else '∞'
|
|
170
|
+
buffer = f'{self.uid} - {self.subnet_str}\n'
|
|
171
|
+
buffer += f'Elapsed: {int(t_elapsed)} sec - Remain: {t_remain} sec\n'
|
|
172
|
+
buffer += f'Scanned: {self.results.devices_scanned}/{self.results.devices_total}'
|
|
173
|
+
buffer += f' - {percent}%\n'
|
|
174
|
+
buffer += str(self.job_stats)
|
|
143
175
|
os.system('cls' if os.name == 'nt' else 'clear')
|
|
144
|
-
print(
|
|
145
|
-
|
|
146
|
-
print(self.job_stats)
|
|
147
|
-
sleep(1)
|
|
176
|
+
print(buffer)
|
|
177
|
+
sleep(sleep_sec)
|
|
148
178
|
|
|
149
179
|
@terminator
|
|
150
180
|
@job_tracker
|
|
@@ -187,9 +217,13 @@ class SubnetScanner:
|
|
|
187
217
|
def _test_port(self,host: Device, port: int):
|
|
188
218
|
"""
|
|
189
219
|
Test if a port is open on a given host.
|
|
220
|
+
If port open, determine service.
|
|
190
221
|
Device class handles tracking open ports.
|
|
191
222
|
"""
|
|
192
|
-
|
|
223
|
+
is_alive = host.test_port(port)
|
|
224
|
+
if is_alive and self.cfg.task_scan_port_services:
|
|
225
|
+
host.scan_service(port)
|
|
226
|
+
return is_alive
|
|
193
227
|
|
|
194
228
|
|
|
195
229
|
@terminator
|
|
@@ -209,7 +243,7 @@ class SubnetScanner:
|
|
|
209
243
|
class ScannerResults:
|
|
210
244
|
def __init__(self,scan: SubnetScanner):
|
|
211
245
|
self.scan = scan
|
|
212
|
-
self.port_list: str = scan.port_list
|
|
246
|
+
self.port_list: str = scan.cfg.port_list
|
|
213
247
|
self.subnet: str = scan.subnet_str
|
|
214
248
|
self.uid = scan.uid
|
|
215
249
|
|
|
@@ -263,7 +297,7 @@ class ScannerResults:
|
|
|
263
297
|
def __str__(self):
|
|
264
298
|
# Prepare data for tabulate
|
|
265
299
|
data = [
|
|
266
|
-
[device.ip, device.hostname, device.
|
|
300
|
+
[device.ip, device.hostname, device.get_mac(), ", ".join(map(str, device.ports))]
|
|
267
301
|
for device in self.devices
|
|
268
302
|
]
|
|
269
303
|
|
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
{
|
|
2
|
+
// ----------------------- Web Services -----------------------
|
|
3
|
+
"HTTP": [
|
|
4
|
+
"HTTP",
|
|
5
|
+
"Apache",
|
|
6
|
+
"Nginx",
|
|
7
|
+
"IIS",
|
|
8
|
+
"lighttpd",
|
|
9
|
+
"Caddy",
|
|
10
|
+
"OpenResty",
|
|
11
|
+
"GWS", // Google Web Server
|
|
12
|
+
"LiteSpeed",
|
|
13
|
+
"Gunicorn", // Often in X-Powered-By
|
|
14
|
+
"OpenLiteSpeed",
|
|
15
|
+
"Cloudflare"
|
|
16
|
+
],
|
|
17
|
+
"HTTPS": [
|
|
18
|
+
"HTTPS",
|
|
19
|
+
"SSL",
|
|
20
|
+
"TLS"
|
|
21
|
+
// Possibly you'd see "443" in a banner or SNI reference,
|
|
22
|
+
// but typically "SSL" or "TLS" coverage is sufficient
|
|
23
|
+
],
|
|
24
|
+
|
|
25
|
+
// ------------------ Remote Shell / Admin --------------------
|
|
26
|
+
"SSH": [
|
|
27
|
+
"SSH",
|
|
28
|
+
"OpenSSH",
|
|
29
|
+
"Dropbear",
|
|
30
|
+
"libssh"
|
|
31
|
+
],
|
|
32
|
+
"Telnet": [
|
|
33
|
+
"Telnet",
|
|
34
|
+
"BusyBox on telnetd"
|
|
35
|
+
],
|
|
36
|
+
|
|
37
|
+
// ------------------ File Transfer Protocols -----------------
|
|
38
|
+
"FTP": [
|
|
39
|
+
"FTP",
|
|
40
|
+
"FileZilla",
|
|
41
|
+
"ProFTPD",
|
|
42
|
+
"vsftpd",
|
|
43
|
+
"Pure-FTPd",
|
|
44
|
+
"WS_FTP",
|
|
45
|
+
"Microsoft ftpd"
|
|
46
|
+
],
|
|
47
|
+
"SFTP": [
|
|
48
|
+
"SFTP"
|
|
49
|
+
// SFTP typically is an SSH subsystem, so you'd often see an SSH banner anyway
|
|
50
|
+
],
|
|
51
|
+
"TFTP": [
|
|
52
|
+
"TFTP"
|
|
53
|
+
],
|
|
54
|
+
|
|
55
|
+
// -------------------- Email / Messaging ----------------------
|
|
56
|
+
"SMTP": [
|
|
57
|
+
"SMTP",
|
|
58
|
+
"Postfix",
|
|
59
|
+
"Exim",
|
|
60
|
+
"Sendmail",
|
|
61
|
+
"Qmail",
|
|
62
|
+
"Exchange"
|
|
63
|
+
],
|
|
64
|
+
"SMTPS": [
|
|
65
|
+
"SMTPS",
|
|
66
|
+
"465 secure",
|
|
67
|
+
"587 secure"
|
|
68
|
+
// Some servers might mention "TLS wrapper" or similar
|
|
69
|
+
],
|
|
70
|
+
"POP3": [
|
|
71
|
+
"POP3",
|
|
72
|
+
"Dovecot",
|
|
73
|
+
"Courier",
|
|
74
|
+
"POP3 (Internet Mail)"
|
|
75
|
+
],
|
|
76
|
+
"POP3S": [
|
|
77
|
+
"POP3S",
|
|
78
|
+
"SSL POP3",
|
|
79
|
+
"Dovecot",
|
|
80
|
+
"Courier"
|
|
81
|
+
],
|
|
82
|
+
"IMAP": [
|
|
83
|
+
"IMAP",
|
|
84
|
+
"Dovecot",
|
|
85
|
+
"Courier",
|
|
86
|
+
"Cyrus",
|
|
87
|
+
"IMAP4"
|
|
88
|
+
],
|
|
89
|
+
"IMAPS": [
|
|
90
|
+
"IMAPS",
|
|
91
|
+
"SSL IMAP",
|
|
92
|
+
"Dovecot",
|
|
93
|
+
"Courier",
|
|
94
|
+
"Cyrus"
|
|
95
|
+
],
|
|
96
|
+
|
|
97
|
+
// ---------------- Domain / Directory Services ---------------
|
|
98
|
+
"DNS": [
|
|
99
|
+
"DNS",
|
|
100
|
+
"Bind",
|
|
101
|
+
"DNSMasq",
|
|
102
|
+
"PowerDNS",
|
|
103
|
+
"Unbound",
|
|
104
|
+
"Microsoft DNS",
|
|
105
|
+
"Knot DNS"
|
|
106
|
+
],
|
|
107
|
+
"LDAP": [
|
|
108
|
+
"LDAP"
|
|
109
|
+
],
|
|
110
|
+
"Active Directory": [
|
|
111
|
+
"Active Directory",
|
|
112
|
+
"Kerberos",
|
|
113
|
+
"MSAD",
|
|
114
|
+
"LDAP for AD",
|
|
115
|
+
"LDAP Service (AD)"
|
|
116
|
+
],
|
|
117
|
+
|
|
118
|
+
// -------------------- Database Services ----------------------
|
|
119
|
+
"MySQL": [
|
|
120
|
+
"MySQL",
|
|
121
|
+
"MariaDB",
|
|
122
|
+
"Percona"
|
|
123
|
+
],
|
|
124
|
+
"PostgreSQL": [
|
|
125
|
+
"PostgreSQL",
|
|
126
|
+
"Postgres"
|
|
127
|
+
],
|
|
128
|
+
"Microsoft SQL Server": [
|
|
129
|
+
"MSSQL",
|
|
130
|
+
"Microsoft SQL Server",
|
|
131
|
+
"TDS",
|
|
132
|
+
"SQL Server",
|
|
133
|
+
"MS-SQL"
|
|
134
|
+
],
|
|
135
|
+
"Oracle Database": [
|
|
136
|
+
"Oracle",
|
|
137
|
+
"TNS",
|
|
138
|
+
"Oracle Net"
|
|
139
|
+
],
|
|
140
|
+
"MongoDB": [
|
|
141
|
+
"MongoDB"
|
|
142
|
+
],
|
|
143
|
+
"Redis": [
|
|
144
|
+
"Redis"
|
|
145
|
+
],
|
|
146
|
+
"Cassandra": [
|
|
147
|
+
"Cassandra"
|
|
148
|
+
],
|
|
149
|
+
"Memcached": [
|
|
150
|
+
"Memcached"
|
|
151
|
+
],
|
|
152
|
+
|
|
153
|
+
// ----------------- Caching / Indexing / Logging -------------
|
|
154
|
+
"Elasticsearch": [
|
|
155
|
+
"Elasticsearch"
|
|
156
|
+
],
|
|
157
|
+
"Logstash": [
|
|
158
|
+
"Logstash"
|
|
159
|
+
],
|
|
160
|
+
|
|
161
|
+
// --------------- Message Brokers & Streaming ----------------
|
|
162
|
+
"Kafka": [
|
|
163
|
+
"Kafka"
|
|
164
|
+
],
|
|
165
|
+
"RabbitMQ": [
|
|
166
|
+
"RabbitMQ",
|
|
167
|
+
"AMQP"
|
|
168
|
+
],
|
|
169
|
+
"ActiveMQ": [
|
|
170
|
+
"ActiveMQ"
|
|
171
|
+
],
|
|
172
|
+
"Mosquitto": [
|
|
173
|
+
"Mosquitto",
|
|
174
|
+
"MQTT"
|
|
175
|
+
],
|
|
176
|
+
|
|
177
|
+
// -------------------- Microsoft Services ---------------------
|
|
178
|
+
"RDP": [
|
|
179
|
+
"RDP",
|
|
180
|
+
"Terminal Services",
|
|
181
|
+
"Remote Desktop",
|
|
182
|
+
"MSTerminal"
|
|
183
|
+
],
|
|
184
|
+
"SMB": [
|
|
185
|
+
"SMB",
|
|
186
|
+
"NetBIOS",
|
|
187
|
+
"Samba"
|
|
188
|
+
],
|
|
189
|
+
"WMI": [
|
|
190
|
+
"WMI"
|
|
191
|
+
],
|
|
192
|
+
"WinRM": [
|
|
193
|
+
"WinRM"
|
|
194
|
+
],
|
|
195
|
+
|
|
196
|
+
// ---------------- Collaboration / Chat -----------------------
|
|
197
|
+
"IRC": [
|
|
198
|
+
"IRC"
|
|
199
|
+
],
|
|
200
|
+
"XMPP": [
|
|
201
|
+
"XMPP",
|
|
202
|
+
"Jabber"
|
|
203
|
+
],
|
|
204
|
+
"Matrix": [
|
|
205
|
+
"Matrix"
|
|
206
|
+
],
|
|
207
|
+
|
|
208
|
+
// ------------- Virtualization / Container Services ----------
|
|
209
|
+
"Docker API": [
|
|
210
|
+
"Docker"
|
|
211
|
+
],
|
|
212
|
+
"Kubernetes API": [
|
|
213
|
+
"Kubernetes",
|
|
214
|
+
"K8s",
|
|
215
|
+
"kube-apiserver"
|
|
216
|
+
],
|
|
217
|
+
"VMware ESXi": [
|
|
218
|
+
"VMware ESXi",
|
|
219
|
+
"ESX"
|
|
220
|
+
],
|
|
221
|
+
"Proxmox": [
|
|
222
|
+
"Proxmox"
|
|
223
|
+
],
|
|
224
|
+
|
|
225
|
+
// ----------------- Remote Desktop / Control -----------------
|
|
226
|
+
"VNC": [
|
|
227
|
+
"VNC",
|
|
228
|
+
"RFB"
|
|
229
|
+
],
|
|
230
|
+
"TeamViewer": [
|
|
231
|
+
"TeamViewer"
|
|
232
|
+
],
|
|
233
|
+
"AnyDesk": [
|
|
234
|
+
"AnyDesk"
|
|
235
|
+
],
|
|
236
|
+
|
|
237
|
+
// --------------------- Voice over IP ------------------------
|
|
238
|
+
"SIP": [
|
|
239
|
+
"SIP",
|
|
240
|
+
"Asterisk",
|
|
241
|
+
"FreeSWITCH"
|
|
242
|
+
],
|
|
243
|
+
"H.323": [
|
|
244
|
+
"H.323"
|
|
245
|
+
],
|
|
246
|
+
|
|
247
|
+
// ----------- Time, Network Config, and Infrastructure -------
|
|
248
|
+
"NTP": [
|
|
249
|
+
"NTP"
|
|
250
|
+
],
|
|
251
|
+
"DHCP": [
|
|
252
|
+
"DHCP"
|
|
253
|
+
],
|
|
254
|
+
|
|
255
|
+
// ------------------ VPN / Tunneling / Security --------------
|
|
256
|
+
"OpenVPN": [
|
|
257
|
+
"OpenVPN"
|
|
258
|
+
],
|
|
259
|
+
"IPSec": [
|
|
260
|
+
"IPSec",
|
|
261
|
+
"IKE"
|
|
262
|
+
],
|
|
263
|
+
"WireGuard": [
|
|
264
|
+
"WireGuard"
|
|
265
|
+
],
|
|
266
|
+
|
|
267
|
+
// ---------------------- Other Protocols ----------------------
|
|
268
|
+
"SNMP": [
|
|
269
|
+
"SNMP"
|
|
270
|
+
],
|
|
271
|
+
"SNMP Trap": [
|
|
272
|
+
"Trap",
|
|
273
|
+
"SNMPTRAP"
|
|
274
|
+
],
|
|
275
|
+
"Syslog": [
|
|
276
|
+
"Syslog"
|
|
277
|
+
],
|
|
278
|
+
|
|
279
|
+
// -------------------- Cloud Services / APIs -----------------
|
|
280
|
+
"AWS S3": [
|
|
281
|
+
"AmazonS3",
|
|
282
|
+
"S3"
|
|
283
|
+
],
|
|
284
|
+
"AWS RDS": [
|
|
285
|
+
"AWS RDS",
|
|
286
|
+
"amazon-rds"
|
|
287
|
+
],
|
|
288
|
+
"Azure DevOps": [
|
|
289
|
+
"Azure DevOps",
|
|
290
|
+
"VSTS"
|
|
291
|
+
],
|
|
292
|
+
"GCP Services": [
|
|
293
|
+
"GCP",
|
|
294
|
+
"googleapis.com"
|
|
295
|
+
],
|
|
296
|
+
|
|
297
|
+
// -------------------- Repo / Code Hosting --------------------
|
|
298
|
+
"Git": [
|
|
299
|
+
"git-daemon"
|
|
300
|
+
],
|
|
301
|
+
"SVN": [
|
|
302
|
+
"SVN",
|
|
303
|
+
"Subversion"
|
|
304
|
+
],
|
|
305
|
+
|
|
306
|
+
// -------------- HPC / Cluster Management / HPC --------------
|
|
307
|
+
"Slurm": [
|
|
308
|
+
"Slurm"
|
|
309
|
+
],
|
|
310
|
+
|
|
311
|
+
// --------------------- Misc / Exotic ------------------------
|
|
312
|
+
"Tor": [
|
|
313
|
+
"Tor",
|
|
314
|
+
"obfs"
|
|
315
|
+
],
|
|
316
|
+
"ZeroTier": [
|
|
317
|
+
"ZeroTier"
|
|
318
|
+
],
|
|
319
|
+
"Mumble": [
|
|
320
|
+
"Mumble",
|
|
321
|
+
"Murmur"
|
|
322
|
+
],
|
|
323
|
+
"Spice": [
|
|
324
|
+
"SPICE protocol"
|
|
325
|
+
],
|
|
326
|
+
"FusionDirectory": [
|
|
327
|
+
"FusionDirectory"
|
|
328
|
+
],
|
|
329
|
+
"Jenkins": [
|
|
330
|
+
"Jenkins"
|
|
331
|
+
],
|
|
332
|
+
"GitLab": [
|
|
333
|
+
"GitLab"
|
|
334
|
+
],
|
|
335
|
+
"GitHub": [
|
|
336
|
+
"GitHub",
|
|
337
|
+
"github.com"
|
|
338
|
+
],
|
|
339
|
+
"Bitbucket": [
|
|
340
|
+
"Bitbucket"
|
|
341
|
+
],
|
|
342
|
+
|
|
343
|
+
// ------------------ Legacy or Older Protocols ---------------
|
|
344
|
+
"Gopher": [
|
|
345
|
+
"Gopher"
|
|
346
|
+
],
|
|
347
|
+
"Finger": [
|
|
348
|
+
"Finger"
|
|
349
|
+
],
|
|
350
|
+
"Ident": [
|
|
351
|
+
"Ident"
|
|
352
|
+
],
|
|
353
|
+
"Rlogin": [
|
|
354
|
+
"rlogin"
|
|
355
|
+
],
|
|
356
|
+
"Rsync": [
|
|
357
|
+
"rsync"
|
|
358
|
+
],
|
|
359
|
+
"UUCP": [
|
|
360
|
+
"UUCP"
|
|
361
|
+
],
|
|
362
|
+
"AFS": [
|
|
363
|
+
"AFS",
|
|
364
|
+
"OpenAFS"
|
|
365
|
+
],
|
|
366
|
+
"NIS": [
|
|
367
|
+
"NIS",
|
|
368
|
+
"YPServ"
|
|
369
|
+
],
|
|
370
|
+
"Telnet SSL": [
|
|
371
|
+
"telnet-ssl"
|
|
372
|
+
],
|
|
373
|
+
|
|
374
|
+
// ----------------- Big Data / Hadoop Ecosystem --------------
|
|
375
|
+
"Hadoop": [
|
|
376
|
+
"Hadoop",
|
|
377
|
+
"MapReduce",
|
|
378
|
+
"YARN"
|
|
379
|
+
],
|
|
380
|
+
"HDFS": [
|
|
381
|
+
"HDFS"
|
|
382
|
+
],
|
|
383
|
+
"Hive": [
|
|
384
|
+
"Hive",
|
|
385
|
+
"HiveServer2"
|
|
386
|
+
],
|
|
387
|
+
"HBase": [
|
|
388
|
+
"HBase",
|
|
389
|
+
"HMaster"
|
|
390
|
+
],
|
|
391
|
+
"Zookeeper": [
|
|
392
|
+
"Zookeeper",
|
|
393
|
+
"ZooKeeper"
|
|
394
|
+
],
|
|
395
|
+
"Spark": [
|
|
396
|
+
"Spark"
|
|
397
|
+
],
|
|
398
|
+
|
|
399
|
+
// ------------ Web Frameworks / Application Servers ----------
|
|
400
|
+
"Tomcat": [
|
|
401
|
+
"Apache Tomcat",
|
|
402
|
+
"Apache-Coyote"
|
|
403
|
+
],
|
|
404
|
+
"JBoss": [
|
|
405
|
+
"JBoss",
|
|
406
|
+
"JBoss EAP"
|
|
407
|
+
],
|
|
408
|
+
"GlassFish": [
|
|
409
|
+
"GlassFish"
|
|
410
|
+
],
|
|
411
|
+
"WebLogic": [
|
|
412
|
+
"WebLogic"
|
|
413
|
+
],
|
|
414
|
+
"WebSphere": [
|
|
415
|
+
"WebSphere"
|
|
416
|
+
],
|
|
417
|
+
"Jetty": [
|
|
418
|
+
"Jetty"
|
|
419
|
+
],
|
|
420
|
+
// Gunicorn and uWSGI also appear under HTTP if they surface in the banner.
|
|
421
|
+
|
|
422
|
+
// ------- Additional Container / Orchestration Tools ---------
|
|
423
|
+
"Docker Swarm": [
|
|
424
|
+
"Swarm"
|
|
425
|
+
],
|
|
426
|
+
|
|
427
|
+
// ---------- Reverse Proxies / Load Balancers / Gateways -----
|
|
428
|
+
"HAProxy": [
|
|
429
|
+
"HAProxy"
|
|
430
|
+
],
|
|
431
|
+
"Traefik": [
|
|
432
|
+
"Traefik"
|
|
433
|
+
],
|
|
434
|
+
"Envoy": [
|
|
435
|
+
"Envoy"
|
|
436
|
+
],
|
|
437
|
+
|
|
438
|
+
// ------------------ CI/CD and DevOps Tools ------------------
|
|
439
|
+
"Bamboo": [
|
|
440
|
+
"Bamboo"
|
|
441
|
+
],
|
|
442
|
+
"TeamCity": [
|
|
443
|
+
"TeamCity"
|
|
444
|
+
],
|
|
445
|
+
"Drone CI": [
|
|
446
|
+
"Drone"
|
|
447
|
+
],
|
|
448
|
+
|
|
449
|
+
// ------------------- Just for completeness ------------------
|
|
450
|
+
"COBOL-based service": [
|
|
451
|
+
"Mainframe",
|
|
452
|
+
"AS/400",
|
|
453
|
+
// Banner might mention "Enterprise COBOL" or "z/OS"
|
|
454
|
+
"z/OS"
|
|
455
|
+
]
|
|
456
|
+
}
|
|
@@ -35,6 +35,8 @@ def get_scan(scan_id):
|
|
|
35
35
|
@api_bp.route('/api/scan/<scan_id>/summary',methods=['GET'])
|
|
36
36
|
def get_scan_summary(scan_id):
|
|
37
37
|
scan = scan_manager.get_scan(scan_id)
|
|
38
|
+
if not scan:
|
|
39
|
+
return jsonify({'error':'scan not found'}), 404
|
|
38
40
|
return jsonify({
|
|
39
41
|
'running': scan.running,
|
|
40
42
|
'percent_complete': scan.calc_percent_complete(),
|
|
@@ -164,7 +164,6 @@ function pollScanSummary(id) {
|
|
|
164
164
|
if (summary.running || summary.stage == 'terminating') {
|
|
165
165
|
progress.css('height','2px');
|
|
166
166
|
progress.css('width',`${summary.percent_complete}vw`);
|
|
167
|
-
// TODO: move overview here??
|
|
168
167
|
setTimeout(() => {pollScanSummary(id)},500);
|
|
169
168
|
} else {
|
|
170
169
|
progress.css('width','100vw');
|
|
@@ -179,6 +178,11 @@ function pollScanSummary(id) {
|
|
|
179
178
|
},1000);
|
|
180
179
|
}
|
|
181
180
|
updateOverviewUI(summary);
|
|
181
|
+
}).fail(function(req) {
|
|
182
|
+
if (req === 404) {
|
|
183
|
+
console.log('Scan not found, redirecting to home');
|
|
184
|
+
window.location.href = '/';
|
|
185
|
+
}
|
|
182
186
|
});
|
|
183
187
|
}
|
|
184
188
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: lanscape
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.9a2
|
|
4
4
|
Summary: A python based local network scanner
|
|
5
5
|
Author-email: Michael Dennis <michael@dipduo.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/mdennis281/py-lanscape
|
|
@@ -18,6 +18,7 @@ src/lanscape/libraries/mac_lookup.py
|
|
|
18
18
|
src/lanscape/libraries/net_tools.py
|
|
19
19
|
src/lanscape/libraries/port_manager.py
|
|
20
20
|
src/lanscape/libraries/runtime_args.py
|
|
21
|
+
src/lanscape/libraries/service_scan.py
|
|
21
22
|
src/lanscape/libraries/subnet_scan.py
|
|
22
23
|
src/lanscape/libraries/version_manager.py
|
|
23
24
|
src/lanscape/resources/mac_addresses/convert_csv.py
|
|
@@ -27,6 +28,7 @@ src/lanscape/resources/ports/full.json
|
|
|
27
28
|
src/lanscape/resources/ports/large.json
|
|
28
29
|
src/lanscape/resources/ports/medium.json
|
|
29
30
|
src/lanscape/resources/ports/small.json
|
|
31
|
+
src/lanscape/resources/services/definitions.jsonc
|
|
30
32
|
src/lanscape/tests/__init__.py
|
|
31
33
|
src/lanscape/tests/_helpers.py
|
|
32
34
|
src/lanscape/tests/test_api.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/static/img/ico/android-chrome-192x192.png
RENAMED
|
File without changes
|
{lanscape-1.2.9a1 → lanscape-1.2.9a2}/src/lanscape/ui/static/img/ico/android-chrome-512x512.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|