diff --git a/IDEAS.md b/IDEAS.md index 10d22cb..2179adb 100644 --- a/IDEAS.md +++ b/IDEAS.md @@ -207,7 +207,7 @@ configuration is not set locally when `run` is executed, then the global configuration will be checked for matching arguments for the module. ```sh -# Install a persistence mthod with a bind channel +# Install a persistence method with a bind channel use persistence/system/cron set method channels/bind set schedule "* * */1 *" @@ -303,7 +303,7 @@ pwncat.victim.progress.status("Here's a status update", task=task) The progress bar itself will be managed by the `Victim` object. We can keep the standard now where iterative/generator based results are used to update a task, but also allows -modules to directly call `pwncat.victim.progres.status`. This would do away with the `Status` +modules to directly call `pwncat.victim.progress.status`. This would do away with the `Status` class. Further, it allows the `module.run` method to return the raw result of the underlying method allowing more flexibility in the return values of modules. It allows modules to have asynchronous (generator) return values. diff --git a/README.md b/README.md index ad76fa3..44d0469 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ for working with remote shells. - Disable history in the remote shell - Normalize shell prompt - Locate useful binaries (using `which`) -- Attempt to spawn a pseudoterminal (pty) for a full interactive session +- Attempt to spawn a pseudo-terminal (pty) for a full interactive session `pwncat` knows how to spawn pty's with a few different methods and will cross-reference the methods with the executables previously enumerated. After @@ -53,7 +53,7 @@ pwncat will take care of the rest. The libraries implementing the C2 are implemented at [pwncat-windows-c2]. The DLLs for the C2 will be automatically downloaded from the targeted release for you. If you do not have internet connectivity on your target machine, -you can tell pwncat to prestage the DLLs using the `--download-plugins` +you can tell pwncat to pre-stage the DLLs using the `--download-plugins` argument. If you are running a release version of pwncat, you can also download a tarball of all built-in plugins from the releases page. @@ -77,7 +77,7 @@ the `stable` version. The current `master` branch is `v0.4.3`. This version has overhauled a lot of the framework to support multiple platforms and -multisession environments. Documentation for this version is available +multi-session environments. Documentation for this version is available in the `latest` version on Read the Docs. **v0.3.1 will not be updated further** @@ -85,7 +85,7 @@ in the `latest` version on Read the Docs. ## Modules Recently, the architecture of the pwncat framework was redesigned to -encorporate a generic "module" structure. All functionality is now +incorporate a generic "module" structure. All functionality is now implemented as modules. This includes enumeration, persistence and privilege escalation. Interacting with modules is similar to most other post-exploitation platforms. You can utilize the familiar `run`, `search` @@ -156,7 +156,7 @@ pwncat -i id_rsa user@10.10.10.10 pwncat -p 2222 user@10.10.10.10 pwncat user@10.10.10.10:2222 # Reconnect utilizing installed persistence -# If reconnection failes and no protocol is specified, +# If reconnection fails and no protocol is specified, # SSH is used as a fallback. pwncat reconnect://user@10.10.10.10 pwncat reconnect://user@c228fc49e515628a0c13bdc4759a12bf diff --git a/pwncat/channel/__init__.py b/pwncat/channel/__init__.py index 4a1cbc8..23635f2 100644 --- a/pwncat/channel/__init__.py +++ b/pwncat/channel/__init__.py @@ -3,7 +3,7 @@ Channels represent the basic communication object within pwncat. Each channel abstracts a communication method with a target. By default, pwncat implements a few standard channels: socket bind/connect and ssh. -A channel largely mimicks a standard socket, however exact compatibility with +A channel largely mimics a standard socket, however exact compatibility with sockets was not the goal. Instead, it provides a low-level communication channel between the target and the attacker. Channels make no assumption about protocol of the C2 connection. This is the platform's job. diff --git a/pwncat/commands/__init__.py b/pwncat/commands/__init__.py index 3e01e89..594a06d 100644 --- a/pwncat/commands/__init__.py +++ b/pwncat/commands/__init__.py @@ -173,7 +173,7 @@ class Parameter: This class allows you to specify the syntax highlighting, tab completion and argparse settings for a command parameter in on go. The ``complete`` argument tells pwncat how to tab complete your argument. The ``token`` - argument is normally ommitted but can be used to change the pygments + argument is normally omitted but can be used to change the pygments syntax highlighting for your argument. All other arguments are passed directly to ``argparse`` when constructing the parser. diff --git a/pwncat/commands/connect.py b/pwncat/commands/connect.py index 2a8f9c4..cd36036 100644 --- a/pwncat/commands/connect.py +++ b/pwncat/commands/connect.py @@ -18,7 +18,7 @@ class Command(CommandDefinition): """ Connect to a remote victim. This command is only valid prior to an established connection. This command attempts to act similar to common tools such as netcat - and ssh simultaneosly. Connection strings come in two forms. Firstly, pwncat + and ssh simultaneously. Connection strings come in two forms. Firstly, pwncat can act like netcat. Using `connect [host] [port]` will connect to a bind shell, while `connect -l [port]` will listen for a reverse shell on the specified port. diff --git a/pwncat/commands/search.py b/pwncat/commands/search.py index c90ce9e..b83a6bc 100644 --- a/pwncat/commands/search.py +++ b/pwncat/commands/search.py @@ -36,7 +36,7 @@ class Command(CommandDefinition): ) for module in modules: - # Rich will ellipsize the column, but we need to squeze + # Rich will ellipsize the column, but we need to squeeze # white space and remove newlines. `textwrap.shorten` is # the easiest way to do that, so we use a large size for # width. diff --git a/pwncat/db.py b/pwncat/db.py index 9541c92..203c03c 100644 --- a/pwncat/db.py +++ b/pwncat/db.py @@ -2,7 +2,7 @@ This package defines all database objects. pwncat internally uses the ZODB database, which stores data as persistent Python objects. Each class defined under this package is a persistent Python -class which is stored verabtim in the database. For documentation +class which is stored verbatim in the database. For documentation on how to create persistent classes, please see the ZODB documentation. """ diff --git a/pwncat/facts/ability.py b/pwncat/facts/ability.py index 79d3e46..7d9cd1a 100644 --- a/pwncat/facts/ability.py +++ b/pwncat/facts/ability.py @@ -25,7 +25,7 @@ def build_gtfo_ability( **kwargs, ) -> Union["GTFOFileRead", "GTFOFileWrite", "GTFOExecute"]: r"""Build a escalation ability from a GTFOBins method. This will return - one of of the GTFO ability classes based on the capabilties exposed by + one of of the GTFO ability classes based on the capabilities exposed by the given GTFOBins method. :param source: the generating module @@ -64,7 +64,7 @@ class FileReadAbility(Fact): :param source: generating module name :type source: str - :param source_uid: the starting UID or None if it doesnt matter + :param source_uid: the starting UID or None if it doesn't matter :type source_uid: Optional[Union[int, str]] :param uid: the target UID :type uid: Union[int, str] @@ -98,7 +98,7 @@ class FileWriteAbility(Fact): :param source: generating module name :type source: str - :param source_uid: the starting UID or None if it doesnt matter + :param source_uid: the starting UID or None if it doesn't matter :type source_uid: Optional[Union[int, str]] :param uid: the target UID :type uid: Union[int, str] @@ -132,7 +132,7 @@ class ExecuteAbility(Fact): :param source: generating module name :type source: str - :param source_uid: the starting UID or None if it doesnt matter + :param source_uid: the starting UID or None if it doesn't matter :type source_uid: Optional[Union[int, str]] :param uid: the target UID :type uid: Union[int, str] @@ -162,7 +162,7 @@ class SpawnAbility(Fact): :param source: generating module name :type source: str - :param source_uid: the starting UID or None if it doesnt matter + :param source_uid: the starting UID or None if it doesn't matter :type source_uid: Optional[Union[int, str]] :param uid: the target UID :type uid: Union[int, str] @@ -191,7 +191,7 @@ class GTFOFileRead(FileReadAbility): :param source: generating module name :type source: str - :param source_uid: the starting UID or None if it doesnt matter + :param source_uid: the starting UID or None if it doesn't matter :type source_uid: Optional[Union[int, str]] :param uid: the target UID :type uid: Union[int, str] @@ -223,7 +223,7 @@ class GTFOFileRead(FileReadAbility): errors: str = None, newline: str = None, ): - """Read the file data using a GTFO bins reader""" + """Read the file data using a GTFObins reader""" if any(c not in "rb" for c in mode): raise ValueError("only r/b modes allowed") @@ -288,7 +288,7 @@ class GTFOFileWrite(FileWriteAbility): :param source: generating module name :type source: str - :param source_uid: the starting UID or None if it doesnt matter + :param source_uid: the starting UID or None if it doesn't matter :type source_uid: Optional[Union[int, str]] :param uid: the target UID :type uid: Union[int, str] @@ -320,7 +320,7 @@ class GTFOFileWrite(FileWriteAbility): errors: str = None, newline: str = None, ): - """Read the file data using a GTFO bins reader""" + """Read the file data using a GTFObins reader""" if any(c not in "wb" for c in mode): raise ValueError("only w/b modes allowed") @@ -385,7 +385,7 @@ class GTFOExecute(ExecuteAbility): :param source: generating module name :type source: str - :param source_uid: the starting UID or None if it doesnt matter + :param source_uid: the starting UID or None if it doesn't matter :type source_uid: Optional[Union[int, str]] :param uid: the target UID :type uid: Union[int, str] @@ -408,7 +408,7 @@ class GTFOExecute(ExecuteAbility): self.kwargs = kwargs def send_command(self, session, command: bytes = None): - """Send the command to the target for this GTFObin""" + """Send the command to the target for this GTFObins""" def Popen(self, session, *args, **kwargs): """Emulate the platform.Popen method for execution as another user""" diff --git a/pwncat/facts/tamper.py b/pwncat/facts/tamper.py index dd5d244..3c129b4 100644 --- a/pwncat/facts/tamper.py +++ b/pwncat/facts/tamper.py @@ -49,7 +49,7 @@ class Tamper(Fact): :param session: the session on which to operate :type session: pwncat.manager.Session """ - raise ModuleFailed("not reverable") + raise ModuleFailed("not revertable") def _annotate_title(self, session, title): """Just a helper for annotating the description with details on diff --git a/pwncat/gtfobins.py b/pwncat/gtfobins.py index 603784b..a71ba28 100644 --- a/pwncat/gtfobins.py +++ b/pwncat/gtfobins.py @@ -163,7 +163,7 @@ class Method: # Make sure both sudo_spec and sudo_user are provided if sudo_spec is assert spec is None or (spec is not None and user is not None) - # Make sure we can use this spec, and get remainig arguments + # Make sure we can use this spec, and get remaining arguments if spec is not None: command, args = self.sudo_args(binary_path, spec) args = gtfo.resolve_binaries( @@ -405,7 +405,7 @@ class GTFOBins: if spec != "ALL": # This is the harder case. We have a specific specification for the - # command wecan run. + # command we can run. # If there are arguments, remove them and grab the first item, which # will be the path or binary name @@ -489,7 +489,7 @@ class GTFOBins: quote = False # Find the remote binary that matches value = self.which(key, quote=quote) - # Whoops! No dependancy + # Whoops! No dependency if value is None: raise MissingBinary(key) # Next time, we have it diff --git a/pwncat/modules/__init__.py b/pwncat/modules/__init__.py index 084f8be..086bcaa 100644 --- a/pwncat/modules/__init__.py +++ b/pwncat/modules/__init__.py @@ -315,7 +315,7 @@ class BaseModule(metaclass=BaseModuleMeta): but only return one scalar value, setting this to true will collapse an array with only a single object to it's scalar value. """ PLATFORM: typing.List[typing.Type["pwncat.platform.Platform"]] = [] - """ The platform this module is compatibile with (can be multiple) """ + """ The platform this module is compatible with (can be multiple) """ def __init__(self): self.progress = None diff --git a/pwncat/modules/agnostic/enumerate/gather.py b/pwncat/modules/agnostic/enumerate/gather.py index 1739cdf..6f498cb 100644 --- a/pwncat/modules/agnostic/enumerate/gather.py +++ b/pwncat/modules/agnostic/enumerate/gather.py @@ -70,7 +70,7 @@ class Module(pwncat.modules.BaseModule): PLATFORM = None def run(self, session, output, modules, types, clear, cache, exclude): - """Perform a enumeration of the given moduels and save the output""" + """Perform a enumeration of the given modules and save the output""" module_names = modules diff --git a/pwncat/modules/linux/enumerate/escalate/append_passwd.py b/pwncat/modules/linux/enumerate/escalate/append_passwd.py index 579c5b4..7443b81 100644 --- a/pwncat/modules/linux/enumerate/escalate/append_passwd.py +++ b/pwncat/modules/linux/enumerate/escalate/append_passwd.py @@ -73,7 +73,7 @@ class AppendPasswd(EscalationReplace): class Module(EnumerateModule): - """Check for possible methods of escalation via modiying /etc/passwd""" + """Check for possible methods of escalation via modifying /etc/passwd""" PROVIDES = ["escalate.replace"] SCHEDULE = Schedule.PER_USER diff --git a/pwncat/modules/linux/enumerate/file/suid.py b/pwncat/modules/linux/enumerate/file/suid.py index 1d0c018..431e4fc 100644 --- a/pwncat/modules/linux/enumerate/file/suid.py +++ b/pwncat/modules/linux/enumerate/file/suid.py @@ -44,7 +44,7 @@ class Module(EnumerateModule): def enumerate(self, session: "pwncat.manager.Session"): # This forces the session to enumerate users FIRST, so we don't run - # into trying to enumerate _whilest_ enumerating SUID binaries... + # into trying to enumerate _whilst_ enumerating SUID binaries... # since we can't yet run multiple processes at the same time session.find_user(uid=0) diff --git a/pwncat/modules/linux/enumerate/software/sudo/cve_2019_14287.py b/pwncat/modules/linux/enumerate/software/sudo/cve_2019_14287.py index 4b58bc1..74c344c 100644 --- a/pwncat/modules/linux/enumerate/software/sudo/cve_2019_14287.py +++ b/pwncat/modules/linux/enumerate/software/sudo/cve_2019_14287.py @@ -66,7 +66,7 @@ class Module(EnumerateModule): for method in session.platform.gtfo.iter_sudo( command, caps=Capability.ALL ): - # Build a generic GTFO bins capability + # Build a generic GTFObins capability yield build_gtfo_ability( source=self.name, uid=0, diff --git a/pwncat/modules/linux/enumerate/software/sudo/rules.py b/pwncat/modules/linux/enumerate/software/sudo/rules.py index fbf3b10..7774dc8 100644 --- a/pwncat/modules/linux/enumerate/software/sudo/rules.py +++ b/pwncat/modules/linux/enumerate/software/sudo/rules.py @@ -261,7 +261,7 @@ class Module(EnumerateModule): for line in result.split("\n"): line = line.rstrip() - # Skipe header lines + # Skip header lines if not line.startswith(" ") and not line.startswith("\t"): continue diff --git a/pwncat/modules/linux/enumerate/system/uname.py b/pwncat/modules/linux/enumerate/system/uname.py index 61446ec..d1b621c 100644 --- a/pwncat/modules/linux/enumerate/system/uname.py +++ b/pwncat/modules/linux/enumerate/system/uname.py @@ -75,7 +75,7 @@ class Module(EnumerateModule): and operating system name (normally GNU/Linux). This module also provides a similar enumeration to the - common Linux Exploit Suggestor, and will report known + common Linux Exploit Suggester, and will report known vulnerabilities which are applicable to the detected kernel version. """ diff --git a/pwncat/modules/linux/implant/passwd.py b/pwncat/modules/linux/implant/passwd.py index 53b5aa8..8935e9c 100644 --- a/pwncat/modules/linux/implant/passwd.py +++ b/pwncat/modules/linux/implant/passwd.py @@ -89,7 +89,7 @@ class Module(ImplantModule): with session.platform.open("/etc/passwd", "r") as filp: passwd_contents = list(filp) except (FileNotFoundError, PermissionError): - raise ModuleFailed("faild to read /etc/passwd") + raise ModuleFailed("failed to read /etc/passwd") # Hash the password yield Status("hashing password") diff --git a/pwncat/modules/windows/bloodhound.py b/pwncat/modules/windows/bloodhound.py index 5e518e4..5c53192 100644 --- a/pwncat/modules/windows/bloodhound.py +++ b/pwncat/modules/windows/bloodhound.py @@ -148,7 +148,7 @@ class Module(BaseModule): raise ModuleFailed(f"while importing Invoke-BloodHound: {exc}") # Try to create a temporary file. We're just going to delete it, but - # this gives us a tangeable temporary path to put the zip file. + # this gives us a tangible temporary path to put the zip file. yield Status("locating a suitable temporary file location") with session.platform.tempfile(suffix="zip", mode="w") as filp: file_path = filp.name diff --git a/pwncat/modules/windows/enumerate/domain/__init__.py b/pwncat/modules/windows/enumerate/domain/__init__.py index c28c141..4dcc0fc 100644 --- a/pwncat/modules/windows/enumerate/domain/__init__.py +++ b/pwncat/modules/windows/enumerate/domain/__init__.py @@ -21,7 +21,7 @@ class DomainObject(Fact): return self.domain[name] def title(self, session: "pwncat.manager.Session"): - return f"Active Dirctory Domain: [magenta]{self.domain['Name']}[/magenta]" + return f"Active Directory Domain: [magenta]{self.domain['Name']}[/magenta]" def description(self, session: "pwncat.manager.Session"): output = [] diff --git a/pwncat/platform/__init__.py b/pwncat/platform/__init__.py index 74b7a5e..682f544 100644 --- a/pwncat/platform/__init__.py +++ b/pwncat/platform/__init__.py @@ -394,7 +394,7 @@ class Path: raise OSError(exc.stdout) from exc def touch(self, mode: int = 0o666, exist_ok: bool = True): - """Createa file at this path. If the file already exists, function + """Create a file at this path. If the file already exists, function succeeds if exist_ok is true (and it's modification time is updated). Otherwise FileExistsError is raised.""" diff --git a/pwncat/platform/linux.py b/pwncat/platform/linux.py index a5cc5f1..3650120 100644 --- a/pwncat/platform/linux.py +++ b/pwncat/platform/linux.py @@ -1,6 +1,6 @@ """ The Linux platform provides Linux shell support ontop of any channel. -The Linux platfrom expects the channel to expose a shell whose stdio +The Linux platform expects the channel to expose a shell whose stdio is connected directly to the channel IO. At a minimum stdin and stdout must be connected. @@ -122,14 +122,14 @@ class PopenLinux(pwncat.subprocess.Popen): except ValueError: pass - # This gets a 'lil... funky... Normally, the ChannelFile + # This gets a 'lil... funky... Normally, the `ChannelFile` # wraps a non-blocking socket in a blocking file object - # because this what we normally we want and allows us + # because this is what we normally want and it allows us # to implement our own timeouts. However, here we want # a non-blocking call to check for EOF, so we set the # internal ``blocking`` flag to False which can cause # a `BlockingIOError` caught below. We need to do this - # in a nested `try-finaly` so we gaurantee catching it + # in a nested `try-finally` so we guarantee catching it # and resetting the flag before calling `_receive_returncode`. try: try: @@ -697,7 +697,7 @@ class Linux(Platform): continue break else: - raise PlatformError("no avialable pty methods") + raise PlatformError("no available pty methods") # When starting a pty, history is sometimes re-enabled self.disable_history() diff --git a/pwncat/platform/windows.py b/pwncat/platform/windows.py index 1d63c24..b2b53b3 100644 --- a/pwncat/platform/windows.py +++ b/pwncat/platform/windows.py @@ -5,13 +5,13 @@ utilize the C2 libraries located at `pwncat-windows-c2