Getting Started

All interactions with Talus are performed through a REST API. Currently the only UI to talus that uses the REST API is a command line interface: talus_client.

Talus Client

The talus_client is python-based CLI that uses nested cmd.Cmd classes to allow the user to either peform actions interactively, or via command-line flags.

Installation

The talus_client module can be installed globally:

pip install --upgrade https://github.com/optiv-labs/talus_client.git@master#egg=talus_client

or locally:

pip install --user --upgrade https://github.com/optiv-labs/talus_client.git@master#egg=talus_client

or in a virtual environment (my preferred method):

virtualenv path_to_venv
source path_to_venv/bin/activate
pip install --upgrade https://github.com/optiv-labs/talus_client.git@master#egg=talus_client
...
# to exit the virtual environment, use the deactivate command
deactivate

Setup

When running the talus_client for the first time you will be prompted to enter the url where the talus REST API is available, as well as a username that you would like all models/jobs/images/etc to be tagged with that you create:

(venv)zorniger [ talus_client ]: talus
You don't have a ~/.talusrc. Give me the URL (and port) of the talus master web server.
E.g. http://some.host.name:55555
your turn: http://master.talus
Are you sure the host is 'http://master.talus'? (not a trick question) (y/n): y
cool
You also don't have a username. Make one up please (and be reasonable): james
You want to use 'james' as your username? (y/n) y
ok, nice to meet you, *quote* james *quote*
talus>

Information about the location of the talus REST API as well as your “username” are stored in a ~/.talusrc json file:

{"host": "http://master.talus", "user": "james"}

Usage

The talus_client is composed of nested cmd.Cmd modules. All commands can be performed via command-line flags:

talus job create task_1 --priority 80 --limit 1 --debug

Or interactively as shown below. Note that if you want to drop straight into one of the interactive create shells, use talus <cmd> create --shell:

(venv)zorniger [ talus_client ]: talus
talus> job
talus:job> create
  idx  name                           task.id
-----  -----------------------------  ------------------------
    0  task_1                         560eaf0f399892009811f19a
    1  task_2                         56297fa9c1d7d2002ccec2f8
    2  task_3                         566a6287a3bfb30003a36918
    3  task_4                         563131d59392d70102b3a321

Which task should the job be based on? (idx or q): 0
[+]  basing job on task named u'task_1' (560eaf0f399892009811f19a)
talus:job:create> show
name        value                                                            description
----------  ---------------------------------------------------------------  -------------------------------------------------------------------
status      {"name": "run"}                                                  Status of the job (don't touch)
priority    50                                                               Priority of the job (0-100, 100 == highest priority)
task        560eaf0f399892009811f19a                                         The task the job is based on
name        task_1 2015-10-29 10:40:39.142128                                The name of the job
tags        [u'james']                                                       Tags associated with this job
image       539d8714c3328350080b3df0                                         The image the job should run on
limit       5                                                                The limit for the task (when does it finish?)
vm_max      1800                                                             Max vm duration (s) before being forcefully terminated
queue       jobs                                                             The queue the job should be dripped into (normal use leave blank)
errors      []                                                               Errors the job has accumulated
params      {"iters": 3, "arg1": "yoyoyo", "arg2": "yoyoyoyoyoy", "comp1...  Parameters (inherited from the chosen task)
progress    None                                                             Current progress of the job (don't touch)
debug       False                                                            If the job should be run in debug mode (logs are always saved)
timestamps  {}                                                               Timestamps (don't touch)
logs        []                                                               Debug logs for this job
network     whitelist                                                        The network whitelist (E.g. 'whitelist:DOMAIN_1,IP_2,DOMAIN_3,...')
talus:job:create> set priority 80
talus:job:create> set limit 1
talus:job:create> set debug True
talus:job:create> save

Help

All commands in the talus_client have a help command that accepts another command as an argument and will display a (hopefully) helpful help message:

(venv)zorniger [ Documents ]: talus image help import
     import   -   Import an image into Talus

                  import FILE -n NAME -o OSID [-d DESC] [-t TAG1,TAG2,..] [-u USER] [-p PASS] [-i]

                              FILE    The file to import
                           -o,--os    ID or name of the operating system model
                         -n,--name    The name of the resulting image (default: basename(FILE))
                         -d,--desc    A description of the image (default: "")
                         -t,--tags    Tags associated with the image (default: [])
                      -f,--file-id    The id of an already-uploaded file (NOT A NORMAL USE CASE)
                     -u,--username    The username to be used in the image (default: user)
                     -p,--password    The password to be used in the image (default: password)
                  -i,--interactive    To interact with the imported image for setup (default: False)

                  Examples:

                  To import an image from VMWare at ``~/images/win7pro.vmdk`` named "win 7 pro test"
                  and to be given a chance to perform some manual setup/checks:

                      image import ~/images/win7pro.vmdk -n "win 7 pro test" -i -o "win7pro" -t windows7,x64,IE8

Notes

It should also be noted that current actions in the talus_client can be cancelled with CTRL-C. Using the exit or similar commands do not cancel the current action.

Creating Images

Images are created and configured on the master node via a remote VNC connection (usually port 59XX). Vagrant is used during the configuration of images to provide users the flexibility of automatically configuring the image via a Vagrantfile (via a --vagrantfile or -v flag in configure, import and create client commands), or to manually (interactively) configure the image (via a --interactive or -i flag).

Creating, importing, or configuring an image without the -i flag will cause the master to shut down and save the VM once the Vagrantfile has finished running.

From Scratch

Creating a base image is done via the talus image import command:

(venv)zorniger [ Documents ]: talus image help import
     import   -   Import an image into Talus

                  import FILE -n NAME -o OSID [-d DESC] [-t TAG1,TAG2,..] [-u USER] [-p PASS] [-i]

                              FILE    The file to import
                           -o,--os    ID or name of the operating system model
                         -n,--name    The name of the resulting image (default: basename(FILE))
                         -d,--desc    A description of the image (default: "")
                         -t,--tags    Tags associated with the image (default: [])
                      -f,--file-id    The id of an already-uploaded file (NOT A NORMAL USE CASE)
                     -u,--username    The username to be used in the image (default: user)
                     -p,--password    The password to be used in the image (default: password)
                  -i,--interactive    To interact with the imported image for setup (default: False)

To import an image from VMWare at ~/images/win7pro.vmdk named win 7 pro test and to be given a chance to perform some manual setup/checks:

talus image import ~/images/win7pro.vmdk -n "win 7 pro test" -i -o "win7pro" -t windows7,x64,IE8

Note that a valid OS id must be supplied, which can be created via talus os create. Existing OS models can be listed via talus os list.

To “save” the image, nicely shut down the VM (if it was configured interactively). The image’s status will change to “ready” once it can be used again.

From a Base Image

It is preferred that base images are kept fairly clean, with minimal code/programs required to work with talus. Images with specific pre-installed requirements should be a new image that is based on a clean base image.

(venv)zorniger [ Documents ]: talus image help create
     create   -   Create a new image in talus using an existing base
                  image. Anything not explicitlyspecified will be
                  inherited from the base image, except for the name,
                  which is required.


                  create -n NAME -b BASEID_NAME [-d DESC] [-t TAG1,TAG2,..] [-u USER] [-p PASS] [-o OSID] [-i]

                           -o,--os    ID or name of the operating system model
                         -b,--base    ID or name of the base image
                         -n,--name    The name of the resulting image (default: basename(FILE))
                         -d,--desc    A description of the image (default: "")
                         -t,--tags    Tags associated with the image (default: [])
                           --shell    Forcefully drop into an interactive shell
                  -v,--vagrantfile    A vagrant file that will be used to congfigure the image
                  -i,--interactive    To interact with the imported image for setup (default: False)

To create a new image based on the image with id 222222222222222222222222 and adding a new description and allowing for manual user setup:

talus image create -b 222222222222222222222222 -d "some new description" -i

To “save” the image, nicely shut down the VM (if it was configured interactively). The image’s status will change to “ready” once it can be used again.

(re)Configuring an Existing Image

Images are allowed to be reconfigured if no images are based on the image that you want to configure. Both configuration flags apply here was well (-v to specify a Vagrantfile and -i to configure the image interactively):

(venv)zorniger [ Documents ]: talus image help configure
  configure   -   Configure an existing image in talus

                  configure ID_OR_NAME [-v PATH_TO_VAGRANTFILE] [-i]

                        id_or_name    The ID or name of the image that is to be configured (required)
                  -i,--interactive    To interact with the imported image for setup (default: False)
                  -v,--vagrantfile    The path to the vagrantfile that should be used to configure the image (default=None)

To configure an image named Windows 7 x64 Test, using a vagrantfile found at ~/vagrantfiles/UpdateIE with no interaction:

talus image configure "Windows 7 x64 Test" --vagrantfile ~/vagrantfiles/UpdateIE

To “save” the image, nicely shut down the VM. The image’s status will change to “ready” once it can be used again.

Setting up an Image

When configuring an image, all VMs should have full network access, including to the host (master) machine. As part of the install process, the master should have been setup with an /install/ directory at the root of its webserver at http://192.168.122.1/install/. The install directory should contain the prebootstrap.py and setup instructions. This would be a good place to put any commonly required installers/packages, etc. (in the /talus/install directory on the master server).

_images/image_configure_install_host.png

Drivers

Images being configured will also have a CDROM mounted containing necessary libvirt drivers for windows (virtio, ethernet adapters, etc). Be sure to check device manager on windows and install drivers from the CDROM for any unrecognized hardware.

Prebootstrap

Download the prebootstrap.py from http://192.168.122.1/install/prebootstrap.py from inside the VM when configuring. The prebootstrap needs to be setup to run on startup. An easy way to do this is to place a link to the prebootstrap in the Startup folder.

General Requirements

Below is a list of other requirements that should be installed/setup in the VM

  • no access control (no UAC, passwordless sudo, etc)
  • automatic login
  • turn off auto-updates
  • change appearance/performance to favor performance over appearance
  • username/password set to “user/password” (this _can_ be different, but it’s easiest to work with the default of user/password)
  • Python 2.7 installed and added to the PATH environment variable
  • pip installed (should come installed by default with the latest versions of Python 2.7.X)
  • run pip install requests pymongo
  • python lxml package (download the installer, don’t do this via pip)

Windows Requirements

  • sysinternals tools added to sys.path, also with EULA having been agreed to on each exe (mainly need PsExec).
  • pip install comtypes
  • windbg
  • !exploitable (msec.dll)
  • VCRedist 2012 x86 and x64 (if applicable)
  • WinRM setup:
winrm quickconfig -q
winrm set winrm/config/winrs @{MaxMemoryPerShellMB="512"}
winrm set winrm/config @{MaxTimeoutms="1800000"}
winrm set winrm/config/service @{AllowUnencrypted="true"}
winrm set winrm/config/service/auth @{Basic="true"}
sc config WinRM start= auto

Also note that all created networks in the VM must be set the “Work” network. This can be set to be the default action by opening:

  1. Open “gpedit.msc”
  2. Go to Computer Configration
  3. Windows Settings
  4. Security Settings
  5. Network list manager

Set the appropriate settings to make all networks automatically be marked as a private (trusted) network.

Tools & Components

Definitions

Talus is built around the idea that tools written to run inside of VMs should be highly configurable from a UI. This should prevent the user from having to re-configure VM images every time dependencies change, and should also keep the user from having to change their code every time he/she needs to tweak its operation.

A Tool is a user-defined class that is run inside the VM once all dependencies have been installed. The run method on an instantiated tool is run once per vm. Tools must list and document their parameters. Tool parameters can be any native python type (str, float, int, etc), a talus Component, or a talus FileSet

a Component is a user-defined class of reusable code. These are intended to be used by a tool in order to perform utility functions. For example, a debugger could be a tool, or a web server, or a file downloader. One component could be written and then reused by multiple different tools. For example, a debugger component could be written and then used by a browser fuzzer tool, a pdb fuzzing tools, etc. A Component must also document all parameters to its init method, using the same format and types as are required with tool classes.

A tool that lists a component as a parameter will be passed an instantiated component of the specified type.

One of the major benefits of this setup is that users can use polymorphism with their components. Back to the debugger example, a generic IDebugger interface could be created that exposes certain functionality/methods. Specific debugger implementations could then subclass the IDebugger component to provide specific functionality (e.g. separate debuggers for Windows, Linux, and Mac). Tools that require a debugger could then set the type of their debugger parameter to an IDebugger component. When configuring the tool to be run, the user will then be able to choose which specific class to use (the windows debugger, linux, or mac debugger).

Separating components from tools allows tools to perform actions without needing to know the configuration details.

Examples

The documented parameters in tools and components are parsed out of the source code and validated in a pre-receive hook in the talus master git repository. Useful error messages should be returned if invalid parameters are specified.

Below is a TestTool class that accepts four parameters - two strings, an integer, and a component:

from talus.tools import Tool

class TestTool(Tool):
    """This is a description for the TestTool
    """

    def run(self, arg1, arg2, comp1, iters):
        """Run the Template tool with a few args and a component

        :param str arg1: The first argument (a string)
        :param str arg2: The second argument (a string)
        :param int iters: The number of times to report progress
        :param Component(ComponentTemplate) comp1: The third argument (an instantiated Template component)
        """
        for x in xrange(iters):
            comp1.do_sometheing(arg1, arg2)
            self.progress(1)

Notice how the parameters are documented within the docstring. These parameters are directly used to configure the Tool before it is run inside the VMs. Below is an example of configuring the test tool above using the talus_client:

talus:job:create> set params

Editing params

talus:job:create:params> show
name    type               value                                         description
------  -----------------  --------------------------------------------  -------------------------------------------------------
arg1    str                None                                          The first argument (a string)
arg2    str                None                                          The second argument (a string)
iters   int                None                                          The number of times to report progress
comp1   ComponentTemplate  (ComponentTemplate) {u'prefix': None}         The third argument (an instantiated Template component)

Git Repo

All tools and components that are to be run through talus must exist in the git repository found on the talus master server. Users can clone the git repository like so:

git clone git+ssh://USER@TALUS_MASTER/talus/talus_code.git

USER should be your username on the talus master server. Users need to be a member of the talus group in order to clone the code repository.

Creating New Code

Code can manually be manually created by creating a new tool/component folder in the talus/tools or talus/components folder. The name of the tool’s directory must be the underscore-cased equivalent of the pascal-cased class name (confusing, I know). For example, the TestTool class must exist in an __init__.py file in the talus/tools/test_tool/ directory.

This can also be performed through the talus_client using the code create comamnd:

create   -   Create new code in the repository. This will create
              the code in the talus repository, as well as in the
              database.


              code create NAME -t or -c

                   -t,--tool    Create a tool
              -c,--component    Create a component

The example below will cause a new tool name DemoTool to be created in the git repository:

talus code create -t DemoTool

After running the above command, users should see their newly-created tool when they pull remote changes to the git repository:

(venv)zorniger [ talus_client ]: talus code create -t DemoTool
[.]  git pull to see your new tool
(venv)zorniger [ talus_client ]: cd /tmp/talus_code/
(venv)zorniger [ talus_code ]: git pull
remote: Counting objects: 10, done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 7 (delta 3), reused 0 (delta 0)
Unpacking objects: 100% (7/7), done.
From git+ssh://master.talus/talus/talus_code
   300d128..a8c01ee  master     -> origin/master
Updating 300d128..a8c01ee
Fast-forward
 talus/tools/demo_tool/__init__.py      | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 talus/tools/demo_tool/requirements.txt |  1 +
 talus/tools/demo_tool/run_local.py     | 14 ++++++++++++++
 3 files changed, 76 insertions(+)
 create mode 100644 talus/tools/demo_tool/__init__.py
 create mode 100644 talus/tools/demo_tool/requirements.txt
 create mode 100644 talus/tools/demo_tool/run_local.py

Creating a Task

Tasks can be thought of as templates that contain default settings for running a tool. Tasks are created through the talus client either interactively, or through command-line parameters:

create   -   Create a new task in Talus

             create -n NAME -t TOOL_ID_OR_NAME -p PARAMS -l LIMIT

                     -n,--name    The name of the new task (required, no default)
                     -t,--tool    The name or id of the tool to be run by the task (required, no default)
                    -l,--limit    The limit for the task. What the limit means is defined by how the tool
                                  reports progress. If the tool does not report progress, then the limit
                                  means the number of total VMs to run.
                      --vm-max    Maximum amount of time a vm should be allowed to run (defaults to 30m)
                                  You may use values such as 30m15s. If no units are used, the value is
                                  assumed to be in seconds.
                   -p,--params    The params of the task
                       --shell    Create the task in an interactive shell (default if already in shell and no args)
                  -v,--version    The version the task should be pinned at, else the current HEAD (default=None)
              -f,--params-file    The file that contains the params of the task

To create a new task that uses the tool “BrowserFuzzer”:

To create a new task that also uses the “BrowserFuzzer” tool but reads in the params from a file and has a max vm runtime of 45 minutes 10 seconds:

task create -n "IE Fuzzer" -t "BrowserFuzzer" -f ie_fuzz_params.json --vm-max 45m10s

Note that using command-line options to set the default paramters for tools and components is very unwieldy and extremely tedious. It is HIGHLY recommended that you use the interactive mode to create tasks instead:

(venv)zorniger [ talus_code ]: talus
ttalus> task
talus:task> create
talus:task:create> show
name        value       description
----------  ----------  --------------------------------------------------------------------
version     None        The version of code the task should run on (leave blank for default)
params      {}          The parameters for the tool
name                    The name of the task
tags        [u'james']  Tags associated with this task
timestamps  {}          Timestamps (don't mess with this)
tool        None        The tool the task should run
limit       1           Limit for the task (when does it finish?)
image       None        The default image for this task
vm_max      1800        Max vm duration (s) before being forcefully terminated
network     whitelist   The network whitelist (E.g. 'whitelist:DOMAIN_1,IP_2,DOMAIN_3,...')
talus:task:create> set name "the name of the task"

Tasks can be listed using the talus task list command.

Creating and Running a Job

Jobs are instances of a task that have been run. Job parameters should never be edited, as they preserve the state that the job was run under (to help with reproducibility, etc.)

Creating a job is nearly identical to creating a task, and can be done through both the command-line and interactive modes. If no changes to the default task settings need to be made, all that must be provided to run a job is the task name or id.

An optional --debug flag exists when creating a job. This will cause the master daemon to spin up at most --limit VMs, and will also cause all messages logged in the tool via self.log.{debug,info,error,warn,etc} to be saved to the database.

Limit and Progress

The limit attribute on a job determines when a job will be finished. The limit can be any positive integer or -1. A value of -1 means that the job will run forever until the user cancels the job.

By default, if a successfully run tool did not explicitly increment the job’s progress via self.progress(), the job’s overall progress is automatically incremented by 1. For example, tools may choose to increment the job’s progress for every 100 iterations of a fuzzer by doing something similar to:

def run(self, ...):
    """...
    """
    count = 0
    for x in xrange(iters):
        count += 1
        if x % 100 == 0:
            self.progress(count)
            count = 0
        self.perform_iteration()
    # report any unreported iterations
    self.progress(count)

This will allow the user to treat the --limit of the job as total number of iterations required. Talus will continue to spin up as many VMs as possible (according the job’s priority) until the limit has been reached.

Priorities

A job may also have a priority. Priority values can be anything between 0 and 100. The master daemon maintains a priority queue that it uses to add batches of job parts into the jobs queue when the queue is empty. This allows one job to preempt other lower-piority jobs. This also allows users to start never-ending jobs that can run with an extremely low priority.

Job Status/Info

A job’s status, current speed (how many progress increments/time), overall progress, and details of currently-running VMs for that job can be viewed using the talus job info command:

info   -   List detailed information about the job.

           Git-like syntax can also be used here to refer to the most recently created
           job. E.g. the command below will show info about the 2nd most recent job:

               job info +2

           Search information can also be used. If git-like syntax is omitted, only
           the first entry returned from the database will be displayed.

               job info --all --status running --sort -priority +2

           The example above will show information about 2nd highest priority job whose
           status is running. Omitting --all will cause the search to be performed only
           among _your_ jobs.

Below is an example of output from the job info command:

(venv)zorniger [ talus_client ]: talus job info +1
[+]  default filtering by username (searching for tags = james)
[+]  use --all to view all models

         ID: 5633c7808fa3e20018c34afc
       Name: test_task 2015-10-30 14:39:44.111238
     Status: running
       Tags: [u'james', u'']
    Started: seconds ago (2015-10-30 14:39:44)
      Ended:
      Debug: False
      Speed: 0.0/s, 0.0/min, 0.0/hour, 0.0/day
   Progress: 0.0% (0 / 20)
       Task: crash_test_task (560eaf0f39489200081ff19a)
   Priority: 50
     Params: {"iters": 3, "arg1": "yoyoyo", "arg2": "yoyoyoyoyoy", "comp1": {"params": {"prefix": "blahblah"}, "class": "ComponentTemplate"}}
    Network: whitelist
      Image: win7 (563d827413a25300090faa02)
     VM Max: 1800
Running VMS:

slave           vnc port  running since      job idx  status        |  slave           vnc port  running since      job idx  status
------------  ----------  ---------------  ---------  ------------  |  ------------  ----------  ---------------  ---------  --------
slave.talus2        5948  seconds ago              1  running tool  |  master.talus        5919  seconds ago              2  booting
slave.talus2        5949  seconds ago              3  running tool  |  master.talus        5915  seconds ago              6  booting
slave.talus2        5912  seconds ago              5  running tool  |  master.talus        5907  seconds ago             11  booting
slave.talus2        5901  seconds ago             10  running tool  |  master.talus        5900  seconds ago             14  booting
slave.talus2        5902  seconds ago             13  running tool  |  master.talus        5910  seconds ago             15  booting
slave.talus2        5913  seconds ago             19  running tool  |  slave.talus1        5940  seconds ago             24  booting
slave.talus2        5903  seconds ago             21  running tool  |  slave.talus1        5939  seconds ago             30  booting
slave.talus2        5909  seconds ago             23  running tool  |  slave.talus1        5930  seconds ago             36  booting
slave.talus3        5910  seconds ago             26  running tool  |  slave.talus1        5941  seconds ago             40  booting
slave.talus3        5917  seconds ago             27  running tool  |  slave.talus1        5938  seconds ago             41  booting
slave.talus3        5918  seconds ago             29  running tool  |  slave.talus1        5926  seconds ago             59  booting
slave.talus3        5907  seconds ago             32  running tool  |  slave.talus1        5924  seconds ago             69  booting
slave.talus3        5919  seconds ago             35  running tool  |  slave.talus1        5922  seconds ago             70  booting
slave.talus3        5920  seconds ago             39  running tool  |  slave.talus1        5925  seconds ago             72  booting
slave.talus3        5906  seconds ago             46  running tool  |  slave.talus1        5933  seconds ago             73  booting
slave.talus3        5905  seconds ago             48  running tool  |  slave.talus2        5929  seconds ago             75  booting
slave.talus3        5914  seconds ago             49  booting       |  slave.talus2        5942  seconds ago             76  booting
slave.talus3        5911  seconds ago             52  running tool  |

Results

Adding

Results are added from a tool by using the self.result(TYPE, DATA) method. This cause the result of type TYPE to be added to the database. Information about the job, tool, timestamps, etc will be automatically added to the result in the database.

For example, to save data about a crash, you would set the type to "crash", and add the crash information as the data parameter:

class CrashTestTool(Tool):
    """...
    """
    file_id = self.add_file(
        "REPRO DATA",
        content_type="application/json",
        filename="this_was_the_filename.json"
    )
    self.result("crash", {
        "registers": {
            "eip": int(random.random() * 0xffffffff),
            "eax": int(random.random() * 0xffffffff),
            "ecx": int(random.random() * 0xffffffff),
            "edx": int(random.random() * 0xffffffff),
            "ebx": int(random.random() * 0xffffffff),
            "esp": int(random.random() * 0xffffffff),
        },
        "backtrace": [

        ],
        "disassembly": [
            "0000fff0 int 3",
            "0000fff1 int 3",
            "0000fff2 int 3",
            "--> 0000fff3 {}".format(random.choice(["jmp eax", "mov eax,[ecx+12]", "ret", "call [ebx]", "lea ecx,[eax+1080]"])),
            "0000fff4 ret",
        ],
        "hash_major": random.choice(["bucket1", "bucket2", "bucket3"]),
        "hash_minor": random.choice(["minor_bucket1", "minor_bucket2", "minor_bucket3"]),
        "exploitability": random.choice(["EXPLOITABLE", "NOTEXPLOITABLE", "UNLIKELY"]),
        # a list of files for reproducing the bug
        "repro": [
            file_id,
        ],
    })

Listing

Results can be listed using the talus result list command. Standard search queries can be used, as with all other search methods:

(venv)zorniger [ talus_client ]: talus result list --job 563117bd9392d70008b30324 --num 10 --tags result_test
[+]  searching for job = 563117bd9392d70008b30324
[+]  searching for num = 10
[+]  searching for tags = result_test
[+]  default filtering by username (searching for tags = james)
[+]  use --all to view all models
id                        tags                        type    tool           created                     job                       data
------------------------  --------------------------  ------  -------------  --------------------------  ------------------------  ----------------------------------------
563118cfd8fb8d38907eec7e  [u'james', u'result_test']  crash   CrashTestTool  2015-10-28T12:49:51.740000  563117bd9392d70008b30324  {u'backtrace': [], u'repro': [u'56317b33
563118c6d8fb8d38907eec75  [u'james', u'result_test']  crash   CrashTestTool  2015-10-28T12:49:42.759000  563117bd9392d70008b30324  {u'backtrace': [], u'repro': [u'56317b30
563118c6d8fb8d38907eec74  [u'james', u'result_test']  crash   CrashTestTool  2015-10-28T12:49:42.478000  563117bd9392d70008b30324  {u'backtrace': [], u'repro': [u'56317b2b
563118c0d8fb8d38907eec6d  [u'james', u'result_test']  crash   CrashTestTool  2015-10-28T12:49:36.671000  563117bd9392d70008b30324  {u'backtrace': [], u'repro': [u'56317b26
563118bdd8fb8d38907eec69  [u'james', u'result_test']  crash   CrashTestTool  2015-10-28T12:49:33.002000  563117bd9392d70008b30324  {u'backtrace': [], u'repro': [u'56317b29
563118b6d8fb8d38907eec62  [u'james', u'result_test']  crash   CrashTestTool  2015-10-28T12:49:26.817000  563117bd9392d70008b30324  {u'backtrace': [], u'repro': [u'56317b20
563118b0d8fb8d38907eec5c  [u'james', u'result_test']  crash   CrashTestTool  2015-10-28T12:49:20.540000  563117bd9392d70008b30324  {u'backtrace': [], u'repro': [u'56317b1c
563118afd8fb8d38907eec59  [u'james', u'result_test']  crash   CrashTestTool  2015-10-28T12:49:19.486000  563117bd9392d70008b30324  {u'backtrace': [], u'repro': [u'56317b1a
563118acd8fb8d38907eec55  [u'james', u'result_test']  crash   CrashTestTool  2015-10-28T12:49:16.318000  563117bd9392d70008b30324  {u'backtrace': [], u'repro': [u'56317b17
563118aad8fb8d38907eec52  [u'james', u'result_test']  crash   CrashTestTool  2015-10-28T12:49:14.802000  563117bd9392d70008b30324  {u'backtrace': [], u'repro': [u'56317b16

Crashes

A crash-specific result-type command can be used to view crashes, crash details, and export crash data.

Listing

Listing crashes is performed with the talus crash list command:

list   -   List crashes in talus. Fields to be searched for
           must be turned into parameter format (E.g.
           ``--search-item "some value"`` format would search

           for a result with the field ``search_item`` equaling ``some value``).

           Examples:
               crash list --search-item "search value" [--search-item2 "search value2" ...]
               crash list --registers.eip 0x41414141
               crash list --all --tags browser_fuzzing
               crash list --exploitability EXPLOITABLE
               crash list --\$where "(this.data.registers.eax + 0x59816867) == this.data.registers.eip"

Below is a simple example of using the crash list command:

(venv)zorniger [ talus_client ]: talus crash list --tags result_test --num 10
[+]  searching for tags = result_test
[+]  searching for num = 10
[+]  default filtering by username (searching for tags = james)
[+]  use --all to view all models
id                        tool           created     exploitability    hash                   instr               registers
------------------------  -------------  ----------  ----------------  ---------------------  ------------------  -------------------------
563118cfd8fb8d38907eec7e  CrashTestTool  2 days ago  EXPLOITABLE       bucket3:minor_bucket3  ret
563118c6d8fb8d38907eec75  CrashTestTool  2 days ago  EXPLOITABLE       bucket2:minor_bucket1  call [ebx]          ebx:227faccc
563118c6d8fb8d38907eec74  CrashTestTool  2 days ago  UNLIKELY          bucket2:minor_bucket2  lea ecx,[eax+1080]  eax:4a358661 ecx:24f6c0d8
563118c0d8fb8d38907eec6d  CrashTestTool  2 days ago  EXPLOITABLE       bucket2:minor_bucket1  jmp eax             eax:a5a76cb6
563118bdd8fb8d38907eec69  CrashTestTool  2 days ago  NOTEXPLOITABLE    bucket3:minor_bucket3  ret
563118b6d8fb8d38907eec62  CrashTestTool  2 days ago  NOTEXPLOITABLE    bucket1:minor_bucket2  mov eax,[ecx+12]    eax:ba014e3e ecx:607ce892
563118b0d8fb8d38907eec5c  CrashTestTool  2 days ago  NOTEXPLOITABLE    bucket3:minor_bucket3  call [ebx]          ebx:b32b4d80
563118afd8fb8d38907eec59  CrashTestTool  2 days ago  UNLIKELY          bucket2:minor_bucket1  mov eax,[ecx+12]    eax:a7bf6d02 ecx:a963a5f7
563118acd8fb8d38907eec55  CrashTestTool  2 days ago  NOTEXPLOITABLE    bucket2:minor_bucket1  jmp eax             eax:e8a66627
563118aad8fb8d38907eec52  CrashTestTool  2 days ago  NOTEXPLOITABLE    bucket2:minor_bucket3  call [ebx]          ebx:56cf65d3

Info

Crash info can be dumped using the talus crash info command. If you want to see all details of a crash, add the --details flag:

info   -   List detailed information about the crash.

           Git-like syntax can also be used here to refer to the most recently created
           crash result. E.g. the command below will show info about the 2nd most recent crash:

               crash info +2

           Search information can also be used. If git-like syntax is omitted, only
           the first entry returned from the database will be displayed.

               crash info --all --registers.eip 0x41414141 --sort registers.eax +1

           The example above will show information about the crash with the lowest eax value
           (+2 would show the 2nd lowest) that has an eip 0f 0x41414141.  Omitting --all will
           cause the search to be performed only among _your_ crashes.

           To view _all_ of the details about a crash, add the --details flag.

Below is the output of a real example of viewing crash info:

(venv)zorniger [ talus_client ]: talus crash info --tags result_test +2
[+]  searching for tags = result_test
[+]  default filtering by username (searching for tags = james)
[+]  use --all to view all models

              ID: 563118c6d8fb8d38907eec75
             Job: james_test_test9 (563117bd9392d70008b30324)
  Exploitability: EXPLOITABLE
Hash Major/Minor: bucket2 minor_bucket1
     Crash Instr: call [ebx]
    Crash Module:
  Exception Code:        0

          -------------------  |  ---  --------  |  ---  --------
          0000fff0 int 3       |  eip  e05576cf  |  edx  c77df43e
          0000fff1 int 3       |  esp  7ad6c630  |  ebx  227faccc
          0000fff2 int 3       |  eax  d9535dd8  |  ecx  e5dc9909
          0000fff3 call [ebx]  |  ---  --------  |  ---  --------
          0000fff4 ret
          -------------------

Exporting

Crashes can be exported as well. Standard search-syntax can be used to choose which crash to export. An optional --dest parameter can be used to specify an output directory that the crash should be saved into:

export   -   Export crash information to the target directory.
             Crashes are identified usinggit-like syntax, ids,
             and/or search queries, as with the info commands:


                 crash export --tags IE +2

             The above command will export the 2nd most recent crash (+2) that belongs to you and
             contains the tag "IE".

             By default crashes will be saved into the current working directory. Use the --dest
             argument to specify a different output directory:

                 crash export +1 --all --tags adobe --dest adobe_crashes

             The more complicated example below will search among all crashes (--all, vs only
             those tagged with your username) for ones that have an exploitability category of
             EXPLOITABLE and crashing module of libxml. The second crash (+2) will be chosen
             after sorting by data.registers.eax

                 crash export --all --exploitability EXPLOITABLE --crashing_module libxml --sort data.registers.eax +2

A real example (with output) of the export command is shown below:

(venv)zorniger [ talus_client ]: talus crash export --tags result_test +2 --dest /tmp/crashes
[+]  searching for tags = result_test
[+]  searching for dest = /tmp/crashes
[+]  default filtering by username (searching for tags = james)
[+]  use --all to view all models
[.]  exporting crash 563118c6d8fb8d38907eec75 from job james_test_test9 (563117bd9392d70008b30324)
[.]  saving to /tmp/crashes/ultimate_hood_563118c6d8fb8d38907eec75
[+]  /tmp/crashes/ultimate_hood_563118c6d8fb8d38907eec75/crash.json
[+]  /tmp/crashes/ultimate_hood_563118c6d8fb8d38907eec75/crash.txt
[+]  /tmp/crashes/ultimate_hood_563118c6d8fb8d38907eec75/repro/this_was_the_filename.json
[.]  done exporting crash

Notice how the crash folder takes the form ADJECTIVE_NOUN_ID. This is done to make remembering individual crashes easier. Long numbers aren’t something we are inherently good at remembering or differentiating.

Slave Status/Info

Status of all active slaves can be listed using the talus slave list command:

(venv)zorniger [ talus_client ]: talus slave list
id                        hostname      ip              max_vms    running_vms
------------------------  ------------  --------------  ---------  -------------
56326a6bd2fb8d2234aeaab5  master.talus   1.1.1.2          5              0
56326ccad2fb8d2234aeaab1  slave1.talus   1.1.1.3         10              0
56326a12d2fb8d2234aeaab2  slave2.talus   1.1.1.4         10              0
56326a12d2fb8d2234aeaac3  slave3.talus   1.1.1.5         10              0

Individual information about a slave can be viewed using the talus slave info command:

(venv)zorniger [ talus_client ]: talus slave info slave2.talus

         ID: 56326a12d2fb8d2234aeaab2
       UUID: bf6a8a96-4c9c-45d5-6788-149c85363122
   Hostname: slave2.talus
    IP Addr: 1.1.1.4
   Jobs Run: 67
    Max VMs: 10
Running VMs: 10

    tool        vnc  running since    job                         job idx
    --------  -----  ---------------  ------------------------  ---------
    TestTool   5910  seconds ago      5633c7808fa3e20018c34afc          7
    TestTool   5906  seconds ago      5633c7808fa3e20018c34afc         10
    TestTool   5907  seconds ago      5633c7808fa3e20018c34afc         13
    TestTool   5917  seconds ago      5633c7808fa3e20018c34afc         15
    TestTool   5921  seconds ago      5633c7808fa3e20018c34afc         16
    TestTool   5902  seconds ago      5633c7808fa3e20018c34afc         17
    TestTool   5927  seconds ago      5633c7808fa3e20018c34afc         19
    TestTool   5931  seconds ago      5633c7808fa3e20018c34afc         21
    TestTool   5929  seconds ago      5633c7808fa3e20018c34afc         31
    TestTool   5928  seconds ago      5633c7808fa3e20018c34afc         34

Master Status/Info

Overall information about talus and the master daemon can be viewed with the command talus master info:

(venv)zorniger [ talus_client ]: talus master info

hostname: master.talus
      ip: 1.1.1.2
     vms: None
  queues:
          jobs
                priority  job name                              job id                    prog/limit    tags
              ----------  ------------------------------------  ------------------------  ------------  ---------------
                      50  test_task 2015-10-30 14:39:44.111238  5633c7808fa3e20018c34afc  0 / 20        [u'james', u'']

The master info command will show all VMs that are currently running as part of image configuration (under the vms: section), and will also show the current state of its priority queue, with the highest priority and job that gets first-dibs on resources at the top of the list.