Skip to content

Commit 7932d63

Browse files
authored
added shell completion support via argcomplete (#98)
furthermore, added missing psutil dependency to pyproject.toml
1 parent e1a5d44 commit 7932d63

File tree

6 files changed

+74
-20
lines changed

6 files changed

+74
-20
lines changed

Coercer.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/usr/bin/env python3
22
# -*- coding: utf-8 -*-
3+
# PYTHON_ARGCOMPLETE_OK
34
# File name : Coercer.py
45
# Author : Podalirius (@podalirius_)
56
# Date created : 20 Sep 2022

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ You can now install it from pypi (latest version is <img alt="PyPI" src="https:/
3838
sudo python3 -m pip install coercer
3939
```
4040

41+
### Shell Completions
42+
43+
Coercer uses [argcomplete](https://github.com/kislyuk/argcomplete) to autogenerate tab completions for your shell (bash, zsh, fish, ...).
44+
See the `argcomplete` README for how to enable tab completions.
45+
4146
## Quick start
4247

4348
- You want to **assess** the Remote Procedure Calls listening on a machine to see if they can be leveraged to coerce an authentication?
@@ -49,7 +54,7 @@ sudo python3 -m pip install coercer
4954
+ Use [**coerce** mode](./documentation/Coerce-mode.md), example:
5055

5156
https://user-images.githubusercontent.com/79218792/204372851-4ba461ed-6812-4057-829d-0af6a06b0ecc.mp4
52-
57+
5358
- You are doing **research** and want to fuzz Remote Procedure Calls listening on a machine with various paths?
5459
+ Use [**fuzz** mode](./documentation/Fuzz-mode.md), example:
5560

coercer/__main__.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/usr/bin/env python3
22
# -*- coding: utf-8 -*-
3+
# PYTHON_ARGCOMPLETE_OK
34
# File name : __main__.py
45
# Author : Podalirius (@podalirius_)
56
# Date created : 17 Sep 2022
@@ -9,6 +10,7 @@
910
import os
1011
import sys
1112
import threading
13+
import argcomplete
1214
from sectools.network.domains import is_fqdn
1315
from sectools.network.ip import is_ipv4_cidr, is_ipv4_addr, is_ipv6_addr, expand_cidr, expand_port_range
1416

@@ -46,7 +48,7 @@ def parseArgs():
4648
mode_scan_advanced_config.add_argument("--smb-port", default=445, type=int, help="SMB port (default: 445)")
4749
mode_scan_advanced_config.add_argument("--dce-port", default=135, type=int, help="DCERPC port (default: 135)")
4850
mode_scan_advanced_config.add_argument("--dce-ports", default=[], nargs='+', type=int, help="DCERPC ports")
49-
mode_scan_advanced_config.add_argument("--auth-type", default=None, type=str, help="Desired authentication type ('smb' or 'http').")
51+
mode_scan_advanced_config.add_argument("--auth-type", default=None, type=str, choices=('smb', 'http'), help="Desired authentication type.")
5052
mode_scan_advanced_config.add_argument("--stop-on-ntlm-auth", default=False, action="store_true", help="Move on to next target on successful NTLM authentication.")
5153
# Filters
5254
mode_scan_filters = mode_scan.add_argument_group("Filtering")
@@ -93,7 +95,7 @@ def parseArgs():
9395
mode_fuzz_advanced_config.add_argument("--smb-port", default=445, type=int, help="SMB port (default: 445)")
9496
mode_fuzz_advanced_config.add_argument("--dce-port", default=135, type=int, help="DCERPC port (default: 135)")
9597
mode_fuzz_advanced_config.add_argument("--dce-ports", default=[], nargs='+', type=int, help="DCERPC ports")
96-
mode_fuzz_advanced_config.add_argument("--auth-type", default=None, type=str, help="Desired authentication type ('smb' or 'http').")
98+
mode_fuzz_advanced_config.add_argument("--auth-type", default=None, type=str, choices=('smb', 'http'), help="Desired authentication type.")
9799
# Filters
98100
mode_fuzz_filters = mode_fuzz.add_argument_group("Filtering")
99101
mode_fuzz_filters.add_argument("--filter-method-name", default=[], action='append', type=str, help="Filter by method name")
@@ -122,7 +124,7 @@ def parseArgs():
122124
mode_fuzz_logging = mode_fuzz.add_argument_group("Logging")
123125
mode_fuzz_logging.add_argument("--minimum-log-level", default=0, help="Minimum logging level (integer).")
124126
mode_fuzz_logging.add_argument("--log-file", default=None, help="Path for the file to log to (enables logging).")
125-
127+
126128
# Creating the "coerce" subparser ==============================================================================================================
127129
mode_coerce = argparse.ArgumentParser(add_help=False)
128130
mode_coerce.add_argument("-v", "--verbose", default=False, action="store_true", help="Verbose mode (default: False)")
@@ -136,7 +138,7 @@ def parseArgs():
136138
mode_coerce_advanced_config.add_argument("--dce-port", default=135, type=int, help="DCERPC port (default: 135)")
137139
mode_coerce_advanced_config.add_argument("--dce-ports", default=[], nargs='+', type=int, help="DCERPC ports")
138140
mode_coerce_advanced_config.add_argument("--always-continue", default=False, action="store_true", help="Always continue to coerce")
139-
mode_coerce_advanced_config.add_argument("--auth-type", default=None, type=str, help="Desired authentication type ('smb' or 'http').")
141+
mode_coerce_advanced_config.add_argument("--auth-type", default=None, type=str, choices=('smb', 'http'), help="Desired authentication type.")
140142
# Filters
141143
mode_coerce_filters = mode_coerce.add_argument_group("Filtering")
142144
mode_coerce_filters.add_argument("--filter-method-name", default=[], action='append', type=str, help="Filter by method name")
@@ -165,13 +167,14 @@ def parseArgs():
165167
mode_coerce_logging = mode_coerce.add_argument_group("Logging")
166168
mode_coerce_logging.add_argument("--minimum-log-level", default=0, help="Minimum logging level (integer).")
167169
mode_coerce_logging.add_argument("--log-file", default=None, help="Path for the file to log to (enables logging).")
168-
170+
169171
# Adding the subparsers to the base parser
170172
subparsers = parser.add_subparsers(help="Mode", dest="mode", required=True)
171173
mode_scan_parser = subparsers.add_parser("scan", parents=[mode_scan], help="Tests known methods with known working paths on all methods, and report when an authentication is received.")
172-
mode_coerce_parser = subparsers.add_parser("coerce", parents=[mode_coerce], help="Trigger authentications through all known methods with known working paths")
174+
mode_coerce_parser = subparsers.add_parser("coerce", parents=[mode_coerce], help="Trigger authentications through all known methods with known working paths.")
173175
mode_fuzz_parser = subparsers.add_parser("fuzz", parents=[mode_fuzz], help="Tests every method with a list of exploit paths, and report when an authentication is received.")
174176

177+
argcomplete.autocomplete(parser, always_complete_options=False)
175178
options = parser.parse_args()
176179

177180
# Parsing hashes
@@ -245,15 +248,15 @@ def main():
245248
final_targets.append(target)
246249
else:
247250
reporter.print_warn("Target '%s' was not added." % target, debug=True)
248-
249-
# Sort
251+
252+
# Sort
250253
targets = sorted(list(set(final_targets)))
251254

252255
credentials = Credentials(
253-
username=options.username,
254-
password=options.password,
255-
domain=options.domain,
256-
lmhash=lmhash,
256+
username=options.username,
257+
password=options.password,
258+
domain=options.domain,
259+
lmhash=lmhash,
257260
nthash=nthash
258261
)
259262

poetry.lock

Lines changed: 47 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@ authors = [
99
{ name = "p0dalirius" }
1010
]
1111
dependencies = [
12+
"argcomplete",
1213
"impacket>=0.10.0",
1314
"xlsxwriter>=3.0.0",
1415
"jinja2>=3.1.3",
1516
"sectools>=1.4.3",
16-
"netifaces>=0.11.0"
17+
"netifaces>=0.11.0",
18+
"psutil",
1719
]
1820

1921
[project.scripts]

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
argcomplete
12
impacket
23
xlsxwriter
34
jinja2
45
sectools
56
netifaces
67
psutil
7-
pydivert; sys_platform == "win32"
8+
pydivert; sys_platform == "win32"

0 commit comments

Comments
 (0)