Added implant module list subcommand

Also updated documentation to clarify implant reconnection process.
This commit is contained in:
Caleb Stewart 2021-12-26 03:57:13 -05:00
parent 6a913f0fb3
commit a952923b7d
5 changed files with 800 additions and 263 deletions

View File

@ -13,6 +13,8 @@ and simply didn't have the time to go back and retroactively create one.
- Fixed parsing of `--ssl` argument in main entrypoint ([#225](https://github.com/calebstewart/pwncat/issues/225))
- Replaced `paramiko` with `paramiko-ng`
- Utilized Paramiko SSHClient which will also utilize the SSHAgent if available by default and supports key types aside from RSA ([#91](https://github.com/calebstewart/pwncat/issues/91))
- Added implant module `list` command to match documentation ([#224](https://github.com/calebstewart/pwncat/issues/224)).
- Update documentation to clarify implant reconnection
## [0.5.1] - 2021-12-07
Minor bug fixes. Mainly typos from changing the package name.

View File

@ -63,5 +63,24 @@ Reconnecting With Implants
Remote implants provide a way to reconnect to a target at will. Reconnecting can be accomplished by simply
executing the pwncat entrypoint and specifying either the IP address or unique host ID of the target.
pwncat will automatically check for installed implants and attempt to reconnect. See the Usage section for
examples.
pwncat will automatically check for installed implants and attempt to reconnect.
To list all installed remote implants, use the ``--list`` argument:
.. code-block:: bash
$ pwncat-cs --list
╷ ╷ ╷ ╷
ID │ Address │ Platform │ Implant │ User
══════════════════════════════════╪════════════════╪══════════╪═══════════════════════════════════════╪═══════
ab8b7df2a1f83fa6694b0315aaf1deec │ 192.168.10.100 │ linux │ linux.implant.authorized_key │ caleb
When attempting to reconnect, you only need to provide the unique host ID from the above table. You can also provide the remote address, but keep in mind that if multiple hosts sit behind a single NAT, the host ID is more reliable for reconnecting.
.. code-block:: bash
$ pwncat-cs ab8b7df2a1f83fa6694b0315aaf1deec
[03:08:13] Welcome to pwncat 🐈!
trigger implant: linux.implant.authorized_key
[03:08:18] 192.168.10.100:22: loaded known host from db
192.168.10.100:22: connected via backdoor public key added to caleb authorized_keys

1020
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -18,27 +18,36 @@ class Module(BaseModule):
PLATFORM = None
""" No platform restraints """
ARGUMENTS = {
"list": Argument(Bool, default=False, help="list installed implants"),
"remove": Argument(Bool, default=False, help="remove installed implants"),
"escalate": Argument(
Bool, default=False, help="escalate using an installed local implant"
),
}
def run(self, session, remove, escalate):
def run(self, session, remove, escalate, **kwargs):
"""Perform the requested action"""
if (not remove and not escalate) or (remove and escalate):
raise ModuleFailed("expected one of escalate or remove")
if sum([remove, escalate, kwargs.get("list")]) > 1:
raise ModuleFailed("expected one of escalate, remove or list")
if remove is False and escalate is False:
kwargs["list"] = True
# Look for matching implants
implants = list(
implant
for implant in session.run("enumerate", types=["implant.*"])
if not escalate
or kwargs.get("list")
or "implant.replace" in implant.types
or "implant.spawn" in implant.types
)
if not implants:
console.print("No installed implants.")
return
try:
session._progress.stop()
@ -50,6 +59,8 @@ class Module(BaseModule):
prompt = "Which should we remove (e.g. '1 2 4', default: all)? "
elif escalate:
prompt = "Which should we attempt escalation with (e.g. '1 2 4', default: all)? "
else:
return
while True:
selections = Prompt.ask(prompt, console=console)

View File

@ -43,6 +43,7 @@ zodburi = "^2.5.0"
Jinja2 = "^3.0.1"
paramiko-ng = "^2.8.8"
PyNaCl = "^1.4.0"
sphinx-toolbox = "^2.15.2"
[tool.poetry.dev-dependencies]
isort = "^5.8.0"