Multiple typo fixes
This shouldn't break anything, no variable name is changed. Documentation and strings are fixed, strings that do not come in a 'command' or those that are required for 'pwncat' to work are not changed.
This commit is contained in:
parent
2790a7a287
commit
e2929573be
4
IDEAS.md
4
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.
|
configuration will be checked for matching arguments for the module.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
# Install a persistence mthod with a bind channel
|
# Install a persistence method with a bind channel
|
||||||
use persistence/system/cron
|
use persistence/system/cron
|
||||||
set method channels/bind
|
set method channels/bind
|
||||||
set schedule "* * */1 *"
|
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
|
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
|
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
|
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
|
method allowing more flexibility in the return values of modules. It allows modules to have
|
||||||
asynchronous (generator) return values.
|
asynchronous (generator) return values.
|
||||||
|
|
10
README.md
10
README.md
|
@ -22,7 +22,7 @@ for working with remote shells.
|
||||||
- Disable history in the remote shell
|
- Disable history in the remote shell
|
||||||
- Normalize shell prompt
|
- Normalize shell prompt
|
||||||
- Locate useful binaries (using `which`)
|
- 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
|
`pwncat` knows how to spawn pty's with a few different methods and will
|
||||||
cross-reference the methods with the executables previously enumerated. After
|
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 libraries implementing the C2 are implemented at [pwncat-windows-c2].
|
||||||
The DLLs for the C2 will be automatically downloaded from the targeted release
|
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,
|
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
|
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.
|
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
|
The current `master` branch is `v0.4.3`. This version has
|
||||||
overhauled a lot of the framework to support multiple platforms and
|
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.
|
in the `latest` version on Read the Docs.
|
||||||
|
|
||||||
**v0.3.1 will not be updated further**
|
**v0.3.1 will not be updated further**
|
||||||
|
@ -85,7 +85,7 @@ in the `latest` version on Read the Docs.
|
||||||
## Modules
|
## Modules
|
||||||
|
|
||||||
Recently, the architecture of the pwncat framework was redesigned to
|
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
|
implemented as modules. This includes enumeration, persistence and
|
||||||
privilege escalation. Interacting with modules is similar to most other
|
privilege escalation. Interacting with modules is similar to most other
|
||||||
post-exploitation platforms. You can utilize the familiar `run`, `search`
|
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 -p 2222 user@10.10.10.10
|
||||||
pwncat user@10.10.10.10:2222
|
pwncat user@10.10.10.10:2222
|
||||||
# Reconnect utilizing installed persistence
|
# 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.
|
# SSH is used as a fallback.
|
||||||
pwncat reconnect://user@10.10.10.10
|
pwncat reconnect://user@10.10.10.10
|
||||||
pwncat reconnect://user@c228fc49e515628a0c13bdc4759a12bf
|
pwncat reconnect://user@c228fc49e515628a0c13bdc4759a12bf
|
||||||
|
|
|
@ -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
|
abstracts a communication method with a target. By default, pwncat implements
|
||||||
a few standard channels: socket bind/connect and ssh.
|
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
|
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
|
between the target and the attacker. Channels make no assumption about protocol
|
||||||
of the C2 connection. This is the platform's job.
|
of the C2 connection. This is the platform's job.
|
||||||
|
|
|
@ -173,7 +173,7 @@ class Parameter:
|
||||||
This class allows you to specify the syntax highlighting, tab completion
|
This class allows you to specify the syntax highlighting, tab completion
|
||||||
and argparse settings for a command parameter in on go. The ``complete``
|
and argparse settings for a command parameter in on go. The ``complete``
|
||||||
argument tells pwncat how to tab complete your argument. The ``token``
|
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
|
syntax highlighting for your argument. All other arguments are passed
|
||||||
directly to ``argparse`` when constructing the parser.
|
directly to ``argparse`` when constructing the parser.
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ class Command(CommandDefinition):
|
||||||
"""
|
"""
|
||||||
Connect to a remote victim. This command is only valid prior to an established
|
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
|
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,
|
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.
|
while `connect -l [port]` will listen for a reverse shell on the specified port.
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ class Command(CommandDefinition):
|
||||||
)
|
)
|
||||||
|
|
||||||
for module in modules:
|
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
|
# white space and remove newlines. `textwrap.shorten` is
|
||||||
# the easiest way to do that, so we use a large size for
|
# the easiest way to do that, so we use a large size for
|
||||||
# width.
|
# width.
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
This package defines all database objects. pwncat internally uses
|
This package defines all database objects. pwncat internally uses
|
||||||
the ZODB database, which stores data as persistent Python objects.
|
the ZODB database, which stores data as persistent Python objects.
|
||||||
Each class defined under this package is a persistent Python
|
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
|
on how to create persistent classes, please see the ZODB
|
||||||
documentation.
|
documentation.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -25,7 +25,7 @@ def build_gtfo_ability(
|
||||||
**kwargs,
|
**kwargs,
|
||||||
) -> Union["GTFOFileRead", "GTFOFileWrite", "GTFOExecute"]:
|
) -> Union["GTFOFileRead", "GTFOFileWrite", "GTFOExecute"]:
|
||||||
r"""Build a escalation ability from a GTFOBins method. This will return
|
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.
|
the given GTFOBins method.
|
||||||
|
|
||||||
:param source: the generating module
|
:param source: the generating module
|
||||||
|
@ -64,7 +64,7 @@ class FileReadAbility(Fact):
|
||||||
|
|
||||||
:param source: generating module name
|
:param source: generating module name
|
||||||
:type source: str
|
: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]]
|
:type source_uid: Optional[Union[int, str]]
|
||||||
:param uid: the target UID
|
:param uid: the target UID
|
||||||
:type uid: Union[int, str]
|
:type uid: Union[int, str]
|
||||||
|
@ -98,7 +98,7 @@ class FileWriteAbility(Fact):
|
||||||
|
|
||||||
:param source: generating module name
|
:param source: generating module name
|
||||||
:type source: str
|
: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]]
|
:type source_uid: Optional[Union[int, str]]
|
||||||
:param uid: the target UID
|
:param uid: the target UID
|
||||||
:type uid: Union[int, str]
|
:type uid: Union[int, str]
|
||||||
|
@ -132,7 +132,7 @@ class ExecuteAbility(Fact):
|
||||||
|
|
||||||
:param source: generating module name
|
:param source: generating module name
|
||||||
:type source: str
|
: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]]
|
:type source_uid: Optional[Union[int, str]]
|
||||||
:param uid: the target UID
|
:param uid: the target UID
|
||||||
:type uid: Union[int, str]
|
:type uid: Union[int, str]
|
||||||
|
@ -162,7 +162,7 @@ class SpawnAbility(Fact):
|
||||||
|
|
||||||
:param source: generating module name
|
:param source: generating module name
|
||||||
:type source: str
|
: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]]
|
:type source_uid: Optional[Union[int, str]]
|
||||||
:param uid: the target UID
|
:param uid: the target UID
|
||||||
:type uid: Union[int, str]
|
:type uid: Union[int, str]
|
||||||
|
@ -191,7 +191,7 @@ class GTFOFileRead(FileReadAbility):
|
||||||
|
|
||||||
:param source: generating module name
|
:param source: generating module name
|
||||||
:type source: str
|
: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]]
|
:type source_uid: Optional[Union[int, str]]
|
||||||
:param uid: the target UID
|
:param uid: the target UID
|
||||||
:type uid: Union[int, str]
|
:type uid: Union[int, str]
|
||||||
|
@ -223,7 +223,7 @@ class GTFOFileRead(FileReadAbility):
|
||||||
errors: str = None,
|
errors: str = None,
|
||||||
newline: 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):
|
if any(c not in "rb" for c in mode):
|
||||||
raise ValueError("only r/b modes allowed")
|
raise ValueError("only r/b modes allowed")
|
||||||
|
@ -288,7 +288,7 @@ class GTFOFileWrite(FileWriteAbility):
|
||||||
|
|
||||||
:param source: generating module name
|
:param source: generating module name
|
||||||
:type source: str
|
: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]]
|
:type source_uid: Optional[Union[int, str]]
|
||||||
:param uid: the target UID
|
:param uid: the target UID
|
||||||
:type uid: Union[int, str]
|
:type uid: Union[int, str]
|
||||||
|
@ -320,7 +320,7 @@ class GTFOFileWrite(FileWriteAbility):
|
||||||
errors: str = None,
|
errors: str = None,
|
||||||
newline: 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):
|
if any(c not in "wb" for c in mode):
|
||||||
raise ValueError("only w/b modes allowed")
|
raise ValueError("only w/b modes allowed")
|
||||||
|
@ -385,7 +385,7 @@ class GTFOExecute(ExecuteAbility):
|
||||||
|
|
||||||
:param source: generating module name
|
:param source: generating module name
|
||||||
:type source: str
|
: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]]
|
:type source_uid: Optional[Union[int, str]]
|
||||||
:param uid: the target UID
|
:param uid: the target UID
|
||||||
:type uid: Union[int, str]
|
:type uid: Union[int, str]
|
||||||
|
@ -408,7 +408,7 @@ class GTFOExecute(ExecuteAbility):
|
||||||
self.kwargs = kwargs
|
self.kwargs = kwargs
|
||||||
|
|
||||||
def send_command(self, session, command: bytes = None):
|
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):
|
def Popen(self, session, *args, **kwargs):
|
||||||
"""Emulate the platform.Popen method for execution as another user"""
|
"""Emulate the platform.Popen method for execution as another user"""
|
||||||
|
|
|
@ -49,7 +49,7 @@ class Tamper(Fact):
|
||||||
:param session: the session on which to operate
|
:param session: the session on which to operate
|
||||||
:type session: pwncat.manager.Session
|
:type session: pwncat.manager.Session
|
||||||
"""
|
"""
|
||||||
raise ModuleFailed("not reverable")
|
raise ModuleFailed("not revertable")
|
||||||
|
|
||||||
def _annotate_title(self, session, title):
|
def _annotate_title(self, session, title):
|
||||||
"""Just a helper for annotating the description with details on
|
"""Just a helper for annotating the description with details on
|
||||||
|
|
|
@ -163,7 +163,7 @@ class Method:
|
||||||
# Make sure both sudo_spec and sudo_user are provided if sudo_spec is
|
# 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)
|
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:
|
if spec is not None:
|
||||||
command, args = self.sudo_args(binary_path, spec)
|
command, args = self.sudo_args(binary_path, spec)
|
||||||
args = gtfo.resolve_binaries(
|
args = gtfo.resolve_binaries(
|
||||||
|
@ -405,7 +405,7 @@ class GTFOBins:
|
||||||
|
|
||||||
if spec != "ALL":
|
if spec != "ALL":
|
||||||
# This is the harder case. We have a specific specification for the
|
# 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
|
# If there are arguments, remove them and grab the first item, which
|
||||||
# will be the path or binary name
|
# will be the path or binary name
|
||||||
|
@ -489,7 +489,7 @@ class GTFOBins:
|
||||||
quote = False
|
quote = False
|
||||||
# Find the remote binary that matches
|
# Find the remote binary that matches
|
||||||
value = self.which(key, quote=quote)
|
value = self.which(key, quote=quote)
|
||||||
# Whoops! No dependancy
|
# Whoops! No dependency
|
||||||
if value is None:
|
if value is None:
|
||||||
raise MissingBinary(key)
|
raise MissingBinary(key)
|
||||||
# Next time, we have it
|
# Next time, we have it
|
||||||
|
|
|
@ -315,7 +315,7 @@ class BaseModule(metaclass=BaseModuleMeta):
|
||||||
but only return one scalar value, setting this to true will collapse
|
but only return one scalar value, setting this to true will collapse
|
||||||
an array with only a single object to it's scalar value. """
|
an array with only a single object to it's scalar value. """
|
||||||
PLATFORM: typing.List[typing.Type["pwncat.platform.Platform"]] = []
|
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):
|
def __init__(self):
|
||||||
self.progress = None
|
self.progress = None
|
||||||
|
|
|
@ -70,7 +70,7 @@ class Module(pwncat.modules.BaseModule):
|
||||||
PLATFORM = None
|
PLATFORM = None
|
||||||
|
|
||||||
def run(self, session, output, modules, types, clear, cache, exclude):
|
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
|
module_names = modules
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ class AppendPasswd(EscalationReplace):
|
||||||
|
|
||||||
|
|
||||||
class Module(EnumerateModule):
|
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"]
|
PROVIDES = ["escalate.replace"]
|
||||||
SCHEDULE = Schedule.PER_USER
|
SCHEDULE = Schedule.PER_USER
|
||||||
|
|
|
@ -44,7 +44,7 @@ class Module(EnumerateModule):
|
||||||
def enumerate(self, session: "pwncat.manager.Session"):
|
def enumerate(self, session: "pwncat.manager.Session"):
|
||||||
|
|
||||||
# This forces the session to enumerate users FIRST, so we don't run
|
# 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
|
# since we can't yet run multiple processes at the same time
|
||||||
session.find_user(uid=0)
|
session.find_user(uid=0)
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ class Module(EnumerateModule):
|
||||||
for method in session.platform.gtfo.iter_sudo(
|
for method in session.platform.gtfo.iter_sudo(
|
||||||
command, caps=Capability.ALL
|
command, caps=Capability.ALL
|
||||||
):
|
):
|
||||||
# Build a generic GTFO bins capability
|
# Build a generic GTFObins capability
|
||||||
yield build_gtfo_ability(
|
yield build_gtfo_ability(
|
||||||
source=self.name,
|
source=self.name,
|
||||||
uid=0,
|
uid=0,
|
||||||
|
|
|
@ -261,7 +261,7 @@ class Module(EnumerateModule):
|
||||||
for line in result.split("\n"):
|
for line in result.split("\n"):
|
||||||
line = line.rstrip()
|
line = line.rstrip()
|
||||||
|
|
||||||
# Skipe header lines
|
# Skip header lines
|
||||||
if not line.startswith(" ") and not line.startswith("\t"):
|
if not line.startswith(" ") and not line.startswith("\t"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ class Module(EnumerateModule):
|
||||||
and operating system name (normally GNU/Linux).
|
and operating system name (normally GNU/Linux).
|
||||||
|
|
||||||
This module also provides a similar enumeration to the
|
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
|
vulnerabilities which are applicable to the detected
|
||||||
kernel version.
|
kernel version.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -89,7 +89,7 @@ class Module(ImplantModule):
|
||||||
with session.platform.open("/etc/passwd", "r") as filp:
|
with session.platform.open("/etc/passwd", "r") as filp:
|
||||||
passwd_contents = list(filp)
|
passwd_contents = list(filp)
|
||||||
except (FileNotFoundError, PermissionError):
|
except (FileNotFoundError, PermissionError):
|
||||||
raise ModuleFailed("faild to read /etc/passwd")
|
raise ModuleFailed("failed to read /etc/passwd")
|
||||||
|
|
||||||
# Hash the password
|
# Hash the password
|
||||||
yield Status("hashing password")
|
yield Status("hashing password")
|
||||||
|
|
|
@ -148,7 +148,7 @@ class Module(BaseModule):
|
||||||
raise ModuleFailed(f"while importing Invoke-BloodHound: {exc}")
|
raise ModuleFailed(f"while importing Invoke-BloodHound: {exc}")
|
||||||
|
|
||||||
# Try to create a temporary file. We're just going to delete it, but
|
# 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")
|
yield Status("locating a suitable temporary file location")
|
||||||
with session.platform.tempfile(suffix="zip", mode="w") as filp:
|
with session.platform.tempfile(suffix="zip", mode="w") as filp:
|
||||||
file_path = filp.name
|
file_path = filp.name
|
||||||
|
|
|
@ -21,7 +21,7 @@ class DomainObject(Fact):
|
||||||
return self.domain[name]
|
return self.domain[name]
|
||||||
|
|
||||||
def title(self, session: "pwncat.manager.Session"):
|
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"):
|
def description(self, session: "pwncat.manager.Session"):
|
||||||
output = []
|
output = []
|
||||||
|
|
|
@ -394,7 +394,7 @@ class Path:
|
||||||
raise OSError(exc.stdout) from exc
|
raise OSError(exc.stdout) from exc
|
||||||
|
|
||||||
def touch(self, mode: int = 0o666, exist_ok: bool = True):
|
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).
|
succeeds if exist_ok is true (and it's modification time is updated).
|
||||||
Otherwise FileExistsError is raised."""
|
Otherwise FileExistsError is raised."""
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
"""
|
"""
|
||||||
The Linux platform provides Linux shell support ontop of any channel.
|
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
|
is connected directly to the channel IO. At a minimum stdin and stdout
|
||||||
must be connected.
|
must be connected.
|
||||||
|
|
||||||
|
@ -122,14 +122,14 @@ class PopenLinux(pwncat.subprocess.Popen):
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
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
|
# 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
|
# to implement our own timeouts. However, here we want
|
||||||
# a non-blocking call to check for EOF, so we set the
|
# a non-blocking call to check for EOF, so we set the
|
||||||
# internal ``blocking`` flag to False which can cause
|
# internal ``blocking`` flag to False which can cause
|
||||||
# a `BlockingIOError` caught below. We need to do this
|
# 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`.
|
# and resetting the flag before calling `_receive_returncode`.
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
|
@ -697,7 +697,7 @@ class Linux(Platform):
|
||||||
continue
|
continue
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
raise PlatformError("no avialable pty methods")
|
raise PlatformError("no available pty methods")
|
||||||
|
|
||||||
# When starting a pty, history is sometimes re-enabled
|
# When starting a pty, history is sometimes re-enabled
|
||||||
self.disable_history()
|
self.disable_history()
|
||||||
|
|
|
@ -5,13 +5,13 @@ utilize the C2 libraries located at `pwncat-windows-c2 <https://github.com/caleb
|
||||||
This will be automatically downloaded to the directory identified by the
|
This will be automatically downloaded to the directory identified by the
|
||||||
``windows_c2_dir`` configuration which defaults to ``~/.local/share/pwncat/``.
|
``windows_c2_dir`` configuration which defaults to ``~/.local/share/pwncat/``.
|
||||||
It will be uploaded and executed via ``Install-Util`` in order to automatically
|
It will be uploaded and executed via ``Install-Util`` in order to automatically
|
||||||
bypass AppLocker, and will provide you an unlogged, unconstrained powershell
|
bypass AppLocker, and will provide you an un-logged, unconstrained powershell
|
||||||
session as well as basic process and file IO routines.
|
session as well as basic process and file IO routines.
|
||||||
|
|
||||||
When operating in a platform-specific environment, you can safely execute multiple
|
When operating in a platform-specific environment, you can safely execute multiple
|
||||||
processes and open multiple files with this platform. However, you should be
|
processes and open multiple files with this platform. However, you should be
|
||||||
careful to cleanup all processes and files prior to return from your method
|
careful to cleanup all processes and files prior to return from your method
|
||||||
or code as the C2 will not attempt to garbage collect file or proces handles.
|
or code as the C2 will not attempt to garbage collect file or process handles.
|
||||||
"""
|
"""
|
||||||
import sys
|
import sys
|
||||||
import gzip
|
import gzip
|
||||||
|
@ -64,7 +64,7 @@ class ProtocolError(PlatformError):
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class stat_result:
|
class stat_result:
|
||||||
"""Python `os` doesn't provide a way to sainly construct a stat_result
|
"""Python `os` doesn't provide a way to sanely construct a stat_result
|
||||||
so I created this."""
|
so I created this."""
|
||||||
|
|
||||||
st_mode = 0
|
st_mode = 0
|
||||||
|
@ -635,7 +635,7 @@ function prompt {
|
||||||
"\\Windows\\System32\\spool\\SERVERS",
|
"\\Windows\\System32\\spool\\SERVERS",
|
||||||
"\\Windows\\System32\\spool\\drivers\\color",
|
"\\Windows\\System32\\spool\\drivers\\color",
|
||||||
"\\Windows\\System32\\Tasks\\Microsoft\\Windows\\SyncCenter",
|
"\\Windows\\System32\\Tasks\\Microsoft\\Windows\\SyncCenter",
|
||||||
"\\Windows\\System32\\Tasks_Migrated (after peforming a version upgrade of Windows 10)",
|
"\\Windows\\System32\\Tasks_Migrated (after performing a version upgrade of Windows 10)",
|
||||||
"\\Windows\\SysWOW64\\FxsTmp",
|
"\\Windows\\SysWOW64\\FxsTmp",
|
||||||
"\\Windows\\SysWOW64\\com\\dmp",
|
"\\Windows\\SysWOW64\\com\\dmp",
|
||||||
"\\Windows\\SysWOW64\\Tasks\\Microsoft\\Windows\\SyncCenter",
|
"\\Windows\\SysWOW64\\Tasks\\Microsoft\\Windows\\SyncCenter",
|
||||||
|
@ -941,7 +941,7 @@ function prompt {
|
||||||
errors: str = None,
|
errors: str = None,
|
||||||
newline: str = None,
|
newline: str = None,
|
||||||
):
|
):
|
||||||
"""Mimick the built-in open method."""
|
"""Mimic the built-in open method."""
|
||||||
|
|
||||||
# Ensure all mode properties are valid
|
# Ensure all mode properties are valid
|
||||||
for char in mode:
|
for char in mode:
|
||||||
|
@ -1038,7 +1038,7 @@ function prompt {
|
||||||
|
|
||||||
def new_item(self, **kwargs):
|
def new_item(self, **kwargs):
|
||||||
"""Run the `New-Item` commandlet with specified arguments and
|
"""Run the `New-Item` commandlet with specified arguments and
|
||||||
raise the appropriate local exception if requried. For a list of
|
raise the appropriate local exception if required. For a list of
|
||||||
valid arguments, see the New-Item help documentation."""
|
valid arguments, see the New-Item help documentation."""
|
||||||
|
|
||||||
command = "New-Item "
|
command = "New-Item "
|
||||||
|
@ -1496,7 +1496,7 @@ function prompt {
|
||||||
# Encode the assembly
|
# Encode the assembly
|
||||||
assembly = base64.b64encode(content).decode("utf-8")
|
assembly = base64.b64encode(content).decode("utf-8")
|
||||||
|
|
||||||
# Load the assembly. Let protocol errors propogate
|
# Load the assembly. Let protocol errors propagate
|
||||||
ident = self.run_method("Reflection", "load", assembly)
|
ident = self.run_method("Reflection", "load", assembly)
|
||||||
|
|
||||||
plugin = DotNetPlugin(self, name, checksum, ident)
|
plugin = DotNetPlugin(self, name, checksum, ident)
|
||||||
|
|
|
@ -95,7 +95,7 @@ class Popen:
|
||||||
|
|
||||||
def communicate(self, input: bytes = None, timeout: float = None):
|
def communicate(self, input: bytes = None, timeout: float = None):
|
||||||
"""Interact with process: Send data to stdin. Read data from stdout
|
"""Interact with process: Send data to stdin. Read data from stdout
|
||||||
and stderr, until end-of-file is readched. Wait for the process to
|
and stderr, until end-of-file is reached. Wait for the process to
|
||||||
terminate and set the ``returncode`` attribute. The optional ``input``
|
terminate and set the ``returncode`` attribute. The optional ``input``
|
||||||
argument should be data to be sent to the child process, or None, if
|
argument should be data to be sent to the child process, or None, if
|
||||||
no data should be sent to the child. If streams were opened in text mode,
|
no data should be sent to the child. If streams were opened in text mode,
|
||||||
|
|
|
@ -87,7 +87,7 @@ class Target(persistent.Persistent):
|
||||||
self.tampers: persistent.list.PersistentList = persistent.list.PersistentList()
|
self.tampers: persistent.list.PersistentList = persistent.list.PersistentList()
|
||||||
""" List of files/properties of the target that have been modified and/or created. """
|
""" List of files/properties of the target that have been modified and/or created. """
|
||||||
self.users: persistent.list.PersistentList = persistent.list.PersistentList()
|
self.users: persistent.list.PersistentList = persistent.list.PersistentList()
|
||||||
""" List of users known on the target system (may not be all-encompasing depending on access) """
|
""" List of users known on the target system (may not be all-encompassing depending on access) """
|
||||||
self.utilities: OOBTree() = OOBTree()
|
self.utilities: OOBTree() = OOBTree()
|
||||||
""" Mapping of utility names to paths. This is mainly used on Unix platforms to identify binaries available in the path. """
|
""" Mapping of utility names to paths. This is mainly used on Unix platforms to identify binaries available in the path. """
|
||||||
self.implants: persistent.list.PersistentList = persistent.list.PersistentList()
|
self.implants: persistent.list.PersistentList = persistent.list.PersistentList()
|
||||||
|
|
|
@ -156,7 +156,7 @@ def join(argv: List[str]):
|
||||||
def quote(token: str):
|
def quote(token: str):
|
||||||
"""Quote the token much like shlex.quote, except don't use single quotes
|
"""Quote the token much like shlex.quote, except don't use single quotes
|
||||||
this will escape any double quotes in the string and wrap it in double
|
this will escape any double quotes in the string and wrap it in double
|
||||||
quotes. If there are no spaces, it returns the stirng unchanged."""
|
quotes. If there are no spaces, it returns the string unchanged."""
|
||||||
for c in token:
|
for c in token:
|
||||||
if c in string.whitespace:
|
if c in string.whitespace:
|
||||||
break
|
break
|
||||||
|
|
|
@ -75,7 +75,7 @@ set -g db "memory://"
|
||||||
yield session
|
yield session
|
||||||
break
|
break
|
||||||
except ChannelError:
|
except ChannelError:
|
||||||
# This seems to be because of the contaiener setup, so we just add
|
# This seems to be because of the container setup, so we just add
|
||||||
# a little sleep in
|
# a little sleep in
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Reference in New Issue