-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Enhance CLI help output with usage examples #1446
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
2a25a98
ad5461b
249b8fc
eea1fbe
634964e
7493c00
753f5a8
1274969
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -21,14 +21,14 @@ OWASP Nettacker | |||||||||||||||
| OWASP Nettacker is an open-source, Python-based automated penetration testing and information-gathering framework designed to help cyber security professionals and ethical hackers perform reconnaissance, vulnerability assessments, and network security audits efficiently. Nettacker automates tasks like port scanning, service detection, subdomain enumeration, network mapping, vulnerability scanning, credential brute-force testing making it a powerful tool for identifying weaknesses in networks, web applications, IoT devices and APIs. | ||||||||||||||||
|
|
||||||||||||||||
| ### Key Features | ||||||||||||||||
|
|
||||||||||||||||
| - **Modular architecture** - Each task — like port scanning, directory discovery, subdomain enumeration, vulnerability checks, or credential brute-forcing - is implemented as its own module, giving you control over what runs. | ||||||||||||||||
| - **Multi-protocol & multithreaded scanning** - Supports HTTP/HTTPS, FTP, SSH, SMB, SMTP, ICMP, TELNET, XML-RPC, and can run scans in parallel for speed. | ||||||||||||||||
| - **Comprehensive output** - Export reports in HTML, JSON, CSV, and plain text. | ||||||||||||||||
| - **Built-in database & drift detection** - Stores past scans in the database for easy search and comparison with current results: useful to detect new hosts, open ports, or vulnerabilities in CI/CD pipelines. | ||||||||||||||||
| - **CLI, REST API & Web UI** - Offers both programmatic integration and a user-friendly web interface for defining scans and viewing results. | ||||||||||||||||
| - **Evasion techniques** - Enables configurable delays, proxy support, and randomized user-agents to reduce detection by firewalls or IDS systems. | ||||||||||||||||
| - **Flexible targets** - Accepts single IPv4s, IP ranges, CIDR blocks, domain names, and full HTTP/HTTPS URLs. Targets can be mixed in a single command or loaded from a file using the `-l/--targets-list` flag. | ||||||||||||||||
| - **Flexible targets**: Accepts single IPv4s, IP ranges, CIDR blocks, domain names, and full HTTP/HTTPS URLs. | ||||||||||||||||
| These methods ensure full compatibility and avoid runtime errors | ||||||||||||||||
|
Comment on lines
+30
to
+31
|
||||||||||||||||
| - **Flexible targets**: Accepts single IPv4s, IP ranges, CIDR blocks, domain names, and full HTTP/HTTPS URLs. | |
| These methods ensure full compatibility and avoid runtime errors | |
| - **Flexible targets**: Accepts single IPv4s, IP ranges, CIDR blocks, domain names, and full HTTP/HTTPS URLs, helping avoid target-parsing errors across different input formats. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keep the explanation inside the list item.
Line 31 is not indented as a continuation of the bullet, so GitHub renders it as a separate paragraph instead of part of Flexible targets.
📝 Suggested fix
- **Flexible targets**: Accepts single IPv4s, IP ranges, CIDR blocks, domain names, and full HTTP/HTTPS URLs.
-These methods ensure full compatibility and avoid runtime errors
+ These methods ensure full compatibility and avoid runtime errors.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - **Flexible targets**: Accepts single IPv4s, IP ranges, CIDR blocks, domain names, and full HTTP/HTTPS URLs. | |
| These methods ensure full compatibility and avoid runtime errors | |
| - **Flexible targets**: Accepts single IPv4s, IP ranges, CIDR blocks, domain names, and full HTTP/HTTPS URLs. | |
| These methods ensure full compatibility and avoid runtime errors. |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@README.md` around lines 30 - 31, The continuation text for the "Flexible
targets" bullet is on its own line and not indented, so GitHub renders it as a
separate paragraph; update the README so the continuation is part of the same
list item by either appending the sentence to the same line as "**Flexible
targets**: Accepts ..." or indenting the following line by two spaces (or adding
a trailing two-space line break on the previous line) so the sentence remains
inside the bullet; locate the "**Flexible targets**" list item in README.md and
adjust the following line accordingly.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,6 +1,7 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import difflib | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import json | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import sys | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from argparse import ArgumentParser | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from argparse import ArgumentParser, RawTextHelpFormatter | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import yaml | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -26,7 +27,27 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| class ArgParser(ArgumentParser): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def __init__(self, api_arguments=None) -> None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| super().__init__(prog="Nettacker", add_help=False) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| super().__init__( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| prog="Nettacker", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description=_("OWASP Nettacker - Automated Penetration Testing Framework"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| epilog=(""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Examples: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Scan a target: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| python nettacker.py -i 192.168.1.1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Scan multiple targets: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| python nettacker.py -l targets.txt | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Run specific module: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| python nettacker.py -i example.com -m port_scan | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Show all modules: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| python nettacker.py --show-all-modules | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+37
to
+46
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| python nettacker.py -i 192.168.1.1 | |
| Scan multiple targets: | |
| python nettacker.py -l targets.txt | |
| Run specific module: | |
| python nettacker.py -i example.com -m port_scan | |
| Show all modules: | |
| python nettacker.py --show-all-modules | |
| nettacker -i 192.168.1.1 | |
| Scan multiple targets: | |
| nettacker -l targets.txt | |
| Run specific module: | |
| nettacker -i example.com -m port_scan | |
| Show all modules: | |
| nettacker --show-all-modules |
Copilot
AI
Mar 24, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because RawTextHelpFormatter preserves all whitespace, the current triple-quoted epilog will render with the leading indentation shown in the source (and the example headings aren’t consistently aligned). Using a dedented string (e.g., via textwrap.dedent) and consistent indentation will make the help output cleaner.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unrelated to what you're trying to do. Please remove this as this is not needed as well, argparser handles all the below.
Copilot
AI
Mar 24, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
parse_known_args() returns any values following an unknown option in unknown_args as separate tokens (e.g., --bad value => ['--bad','value']), so iterating and erroring per-token can produce misleading extra "Unexpected argument" messages. Consider detecting unknown option/value pairs (or delegating to ArgumentParser.error() after computing a suggestion) so the user gets a single accurate error for the unknown flag.
Copilot
AI
Mar 24, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unknown short options like -Z currently fall into the "Unexpected argument" branch, which is misleading (they’re still unknown options). Consider treating any token starting with - as an unknown option (and optionally suggesting close matches for short flags too). Also, using die_failure(...) (or self.error(...)) instead of print/sys.exit would keep error handling consistent with the rest of the CLI (logging + color reset).
| for arg in unknown_args: | |
| if arg.startswith("--") and len(arg) > 1: | |
| suggestion = difflib.get_close_matches(arg, valid_flags, n=1) | |
| if suggestion: | |
| print( | |
| f"Error: Unknown argument '{arg}'. Did you mean '{suggestion[0]}'?", | |
| file=sys.stderr, | |
| ) | |
| else: | |
| print(f"Error: Unknown argument '{arg}'", file=sys.stderr) | |
| else: | |
| print(f"Error: Unexpected argument '{arg}'", file=sys.stderr) | |
| sys.exit(1) | |
| error_messages = [] | |
| for arg in unknown_args: | |
| if arg.startswith("-") and len(arg) > 1: | |
| suggestion = difflib.get_close_matches(arg, valid_flags, n=1) | |
| if suggestion: | |
| error_messages.append( | |
| f"Error: Unknown option '{arg}'. Did you mean '{suggestion[0]}'?" | |
| ) | |
| else: | |
| error_messages.append(f"Error: Unknown option '{arg}'") | |
| else: | |
| error_messages.append(f"Error: Unexpected argument '{arg}'") | |
| die_failure("\n".join(error_messages)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Treat an unknown option and its value as one error.
A typo on an option that takes a value currently produces two diagnostics: one for the bad flag and a second Unexpected argument ... for its value. That makes a single parse mistake look like multiple failures. Please collapse those tokens into one error and send it through the normal CLI failure path.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@nettacker/core/arg_parser.py` around lines 547 - 565, Unknown option tokens
and their following values are reported as two errors; update the unknown_args
handling so when you see an unknown flag token (arg.startswith("--") and
len(arg) > 1) you treat a non-flag next token as its value and skip it, emitting
a single error message (use the same stderr message and path currently used,
then sys.exit(1) or the parser's normal failure mechanism). Concretely, in the
block that iterates unknown_args (and uses self._actions and
difflib.get_close_matches) check the next element in unknown_args: if it exists
and does not start with "-" treat it as the value for the current unknown flag
and advance the loop one extra step so only one diagnostic is printed for the
pair. Ensure suggestion logic (difflib.get_close_matches) still applies to the
flag token only.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are you deleting a perfectly valid documentation line to squeeze in an advertisement for your proposal?