Scripting Tasking
What does this hook into?
Scripting tasking involves the following RESTful endpoints on an instance of Mythic
. This means you need to create a new Mythic
instance (i.e. mythic = Mythic(username="blah" ...
) and then call these functions like mythic.get_all_tasks()
:
This section also hooks into the following async callback functions:
The listen_for_all_tasks
function gets ALL
tasks in the operation and continue to listen for new ones. This is slightly different than the listen_for_new_tasks
function which simply starts listening for new tasking and doesn't give historic data.
Creating Tasks
Most functions in this section are pretty straight forward, but creating new Tasks can be complicated. To help with this, let's look at some examples:
the create_task
function takes in the Task you want to create. At a simple example, let's look at issuing the shell whoami
command that you'd typically type out on the command line. We need to specify a few things:
We have to specify the callback (this can be either with a Callback
object or just the id
associated with the callback). This tells Mythic which callback we're wanting to interact with. Then we need to specify the command we want to issue. This can be either a Command
object, or simply the string of the name of the command we want to execute, shell
in this instance. The last piece here is specifying the parameters we need to send down. params
will either be a string or you can specify the JSON associated with the command as well. In this case, the parameters for our shell
command is simply the string whoami
. At this point, we've described the Task we want to create. Now we can issue it with mythic.create_task
.
create_task
takes an interesting parameter though - return_on
. This specifies when you want to return from this function call. If you've used the interface before, you've noticed that as you go through the tasking life cycle, the status changes between a few status - preprocessing
, submitted
, processing
, processed
, completed
, error
, and sometimes building...
. The return_on
function allows you to specify when you're ready to return. For example, if you don't specify this, the function will return as soon as Mythic gets your RESTful request (i.e. your tasking is in the preprocessing
status). The different status types mean:
preprocessing
- Mythic got the Task request and set it off to the payload type's Docker containersubmitted
- Everything went well with creating Tasking and it's ready for an agent to pick upprocessing
- An agent picked up the tasking, but hasn't returned anythingprocessed
- An agent sent back at least one response, but hasn't indicated that the tasking is donecompleted
- An agent indicated that the tasking is completederror
- An agent indicated that something went wrong after picking up the tasking.
Regardless of the status you say to return_on
, if the task switches to completed
or error
, then it will return. You can also specify a timeout
in seconds of how long to wait for your status to match. This is helpful for scripting so that you don't wait indefinitely for a completed
status if your agent is dead for example.
In the above example, we simply return on submitted
, so there are no responses yet. In this case, we only want to continue on with our function when we have all of the tasking responses, not when we're only partially done. To facilitate this, we have an additional helper function:
This function takes a task id and how long we're willing to wait. This returns an array of the responses (so if there's just one response, it'll be an array of one).
Creating tasks with files
All of the above is fine for most tasking, but what about the case where you want to upload a file with your tasking, such as with the upload
command. Let's take that as an example. The apfell
upload command takes two parameters:
remote_path
- a parameter of typeString
that indicates the remote path of where the file will be uploaded tofile
- a parameter of typeFile
that indicates the actual file we upload. If you do this in the UI, then you'll se a popup modal with a button for you to select a file from disk. Obviously, this isn't available for scripting, so we need to do something else.
The above example is mostly the same as the issue_shell_whoami
example above, except for one addition - the files
parameter. This is an array of TaskFile
objects. Each TaskFile
object takes in a few parameters:
content
- this is the binary data that we're trying to uploadfilename
- this is the filename we want associated with this binary content in the UIparam_name
- this is the name of the parameter we're referencing with the file content. In ourupload
example, this parameter was simply calledfile
, so that's what you see here. In other commands, that parameter could be called anything though.
Since you can potentially upload multiple files for a given command, this files
parameter is an array of entries. Otherwise, you call the mythic.create_task
just like any other tasking function.
Last updated