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()
: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.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: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.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.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:upload
command. Let's take that as an example. The apfell
upload command takes two parameters:remote_path
- a parameter of type String
that indicates the remote path of where the file will be uploaded tofile
- a parameter of type File
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.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 our upload
example, this parameter was simply called file
, so that's what you see here. In other commands, that parameter could be called anything though.files
parameter is an array of entries. Otherwise, you call the mythic.create_task
just like any other tasking function.