-
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathcli.py
More file actions
146 lines (118 loc) · 5.1 KB
/
Copy pathcli.py
File metadata and controls
146 lines (118 loc) · 5.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
"""Argparse entry + bootstrap."""
from __future__ import annotations
import argparse
import logging
import os
import sys
__version__ = "2.0.0-dev"
EPILOG = """\
examples:
sudo .venv/bin/snype
Launch the TUI with defaults.
sudo .venv/bin/snype -i wlan0 -I wlan1
Preconfigure both wireless interfaces and open the TUI.
sudo .venv/bin/snype -i wlan0 -b AA:BB:CC:DD:EE:FF -c 6 -e MyNet
Preselect a target and skip the scan view.
sudo .venv/bin/snype -t tmux
Force the tmux backend for the dual-terminal launcher.
sudo .venv/bin/snype --dry-run -v
Print every external command without running anything.
data layout:
./snype-data/ (override with -d or $SNYPE_DATA_DIR)
config.json interfaces + last target
hs/<ESSID>/<timestamp>/ per-session capture + meta.json
logs/snype.log application log
found_passwords.jsonl recovered keys
terminal backends (selected with -t):
auto xterm > tmux > PTY on desktop; tmux on NetHunter/Termux
xterm spawn a graphical terminal emulator (xterm/kitty/gnome/konsole)
tmux detached session with horizontal split
pty embedded PTY multiplexer (fallback, no external GUI needed)
"""
def build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(
prog="snype",
description="WPA handshake capture utility — TUI wrapper around aircrack-ng and hcxtools.",
epilog=EPILOG,
formatter_class=argparse.RawDescriptionHelpFormatter,
)
ifaces = parser.add_argument_group("interfaces")
ifaces.add_argument("-i", "--interface", metavar="IFACE",
help="primary interface (used for monitoring).")
ifaces.add_argument("-I", "--inject", metavar="IFACE",
help="secondary interface for injection (defaults to the primary one).")
target = parser.add_argument_group("target preselection")
target.add_argument("-b", "--bssid", metavar="MAC",
help="preselect a target BSSID.")
target.add_argument("-c", "--channel", metavar="N",
help="preselect a channel.")
target.add_argument("-e", "--essid", metavar="NAME",
help="preselect an ESSID (used for session naming).")
runtime = parser.add_argument_group("runtime")
runtime.add_argument("-d", "--data-dir", metavar="PATH",
help="override the data directory (default: ./snype-data). "
"Also read from $SNYPE_DATA_DIR.")
runtime.add_argument("-t", "--term-mode", choices=["auto", "xterm", "tmux", "pty"],
default="auto",
help="dual-terminal backend to use (default: auto).")
runtime.add_argument("--duration", type=int, default=10,
help="default duration, in seconds, for timed deauth attacks "
"(default: 10).")
runtime.add_argument("--dry-run", action="store_true",
help="print external commands without executing them.")
runtime.add_argument("-v", "--verbose", action="store_true",
help="enable verbose logging to snype-data/logs/snype.log.")
runtime.add_argument("--version", action="version",
version=f"snype {__version__}")
return parser
def configure_logging(paths, verbose: bool) -> None:
from core.paths import ensure_private_file
paths.ensure()
log_path = ensure_private_file(paths.logs / "snype.log")
level = logging.DEBUG if verbose else logging.INFO
logging.basicConfig(
level=level,
format="%(asctime)s %(levelname)s %(name)s: %(message)s",
handlers=[
logging.FileHandler(log_path, encoding="utf-8"),
logging.StreamHandler(sys.stderr) if verbose else logging.NullHandler(),
],
)
def bootstrap(argv: list[str] | None = None) -> int:
args = build_parser().parse_args(argv)
if os.name == "posix":
os.umask(0o077)
from core import migrate
from core.config import Config, Target
from core.paths import build_paths
from tui.application import run_tui
from tui.state import AppState
paths = build_paths(args.data_dir).ensure()
configure_logging(paths, args.verbose)
actions = migrate.run(paths, verbose=args.verbose)
for line in actions:
logging.getLogger("snype.migrate").info(line)
config = Config.load(paths.config)
if args.interface:
config.monitor_iface = args.interface
if args.inject:
config.inject_iface = args.inject
if args.bssid:
config.target = Target(bssid=args.bssid, channel=args.channel, essid=args.essid)
if args.term_mode and args.term_mode != "auto":
config.term_mode = args.term_mode
config.save(paths.config)
state = AppState(
paths=paths,
config=config,
term_mode=args.term_mode,
dry_run=args.dry_run,
verbose=args.verbose,
)
for line in actions:
state.log(line)
try:
run_tui(state)
except KeyboardInterrupt:
return 130
return 0