authfinder 1.0.1__py3-none-any.whl → 1.1.1__py3-none-any.whl
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.
- authfinder/__init__.py +2 -2
- authfinder/authfinder.py +37 -18
- {authfinder-1.0.1.dist-info → authfinder-1.1.1.dist-info}/METADATA +5 -3
- authfinder-1.1.1.dist-info/RECORD +8 -0
- authfinder-1.0.1.dist-info/RECORD +0 -8
- {authfinder-1.0.1.dist-info → authfinder-1.1.1.dist-info}/WHEEL +0 -0
- {authfinder-1.0.1.dist-info → authfinder-1.1.1.dist-info}/entry_points.txt +0 -0
- {authfinder-1.0.1.dist-info → authfinder-1.1.1.dist-info}/licenses/LICENSE +0 -0
- {authfinder-1.0.1.dist-info → authfinder-1.1.1.dist-info}/top_level.txt +0 -0
authfinder/__init__.py
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"""authfinder: Execute commands across Windows systems using multiple RCE methods"""
|
|
1
|
+
"""authfinder: Execute commands across Windows and Linux systems using multiple RCE methods"""
|
|
2
2
|
|
|
3
|
-
__version__ = "1.
|
|
3
|
+
__version__ = "1.1.1"
|
authfinder/authfinder.py
CHANGED
|
@@ -19,6 +19,7 @@ OUTPUT = False
|
|
|
19
19
|
RUN_ALL = False
|
|
20
20
|
SKIP_PORTSCAN = False
|
|
21
21
|
TOOLS_SPECIFIED = False
|
|
22
|
+
LINUX_MODE = False
|
|
22
23
|
|
|
23
24
|
VALID_TOOLS = ["winrm", "smbexec", "wmi", "ssh", "mssql", "psexec", "atexec", "rdp"]
|
|
24
25
|
NXC_TOOLS = {"smbexec", "wmi", "ssh", "rdp"}
|
|
@@ -235,6 +236,9 @@ def build_cmd(tool, user, target, credential, command):
|
|
|
235
236
|
f"{NXC_CMD} wmi {target} -p {credential} -u \"{user}\" -x 'powershell -enc {b64}'")
|
|
236
237
|
|
|
237
238
|
if tool == "ssh":
|
|
239
|
+
if LINUX_MODE:
|
|
240
|
+
b64 = base64.b64encode(command.encode("utf-8")).decode()
|
|
241
|
+
return f"{NXC_CMD} ssh {target} -p {credential} -u \"{user}\" -x 'echo {b64} | base64 -d | $0'{nxc_output_flag}"
|
|
238
242
|
return f"{NXC_CMD} ssh {target} -p {credential} -u \"{user}\" -x 'powershell -enc {b64}'{nxc_output_flag}"
|
|
239
243
|
|
|
240
244
|
if tool == "rdp":
|
|
@@ -327,6 +331,10 @@ def run_chain(user, ip, credential, command, tool_list=None):
|
|
|
327
331
|
else:
|
|
328
332
|
safe_print(f" [-] For {ip}: {tool} failed.")
|
|
329
333
|
continue
|
|
334
|
+
if tool == "ssh" and 'Linux - Shell' in out and not LINUX_MODE:
|
|
335
|
+
safe_print(f" \033[33m[!]\033[0m For {ip}: {tool} AUTHENTICATION succeeded as {user} with {credential}, but this seems like a Linux machine, so the command didn't run.")
|
|
336
|
+
safe_print(" \033[33m[!]\033[0m Use \033[33m--linux\033[0m to run command across Linux machines.")
|
|
337
|
+
continue
|
|
330
338
|
if '[+]' in out and 'Executed command' not in out:
|
|
331
339
|
safe_print(f" \033[33m[!]\033[0m For {ip}: {tool} AUTHENTICATION succeeded as {user} with {credential}, but seemingly failed to run command. Does the user have the necessary permissions?")
|
|
332
340
|
continue
|
|
@@ -410,6 +418,8 @@ def parse_args():
|
|
|
410
418
|
parser.add_argument("--skip-portscan", action="store_true", help="Skip port scanning and attempt all tools")
|
|
411
419
|
parser.add_argument("-f", "--file", metavar="CRED_FILE", help="Credential file (newline-separated user/password pairs)")
|
|
412
420
|
|
|
421
|
+
parser.add_argument("--linux", action="store_true", help="Linux-only mode - automates SSH, ignores other tools")
|
|
422
|
+
|
|
413
423
|
parser.add_argument("ip_range", help="IP range (e.g., 192.168.1.1-254)")
|
|
414
424
|
parser.add_argument("username", nargs="?", help="Username")
|
|
415
425
|
parser.add_argument("credential", nargs="?", help="Password or NT hash")
|
|
@@ -438,7 +448,7 @@ def check_dependencies():
|
|
|
438
448
|
IMPACKET_PREFIX = "impacket-"
|
|
439
449
|
elif r2:
|
|
440
450
|
IMPACKET_PREFIX = ""
|
|
441
|
-
|
|
451
|
+
elif not LINUX_MODE:
|
|
442
452
|
print("[-] impacket not found. Install with: pipx install impacket")
|
|
443
453
|
sys.exit(1)
|
|
444
454
|
|
|
@@ -465,7 +475,7 @@ def check_dependencies():
|
|
|
465
475
|
for d in os.listdir(base):
|
|
466
476
|
if d.endswith("@evil-winrm"):
|
|
467
477
|
WINRM_CMD = f"{base}/{d}/wrappers/evil-winrm"
|
|
468
|
-
if not WINRM_CMD:
|
|
478
|
+
if not WINRM_CMD and not LINUX_MODE:
|
|
469
479
|
print("[-] evil-winrm not found. Please install with gem install evil-winrm")
|
|
470
480
|
sys.exit(1)
|
|
471
481
|
|
|
@@ -476,7 +486,7 @@ def impacket_cmd(tool):
|
|
|
476
486
|
return f"{tool}.py"
|
|
477
487
|
|
|
478
488
|
def main():
|
|
479
|
-
global VERBOSE, OUTPUT, MAX_THREADS, EXEC_TIMEOUT, RUN_ALL, SKIP_PORTSCAN, TOOLS_SPECIFIED
|
|
489
|
+
global VERBOSE, OUTPUT, MAX_THREADS, EXEC_TIMEOUT, RUN_ALL, SKIP_PORTSCAN, TOOLS_SPECIFIED, LINUX_MODE
|
|
480
490
|
|
|
481
491
|
check_dependencies()
|
|
482
492
|
|
|
@@ -484,28 +494,17 @@ def main():
|
|
|
484
494
|
|
|
485
495
|
VERBOSE = args.v
|
|
486
496
|
OUTPUT = args.o
|
|
487
|
-
MAX_THREADS = args.threads
|
|
497
|
+
MAX_THREADS = args.threads if args.threads > 0 else 1
|
|
488
498
|
EXEC_TIMEOUT = args.timeout
|
|
489
499
|
RUN_ALL = args.run_all
|
|
490
500
|
SKIP_PORTSCAN = args.skip_portscan
|
|
491
|
-
|
|
492
|
-
if args.tools:
|
|
493
|
-
tool_list = parse_tools_list(args.tools)
|
|
494
|
-
TOOLS_SPECIFIED = True
|
|
495
|
-
print(f"[*] Using tools: {', '.join(tool_list)}")
|
|
496
|
-
else:
|
|
497
|
-
tool_list = None
|
|
498
|
-
|
|
499
|
-
if args.skip_portscan:
|
|
500
|
-
print("\033[33m[!] Port scanning disabled (--skip-portscan). All tools will be attempted.\033[0m")
|
|
501
|
-
|
|
502
|
-
command = " ".join(args.command) if args.command else "whoami"
|
|
501
|
+
LINUX_MODE = args.linux
|
|
503
502
|
|
|
504
503
|
if args.file:
|
|
505
504
|
credential_list = load_credential_file(args.file)
|
|
506
505
|
else:
|
|
507
506
|
credential_list = [(args.username, args.credential)]
|
|
508
|
-
|
|
507
|
+
|
|
509
508
|
if args.ip_range.endswith('.txt'):
|
|
510
509
|
ips = []
|
|
511
510
|
with open(args.ip_range) as f:
|
|
@@ -516,12 +515,32 @@ def main():
|
|
|
516
515
|
else:
|
|
517
516
|
ips = parse_ip_range(args.ip_range)
|
|
518
517
|
|
|
518
|
+
if len(ips) < MAX_THREADS and not args.threads:
|
|
519
|
+
MAX_THREADS = len(ips)
|
|
520
|
+
|
|
519
521
|
print(f"[*] Loaded {len(credential_list)} credential set(s)")
|
|
520
522
|
print(f"[*] Processing {len(ips)} IPs with {MAX_THREADS} threads...")
|
|
523
|
+
|
|
524
|
+
if args.linux:
|
|
525
|
+
if args.tools:
|
|
526
|
+
print("\033[31m[!] Tools (--tools) cannot be specified alongside Linux-mode (--linux), as only SSH is supported. Continuing with SSH...\033[0m")
|
|
527
|
+
args.tools = "ssh"
|
|
528
|
+
|
|
529
|
+
if args.tools:
|
|
530
|
+
tool_list = parse_tools_list(args.tools)
|
|
531
|
+
TOOLS_SPECIFIED = True
|
|
532
|
+
print(f"[*] Using tools: {', '.join(tool_list)}")
|
|
533
|
+
else:
|
|
534
|
+
tool_list = None
|
|
535
|
+
|
|
536
|
+
if args.skip_portscan:
|
|
537
|
+
print("\033[33m[!] Port scanning disabled (--skip-portscan). All tools will be attempted.\033[0m")
|
|
538
|
+
|
|
539
|
+
command = " ".join(args.command) if args.command else "whoami"
|
|
521
540
|
|
|
522
541
|
if not OUTPUT:
|
|
523
542
|
print("\033[33m[!] Output Disabled. Run with -o to see successful command output\033[0m")
|
|
524
|
-
|
|
543
|
+
elif not LINUX_MODE:
|
|
525
544
|
print("-" * 20)
|
|
526
545
|
print("\033[33m[!] WARNING: Output Enabled. This WILL trip AV for certain tools\033[0m")
|
|
527
546
|
print("-" * 20)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: authfinder
|
|
3
|
-
Version: 1.
|
|
4
|
-
Summary: Execute commands across Windows systems using multiple RCE methods (WinRM, SMB, WMI, RDP, SSH, MSSQL)
|
|
3
|
+
Version: 1.1.1
|
|
4
|
+
Summary: Execute commands across Windows and Linux systems using multiple RCE methods (WinRM, SMB, WMI, RDP, SSH, MSSQL)
|
|
5
5
|
Author: Khael
|
|
6
6
|
Project-URL: Homepage, https://github.com/KhaelK138/authfinder
|
|
7
7
|
Project-URL: Repository, https://github.com/KhaelK138/authfinder
|
|
@@ -28,7 +28,7 @@ Dynamic: license-file
|
|
|
28
28
|
|
|
29
29
|
# AuthFinder
|
|
30
30
|
|
|
31
|
-
A tool for executing commands across
|
|
31
|
+
A tool for executing commands across Windows (and Linux) systems using various remote execution methods. Automatically tries multiple techniques until one succeeds, based on return codes and output. Makes executing commands given credentials a hell of a lot easier.
|
|
32
32
|
|
|
33
33
|
Big thanks to NetExec, Impacket, and Evil-Winrm, as this tool just essentially acts as a wrapper around those (making it more of a script, I suppose).
|
|
34
34
|
|
|
@@ -45,6 +45,7 @@ Big thanks to NetExec, Impacket, and Evil-Winrm, as this tool just essentially a
|
|
|
45
45
|
- MSSQL (Impacket)
|
|
46
46
|
- **Multi-threaded**: Execute commands across multiple hosts simultaneously
|
|
47
47
|
- **Automatic Pass-the-Hash**: Just paste the NTLM hash as the credential
|
|
48
|
+
- **Linux Support**: Use `--linux` to attempt to run commands across linux machines instead, via SSH
|
|
48
49
|
|
|
49
50
|
## Installation
|
|
50
51
|
|
|
@@ -118,6 +119,7 @@ Options:
|
|
|
118
119
|
--timeout <seconds> Command timeout in seconds (default: 15)
|
|
119
120
|
--run-all Run all tools instead of stopping at first success
|
|
120
121
|
--skip-portscan Skip port scanning and attempt all tools
|
|
122
|
+
--linux Enables Linux-only mode, which uses SSH and ignores other tools
|
|
121
123
|
```
|
|
122
124
|
|
|
123
125
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
authfinder/__init__.py,sha256=Om82CgmeKmOaz2iYQPSeCKFnDTh3lMFxW6HBc7HRL38,121
|
|
2
|
+
authfinder/authfinder.py,sha256=NVamwMtuklt_TfRuT56VqAJ76uZaVhvIzGHSNqjBqvs,22675
|
|
3
|
+
authfinder-1.1.1.dist-info/licenses/LICENSE,sha256=Kw_kDNp7vsEauRb1Al1Urf1pe0EZWYB0HGK8PvT4FV0,1060
|
|
4
|
+
authfinder-1.1.1.dist-info/METADATA,sha256=-taNe3Gj_l-CAvOuFGr_CkdJk2PemGcGU9a8klNluQ8,4614
|
|
5
|
+
authfinder-1.1.1.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
|
|
6
|
+
authfinder-1.1.1.dist-info/entry_points.txt,sha256=9ChuQL6PNJlPHW_hSXvoFffcHCbpE0M8RHk8cz7yaIo,58
|
|
7
|
+
authfinder-1.1.1.dist-info/top_level.txt,sha256=tBEVwAMMMn0YcpoXt_lO1xiT-uznaCGrp7184swWocg,11
|
|
8
|
+
authfinder-1.1.1.dist-info/RECORD,,
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
authfinder/__init__.py,sha256=c8p5Dp-gq4c7FFrY7J2y5z8safxiJeQxfYyRfhd0XOY,111
|
|
2
|
-
authfinder/authfinder.py,sha256=7AiltrKyYMLdubdWfxtjthFQviIHhAnDWGA11nb5J9M,21471
|
|
3
|
-
authfinder-1.0.1.dist-info/licenses/LICENSE,sha256=Kw_kDNp7vsEauRb1Al1Urf1pe0EZWYB0HGK8PvT4FV0,1060
|
|
4
|
-
authfinder-1.0.1.dist-info/METADATA,sha256=iOuuyHEJLno_yhPIDkfezHQwpNmR-UYT9lph24P0RCY,4408
|
|
5
|
-
authfinder-1.0.1.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
|
|
6
|
-
authfinder-1.0.1.dist-info/entry_points.txt,sha256=9ChuQL6PNJlPHW_hSXvoFffcHCbpE0M8RHk8cz7yaIo,58
|
|
7
|
-
authfinder-1.0.1.dist-info/top_level.txt,sha256=tBEVwAMMMn0YcpoXt_lO1xiT-uznaCGrp7184swWocg,11
|
|
8
|
-
authfinder-1.0.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|