carbonblackliveresponse

Collect information and take action on remote endpoints in real time with VMware Carbon Black EDR (Live Response API) (formerly known as Carbon Black Enterprise Live Response).

Endpoint · Carbon Black Enterprise Live Response

Details

IDcarbonblackliveresponse
ProviderBroadcom
CategoryEndpoint
From Version5.0.0
Supported ModulesAgentix XSIAM EDR Cortex Cloud Cloud Runtime Security

README

Overview

Use the VMware Carbon Black EDR (Live Response API) integration (formerly known as Carbon Black Enterprise Live Response) to enable security operators to collect information and take action on remote endpoints in real time.

VMware Carbon Black EDR (Live Response API) Integration is configurable with both VMware Carbon Black EDR (formerly known as Carbon Black Response) and VMware Carbon Black Endpoint Standard (formerly known as Carbon Black Defense).

Use Cases

  • Upload, download, and remove files.
  • Retrieve and remove registry entries.
  • Dump contents of physical memory.
  • Execute and terminate processes.

Playbooks

  • Carbonblackliveresponse playbook
  • Carbon Black Live Response - Wait until command complete
  • Carbon Black Live Response - Create active session
  • Carbon Black Live Response - Download file

Prerequisites

This integration can be used on either VMware Carbon Black EDR (formerly known as Carbon Black Response) or VMware Carbon Black Endpoint Standard (formerly known as Carbon Black Defense).

Carbon Black Live Response

Enable the Live Response API and get an API key. Live Response is disabled by default. If you attempt to use the Live Response integration before enabling it you receive a code 412 error message.

  1. In the /etc/cb/cb.conf file, set CbLREnabled=True, to enable Live Response in your Carbon Black Response server.
  2. Restart the Carbon Black Enterprise services to activate the changes.

Get an API key

Each user in VMware Carbon Black EDR has a personal API key. The API key confers all rights and capabilities assigned to that user to anyone with access to that API key. Therefore, treat your API key as you would your password.

If the API Token is missing or compromised, you can reset the API key to generate a new token and revoke any previous API keys issued to a user.

  1. Log in to the Carbon Black console.
  2. Click the username in the upper right and select Profile info.
  3. Click API Token on the left hand side to reveal your API token. If there is no API token displayed, click Reset to create a new one.

VMware Carbon Black Endpoint Standard

Retrieve an apiKey and connectorId from the Carbon Black environment. 

  1. Navigate to SettingsConnector.
  2. Set up a VMware API Connector. This gives you access to the apiKey and connectorId.

Configure VMware Carbon Black EDR (Live Response API) on Cortex XSOAR

You can set up the integration to work with either VMware Carbon Black EDR or VMware Carbon Black Endpoint Standard.

Set the required fields to suit your instance ONLY.

To set up the integration to work with VMware Carbon Black EDR:

  1. Navigate to Settings > Integrations > Servers & Services.
  2. Search for carbonblackliveresponse.
  3. Click _Add instance to create and configure a new integration instance.
    • Name: a textual name for the integration instance.
    • Server URL: The hostname or IP address and port of the VMware Carbon Black EDR server used.
    • API Token (CB Response): The VMware Carbon Black EDR API token.
  1. Click Test to validate the URLs, token, and connection.

To set up the integration to work with VMware Carbon Black Endpoint Standard:

  1. Navigate to Settings > Integrations > Servers & Services.
  2. Search for carbonblackliveresponse.
  3. Click _Add instance to create and configure a new integration instance.
    • Name: a textual name for the integration instance.
    • Server URL: The hostname or IP address and port of the VMware Carbon Black Endpoint Standard server used.
    • API Token (CB Defense): The VMware Carbon Black Endpoint Standard API token.
    • Connector ID (CB Defense): The VMware Carbon Black Endpoint Standard connector ID.
  1. Click Test to validate the URLs, token, and connection.

 

Using Live Response Integration

Establish a session with the sensor, to enable commands to be sent to an endpoint.

A sensor with an active session will keep an open connection to the Carbon Black server for as long as the session is active. Sessions are kept for a timeout period, and then recycled.

When executing Live response commands, you can either establish a new session with the sensor or execute commands without session management.

Establish a new session with the sensor and execute commands

  • Enables you to execute multiple commands on the endpoint with one continues session. 
  • Faster execution time per command.
  • Requires session management.

Establish a new session with a specified sensor

Create a new session using cb-session-create or cb-session-create-and-wait (for the session data to be returned only once active).
In the data returned you can find the session ID. This ID will be used to execute Live Response commands on the sensor and retrieve session information when needed.
Only one active session per sensor is allowed at a given time.

Execute Live Response commands providing the session ID

For example, !cb-directory-listing path="c:\" session=1234 wait-timeout=120

Command information will be returned once the command status is active or the wait-timeout has expired (in this case, the command status remains as pending).

In the case of timeout, you may inquire command status and retrieve the command data using cb-command-info.

You may run multiple Live Response commands on one running session, but note that each session has a timeout. This is the timeout that a sensor should wait between commands. If no command is issued over this timeout the sensor will quit.
To avoid session timeout:
- Set a longer timeout when creating a new session.
- Run the cb-keepalive command to reset session timeout.

Close the session using the cb-session-close command.

Execute commands without session management

  • Session management is automated.
  • Longer execution time per command.
  1. Execute Live Response commands providing the sensor ID, e.g. !cb-directory-listing path="c:\" sensor=1 wait-timeout=120
    This will automatically establish a new session with the endpoint, execute the command on the sensor and finally close the session.
    Command information will be returned once the command status is active or the wait-timeout has expired (in this case, the command status remains pending).
    In the case of timeout, you may inquire command status and retrieve the command data using cb-command-info.

Known Limitations

Session Limitations
Only one session per sensor is allowed at a given time. An error will occur when trying to open a new session for a sensor with existing active session.

Commands

You can execute these commands from the Cortex XSOAR CLI, as part of an automation, or in a playbook. After you successfully execute a command, a DBot message appears in the War Room with the command details.

  1. Archive a session: cb-archive
  2. Cancel a pending command: cb-command-cancel
  3. Display information for a command: cb-command-info
  4. Delete a file: cb-file-delete
  5. Download a file: cb-file-get
  6. Get a file's metadata: cb-file-info
  7. Upload a file to the Carbon Black server: cb-file-upload
  8. Keep a session alive: cb-keepalive
  9. List existing command instances for a session: cb-list-commands
  10. List files: cb-list-files
  11. List all sessions: cb-list-sessions
  12. Close a session: cb-session-close
  13. Create a new session: cb-session-create
  14. Create a new session and wait: cb-session-create-and-wait
  15. Get information about a session: cb-session-info
  16. Terminate a process: cb-process-kill
  17. List directories on the endpoint: cb-directory-listing
  18. Run an executable on an endpoint: cb-process-execute
  19. Endpoint memory dump: cb-memdump
  20. Create a command: cb-command-create
  21. Create a command and wait: cb-command-create-and-wait
  22. Terminate a process: cb-terminate-process
  23. Delete a file from an endpoint: cb-file-delete-from-endpoint
  24. Enumerate registry values: cb-registry-get-values
  25. Query for a registry value: cb-registry-query-value
  26. Create a new registry key: cb-registry-create-key
  27. Delete a registry key: cb-registry-delete-key
  28. Delete a registry value: cb-registry-delete-value
  29. Set a registry value: cb-registry-set-value
  30. Get a list of processes running on an endpoint: cb-process-list
  31. Get a file from an endpoint: cb-get-file-from-endpoint
  32. Save a file to an endpoint: cb-push-file-to-endpoint

1. Archive a session

Archives the specified session. If the session has no content the command fails.

Base Command

cb-archive

Input
Parameter Description Required
session Session ID to archive Required
  
Context Output

There is no context output for this command.

Command Example
cb-archive session=3997
Context Example
{
  "EntryID": "56@a8449d77-4188-4270-846a-396c5a20d1ef",
  "Extension": "zip",
  "Info": "zip",
  "MD5": "81e67ceddfa1dd2fa668840ffab869c0",
  "Name": "session-3951-archive.zip",
  "SHA1": "212ee624e5312d6e589018c23b708682499074f3",
  "SHA256": "64ef1bd46694f9da1ddc1820d3e5f32e147945f024ab8808b6daba4c6b9b1d86",
  "SSDeep": "96:+DAlcOC5Ee//Jbv6CAOYfyYbzz10xldoqbcdqcLE:+DucOa5bv6CdYXbzJ0x7oLLE",
  "Size": 3751,
  "Type": "gzip compressed data, was "/tmp/tmpvpb7Nt", last modified: Mon Aug  6 07:41:02 2018, max compression\n"
}
Human Readable Output

image

2. Cancel a pending command

Cancels the specified command. Only pending commands can be canceled.

Base Command

cb-command-cancel

Input
Parameter Description Required
session Session ID of command to cancel Required
command Command ID to cancel Required
 
Context Output

 

Path Description
CbLiveResponse.Commands.Status The command status.
CbLiveResponse.Commands.Hostname The hostname of the host running the command.
CbLiveResponse.Commands.CbSensorID The sensor ID.
CbLiveResponse.Commands.CommandName The command name.
CbLiveResponse.Commands.CbSessionID The session ID.
CbLiveResponse.Commands.CbCommandID The command ID.
CbLiveResponse.Commands.OperandObject  Object argument for the CbLive command.For example, for directory list this is the dir path.Click here for more information about the command objects. 
CbLiveResponse.Commands.CreateTime The command's time of creation.
CbLiveResponse.Commands.CommandCompletionTime

When the command was completed. (0 means the command is still in progress.)

CbLiveResponse.Commands.Result.Desc Result description.
CbLiveResponse.Commands.esult.Type Result type.
CbLiveResponse.Commands.Result.Code Result code.
 
Command Example
!cb-command-cancel command=1 session=348
Context Example
Human Readable Output
 

3. Display information for a command


Displays the information of the specified command.

Base Command

cb-command-info

Input
Parameter Description Required
session Session ID of the command Required
command Command ID Required
 
Context Output

There is no context output for this command.

Command Example
!cb-command-info command=1 session=348
Context Example
{
    "CbLiveResponse": {
        "Commands": {
            "CbCommandID": 1,
            "CbSensorID": 17,
            "CbSessionID": 348,
            "CommandCompletionTime": 1540228071.195328,
            "CommandName": "process list",
            "CreateTime": 1540228071.098885,
            "OperandObject": null,
            "Process": [
                {
                    "CommandLine": "",
                    "CreateTime": 1535357799,
                    "Parent": 0,
                    "ParentGuid": "00000011-0000-0000-0000-000000000000",
                    "Path": "c:\\windows\\system32\\ntoskrnl.exe",
                    "ProcessGuid": "00000011-0000-0004-01d4-3dde478174d0",
                    "ProcessID": 4,
                    "SecurityIdentifier": "s-1-5-18",
                    "Username": "NT AUTHORITY\\SYSTEM"
                }
            ],
            "Result.Code": 0,
            "Result.Desc": "",
            "Result.Type": "WinHresult",
            "Status": "complete"
        }
    }
}
Human Readable Output

CB Response - List Processes: Command Status

Cb Sensor ID Cb Session ID Cb Command ID Command Name Status Create Time Command Completion Time Operand Object Result Desc Result Type Result Code
17 348 1 process list complete 1540228071.098885 1540228071.195328     WinHresult 0

 

CB Response - Processes

Process ID Create Time Process Guid Path Command Line Security Identifier Username Parent Parent Guid
4 1535357799 00000011-0000-0004-01d4-3dde478174d0 c:\windows\system32\ntoskrnl.exe   s-1-5-18 NT AUTHORITY\SYSTEM 0 00000011-0000-0000-0000-000000000000

 

4. Delete a file


Deletes the specified file from the Carbon Black server.

Base Command

cb-file-delete

Input
Parameter Description Required
session Session ID Required
file-id File ID Required
 
Context Output
Path Description
CbLiveResponse.Files.Filename The file name.
CbLiveResponse.Files.Size The file size.
CbLiveResponse.Files.CbFileID

The ID of the file within the Cb Session Storage.

 - use with cb-file-get

CbLiveResponse.Files.Status File status (0 means there is no error).
CbLiveResponse.Files.Delete Whether the file was deleted (Boolean).
 
Command Example
Context Example
Human Readable Output 

5. Download a file


Downloads the specified file from the specified session from the Carbon Black server.

Before executing this command, push the file to the Carbon Black endpoint. use command 7-hyperlink, and the name=get-file argument to do this.

Use cb-command-create with name=get-file to push the file from a path on the endpoint to the Carbon Black server before executing cb-file-get.

Base Command

cb-file-get

Input
Parameter Description Required
session Session ID Required
file-id File ID Required
 
Context Output

There is no context output for this command.

Command Example
Context Example
Human Readable Output
 

6. Get a file's metadata


Returns information about the specified file in a specified session.

Base Command

cb-file-info

Input
Parameter Description Required
session Session ID Required
file-id File ID Optional
 
Context Output
Path Description
CbLiveResponse.Files.Filename The file name.
CbLiveResponse.Files.Size The file size.
CbLiveResponse.Files.CbFileID

The ID of the file within the Carbon Black Session Storage

use with cb-file-get.

CbLiveResponse.Files.Status File status (0 means there is no error).
CbLiveResponse.Files.Delete Whether the file was deleted (Boolean).
 
Command Example
Context Example
Human Readable Output

7. Upload a file to the Carbon Black server


Uploads the specified file to the Carbon Black server.

Use cb-command-create with name=put-file to push the file from Cb server to a path on the endpoint.

Base Command

cb-file-upload

Input
Parameter Description Required
session The ID of the session to upload the attachment file through Required
file-id The entry ID of the attachment file to upload. Required
 
Context Output
Path Description
CbLiveResponse.Files.Filename The File name
CbLiveResponse.Files.Size The file size
CbLiveResponse.Files.CbFileID

The ID of the file within the Carbon Defence Session Storage -

use with cb-file-get.

CbLiveResponse.Files.Status File status (0 means there is no error).
CbLiveResponse.Files.Delete Whether the file was deleted (Boolean).
 
Command Example
Context Example
Human Readable Output

8. Keep a session alive


Keeps the specified session alive so that it does not close due to timeout.

Base Command

cb-keepalive

Input
Parameter Description Required
session The ID of the session to keep alive Required
 
Context Output

There is no context output for this command.

Command Example
Context Example
Human Readable Output

9. List existing command instances in a specified session


Returns a list of the existing command instances and their details for the specified session.

Base Command

cb-list-commands

Input
Parameter Description Required
session The session ID Required
 
Context Output

There is no context output for this command.

Command Example
!cb-list-commands session="3951"
Context Example
{
  "Commands": [
    {
      "CbCommandID": 1,
      "CbSensorID": 13,
      "CbSessionID": 3951,
      "CommandCompletionTime": 1533449964.328933,
      "CommandName": "process list",
      "CreateTime": 1533449963.906452,
      "OperandObject": null,
      "Result": {
        "Code": 0,
        "Desc": "",
        "Type": "WinHresult"
      },
      "Status": "complete"
    },
    {
      "CbCommandID": 2,
      "CbSensorID": 13,
      "CbSessionID": 3951,
      "CommandCompletionTime": 1533450217.730081,
      "CommandName": "process list",
      "CreateTime": 1533450217.214258,
      "OperandObject": null,
      "Result": {
        "Code": 0,
        "Desc": "",
        "Type": "WinHresult"
      },
      "Status": "complete"
    },
    {
      "CbCommandID": 3,
      "CbSensorID": 13,
      "CbSessionID": 3951,
      "CommandCompletionTime": 1533450219.874692,
      "CommandName": "directory list",
      "CreateTime": 1533450219.635134,
      "OperandObject": "C:\\Windows\\CarbonBlack",
      "Result": {
        "Code": 0,
        "Desc": "",
        "Type": "WinHresult"
      },
      "Status": "complete"
    },
    {
      "CbCommandID": 4,
      "CbSensorID": 13,
      "CbSessionID": 3951,
      "CommandCompletionTime": 1533450220.312491,
      "CommandName": "directory list",
      "CreateTime": 1533450220.067548,
      "OperandObject": "C:\\Windows\\CarbonBlack\\*",
      "Result": {
        "Code": 0,
        "Desc": "",
        "Type": "WinHresult"
      },
      "Status": "complete"
    },
    {
      "CbCommandID": 5,
      "CbSensorID": 13,
      "CbSessionID": 3951,
      "CommandCompletionTime": 1533450225.146843,
      "CommandName": "directory list",
      "CreateTime": 1533450224.903408,
      "OperandObject": "C:\\Windows",
      "Result": {
        "Code": 0,
        "Desc": "",
        "Type": "WinHresult"
      },
      "Status": "complete"
    }
  ]
}
Human Readable Output

image

10. List files


Lists files in the given session

Base Command

cb-list-files

Input
Parameter Description Required
session The session ID Required
 
Context Output
Path Description
CbLiveResponse.Files.Filename The file name
CbLiveResponse.Files.Size The file size
CbLiveResponse.Files.CbFileID

The ID of the file within the Carbon Black Session Storage -

use with cb-file-get.

CbLiveResponse.Files.Status File status (0 means there is no error)
CbLiveResponse.Files.Delete Whether the file was deleted (Boolean)
 
Command Example
!cb-list-files session=3951
Context Example
Human Readable Output
 

11. List Carbon Black sessions


Returns a list of the Carbon Black sessions.

Base Command

cb-list-sessions

Input
Parameter Description Required
sensor Sensor ID to filter sessions by. Optional
status

Status to filter by. Valid values are:

  • active
  • pending
  • timeout
  • inactive
  • close
Optional
 
Context Output
Path Description
CbLiveResponse.Sessions.CbSensorID Sensor ID
CbLiveResponse.Sessions.CbSessionID Session ID
CbLiveResponse.Sessions.Hostname Hostname
CbLiveResponse.Sessions.Status Session status
CbLiveResponse.Sessions.WaitTimeout Sensor wait timeout
CbLiveResponse.Sessions.SessionTimeout Session Timeout
 
Command Example
!cb-list-sessions status=timeout
Context Example
{
  "Sessions": {
    "CbSensorID": 13,
    "CbSessionID": 3951,
    "Hostname": "WIN1",
    "SessionTimeout": 300,
    "Status": "timeout",
    "SupportedCommands": [
      "delete file",
      "put file",
      "reg delete key",
      "directory list",
      "reg create key",
      "get file",
      "reg enum key",
      "reg query value",
      "kill",
      "create process",
      "process list",
      "reg delete value",
      "reg set value",
      "create directory",
      "memdump"
    ],
    "WaitTimeout": 120
  }
}
Human Readable Output

image

12. Close a session


Closes the specified session.

Base Command

cb-session-close

Input
Parameter Description Required
session The ID of the session to close Required
 
Context Output
Path Description
CbLiveResponse.Sessions.Status Session status
CbLiveResponse.Sessions.Hostname Hostname
CbLiveResponse.Sessions.CbSensorID Sensor ID
CbLiveResponse.Sessions.CbSessionID Session ID
CbLiveResponse.Sessions.SessionTimeout Session Timeout
CbLiveResponse.Sessions.WaitTimeout Sensor wait timeout
 
Command Example
!cb-session-close session=3951
Context Example
{
  "CbSensorID": 13,
  "CbSessionID": 3951,
  "Hostname": "WIN1",
  "SessionTimeout": 300,
  "Status": "close",
  "SupportedCommands": [
    "delete file",
    "put file",
    "reg delete key",
    "directory list",
    "reg create key",
    "get file",
    "reg enum key",
    "reg query value",
    "kill",
    "create process",
    "process list",
    "reg delete value",
    "reg set value",
    "create directory",
    "memdump"
  ],
  "WaitTimeout": 120
}
Human Readable Output

image

13. Create a new session


Creates a new Carbon Black session for the specified sensor.

Base Command

cb-session-create

Input
Parameter Description Required
sensor The ID of the sensor to create a session for Required
command-timeout If a command is not be issued before this time, the session closes Optional
keepalive-timeout

If a command is not issued after this specified number of seconds, the device quits.

Optional
 
Context Output
Path Description
CbLiveResponse.Sessions.Status Session Status
CbLiveResponse.Sessions.Hostname Hostname
CbLiveResponse.Sessions.CbSensorID Sensor ID
CbLiveResponse.Sessions.CbSessionID Session ID
CbLiveResponse.Sessions.SessionTimeout Session Timeout
CbLiveResponse.Sessions.WaitTimeout Sensor wait timeout
 
Command Example
!cb-session-create sensor=13
Context Example
{
"CbSensorID": 13,
"CbSessionID": 3996,
"Hostname": "WIN1",
"SessionTimeout": 300,
"Status": "pending",
"SupportedCommands": [],
"WaitTimeout": 120
}
Human Readable Output

image

14. Create a new session and wait


Creates a new Carbon Black session for the specified sensor and waits for it to be active.

Base Command

cb-session-create-and-wait

Input
Parameter Description Required
sensor The ID of the sensor to create a session for Required
command-timeout If a command is not be issued before this time, the session closes Optional
keepalive-timeout

If the 8 command (keepalive) -hyperlink, is not issued before this time, the session closes.

Optional
wait-timeout The number of seconds to wait for session to be active Optional
 
Context Output
Path Description
CbLiveResponse.Sessions.Status Session status
CbLiveResponse.Sessions.Hostname Hostname
CbLiveResponse.Sessions.CbSensorID Sensor ID
CbLiveResponse.Sessions.CbSessionID Session ID
CbLiveResponse.Sessions.SessionTimeout Session Timeout
CbLiveResponse.Sessions.WaitTimeout Sensor wait timeout
 
Command Example
!cb-session-create-and-wait sensor=17
Context Example
{
    "CbLiveResponse": {
        "Sessions": {
            "CbSensorID": 17,
            "CbSessionID": 334,
            "Hostname": "WIN-B73RGE9AAIF",
            "SessionTimeout": 300,
            "Status": "active",
            "SupportedCommands": [
                "delete file",
                "put file",
                "reg delete key",
                "directory list",
                "reg create key",
                "get file",
                "reg enum key",
                "reg query value",
                "kill",
                "create process",
                "process list",
                "reg delete value",
                "reg set value",
                "create directory",
                "memdump"
            ],
            "WaitTimeout": 120
        }
    }
}
Human Readable Output

CB Response - Create Session And Wait

Cb Sensor ID Cb Session ID Hostname Status Wait Timeout Session Timeout Supported Commands
17 334 WIN-B73RGE9AAIF active 120 300 delete file,put file,reg delete key,directory list,reg create key,get file,reg enum key,reg query value,kill,create process,process list,reg delete value,reg set value,create directory,memdump

 

15. Get information about a session


Displays information about the specified session.

Base Command

cb-session-info

Input
Parameter Description Required
session The ID of the session ID to get information about Required
 
Context Output
Path Description
CbLiveResponse.Sessions.Status Session status
CbLiveResponse.Sessions.Hostname Hostname
CbLiveResponse.Sessions.CbSensorID Sensor ID
CbLiveResponse.Sessions.CbSessionID Session ID
CbLiveResponse.Sessions.SessionTimeout Session Timeout
CbLiveResponse.Sessions.WaitTimeout Sensor wait timeout
 
Command Example
!cb-session-info session=3997
Context Example
{
"CbSensorID": 13,
"CbSessionID": 3997,
"Hostname": "WIN1",
"SessionTimeout": 300,
"Status": "active",
"SupportedCommands": [
"delete file",
"put file",
"reg delete key",
"directory list",
"reg create key",
"get file",
"reg enum key",
"reg query value",
"kill",
"create process",
"process list",
"reg delete value",
"reg set value",
"create directory",
"memdump"
],
"WaitTimeout": 120
}
Human Readable Output

image

16. Terminate a process


Terminates the specified process on the sensor or endpoint.

Base Command

cb-process-kill

Input
Parameter Description Required
session The session ID Optional
pid The PID of the process to terminate Required
wait-timeout Time to wait (in seconds) for Cb command to be executed (change status from pending to in progress</em/complete) Optional
cancel-on-timeout If the command is still pending after this time, the command is cancelled Optional
sensor The sensor ID. Provided the sensor ID to run the command with a new session. The session will be created and closed automatically Optional
 
Context Output
Path Description
CbLiveResponse.Commands.CbCommandID Unique command ID
CbLiveResponse.Commands.CommandName The command name
CbLiveResponse.Commands.Status

The command status

  • pending
  • in progress
  • complete
  • error
  • canceled
CbLiveResponse.Commands.CommandCompletionTime The time the command was completed (0 if not completed)
CbLiveResponse.Commands.OperandObject The process ID
 
Command Example
!cb-process-kill pid=972 sensor=17
Context Example
{
    "CbLiveResponse": {
        "Commands": {
            "CbCommandID": 1,
            "CbSensorID": 17,
            "CbSessionID": 328,
            "CommandCompletionTime": 1540219865.188614,
            "CommandName": "kill",
            "CreateTime": 1540219865.160948,
            "OperandObject": "972",
            "Result": {
                "Code": 0,
                "Desc": "",
                "Type": "WinHresult"
            },
            "Status": "complete"
        }
    }
}
Human Readable Output

CB Response - Kill Process 972: Command Status

Cb Sensor ID Cb Session ID Cb Command ID Command Name Status Create Time Command Completion Time Operand Object Result Desc Result Type Result Code
17 328 1 kill complete 1540219865.160948 1540219865.188614 972   WinHresult 0

 

17. List directories


Returns a list of directories on the endpoint.

Base Command

cb-directory-listing

Input
Parameter Description Required
session The session ID. Optional
path Path for the directory (e.g. "c:\Users\"). Note to end with double backslash. Required
wait-timeout Time to wait (in seconds) for Cb command to be executed (change status from 'pending' to 'in-progress'/'complete'). Optional
cancel-on-timeout Cancel the command if still 'pending' after timeout. Optional
sensor The sensor ID. Provided the sensor ID to run the command with a new session. The session will be created and closed automatically. Optional
 
Context Output
Path Description
CbLiveResponse.Commands.CbCommandID Unique command ID
CbLiveResponse.Commands.CommandName The command name
CbLiveResponse.Commands.DirectoryList.Status

The command status

  • pending
  • in progress
  • complete
  • error
  • canceled
CbLiveResponse.Commands.CommandCompletionTime The time the command was completed (0 if not complete)
CbLiveResponse.Commands.OperandObject the directory listing filter (or path)
CbLiveResponse.Commands.Files.FileAttributes A list of file attributes
CbLiveResponse.Commands.Files.CreateTime Create time in Unix time format
CbLiveResponse.Commands.Files.LastAccessTime Last access time in Unix time format.
CbLiveResponse.Commands.Files.LastWriteTime Last write time in Unix time format.
CbLiveResponse.Commands.Files.FileSize The file size.
CbLiveResponse.Commands.Files.FileName The file name.
 
Command Example
!cb-directory-listing path="c:\Users\All Users\Desktop\" sensor=17
Context Example
{
    "CbLiveResponse": {
        "Commands": {
            "CbCommandID": 1,
            "CbSensorID": 17,
            "CbSessionID": 332,
            "CommandCompletionTime": 1540220585.720132,
            "CommandName": "directory list",
            "CreateTime": 1540220585.692945,
            "Files": [
                {
                    "AlternativeName": null,
                    "CreateTime": 1377185970,
                    "FileAttributes": [
                        "READONLY",
                        "HIDDEN",
                        "DIRECTORY"
                    ],
                    "FileName": ".",
                    "FileSize": 0,
                    "LastAccessTime": 1534297982,
                    "LastWriteTime": 1534297982
                },
                {
                    "AlternativeName": null,
                    "CreateTime": 1377185970,
                    "FileAttributes": [
                        "READONLY",
                        "HIDDEN",
                        "DIRECTORY"
                    ],
                    "FileName": "..",
                    "FileSize": 0,
                    "LastAccessTime": 1534297982,
                    "LastWriteTime": 1534297982
                },
                {
                    "AlternativeName": null,
                    "CreateTime": 1377185972,
                    "FileAttributes": [
                        "HIDDEN",
                        "SYSTEM",
                        "ARCHIVE"
                    ],
                    "FileName": "desktop.ini",
                    "FileSize": 174,
                    "LastAccessTime": 1377185877,
                    "LastWriteTime": 1377185877
                },
                {
                    "AlternativeName": "GOOGLE~1.LNK",
                    "CreateTime": 1509481395,
                    "FileAttributes": [
                        "ARCHIVE"
                    ],
                    "FileName": "Google Chrome.lnk",
                    "FileSize": 2163,
                    "LastAccessTime": 1509481395,
                    "LastWriteTime": 1533760799
                }
            ],
            "OperandObject": "c:\\Users\\All Users\\Desktop\\",
            "Result": {
                "Code": 0,
                "Desc": "",
                "Type": "WinHresult"
            },
            "Status": "complete"
        }
    }
}
Human Readable Output

CB Response - Directory Listing: Command Status

Cb Sensor ID Cb Session ID Cb Command ID Command Name Status Create Time Command Completion Time Operand Object Result Desc Result Type Result Code
17 332 1 directory list complete 1540220585.692945 1540220585.720132 c:\Users\All Users\Desktop| WinHresult 0  

 

CB Response - Directory Listing

File Attributes Create Time Last Access Time Last Write Time File Size File Name Alternative Name
READONLY,HIDDEN,DIRECTORY 1377185970 1534297982 1534297982 0 .  
READONLY,HIDDEN,DIRECTORY 1377185970 1534297982 1534297982 0 ..  
HIDDEN,SYSTEM,ARCHIVE 1377185972 1377185877 1377185877 174 desktop.ini  
ARCHIVE 1509481395 1509481395 1533760799 2163 Google Chrome.lnk GOOGLE~1.LNK

 

18. Run an executable on an endpoint


Runs the executable on an endpoint.

Base Command

cb-process-execute

Input
Parameter Description Required
session The session ID. Optional
sensor The sensor ID. Provided the sensor ID to run the command with a new session. The session will be created and closed automatically. Optional
path the path and command line of the executable Required
wait An optional parameter to specify whether to wait for the process to complete execution before reporting the result. Optional
working-directory An optional parameter to specify the working directory of the executable. Optional
output-file An option file that STDERR and STDOUT will be redirected to. Optional
wait-timeout Time to wait (in seconds) for Cb command to be executed (change status from 'pending' to 'in-progress'/'complete'). Optional
cancel-on-timeout Cancel the command if still 'pending' after timeout. Optional
 
Context Output
Path Description
CbLiveResponse.Commands.CbCommandID Unique command ID
CbLiveResponse.Commands.CommandName The command name
CbLiveResponse.Commands.Status

The command Status

  • pending
  • in progress
  • complete
  • error
  • canceled
CbLiveResponse.Commands.CommandCompletionTime The command completion time (0 if not complete).
CbLiveResponse.Commands.OperandObject The path and command line of the executable
CbLiveResponse.Commands.ReturnCode The return code of the process (if wait was set to true)
CbLiveResponse.Commands.ProcessID The PID of the executed process
 
Command Example
Context Example
Human Readable Output

19. Endpoint memory dump


Endpoint memory dump.

Base Command

cb-memdump

Input
Parameter Description Required
session The session ID. Optional
sensor The sensor ID. Provided the sensor ID to run the command with a new session. The session will be created and closed automatically. Optional
path the path to save the resulting memory dump (on the endpoint). Required
compress An optional parameter to specify whether to compress resulting memory dump. Optional
wait-timeout Time to wait (in seconds) for Cb command to be executed (change status from 'pending' to 'in-progress'/'complete'). Optional
cancel-on-timeout Cancel the command if still 'pending' after timeout. Optional
 
Context Output
Path Description
CbLiveResponse.Commands.CbCommandID Unique command ID
CbLiveResponse.Commands.CommandName The command name
CbLiveResponse.Commands.Status

The command Status

  • pending
  • in progress
  • complete
  • error
  • canceled
CbLiveResponse.Commands.CommandCompletionTime The command completion time (0 if not complete)
CbLiveResponse.Commands.OperandObject The path to save the resulting memory dump (on the endpoint)
CbLiveResponse.Commands.ReturnCode Return code of the memory dump process
CbLiveResponse.Commands.CompressingEnabled Boolean flag indicating if compression is enabled.
CbLiveResponse.Commands.Complete Boolean flag indicating if memory dump is completed.
CbLiveResponse.Commands.PercentDone Percent of the process completed
CbLiveResponse.Commands.DumpingInProgress Boolean flag indicating if memory dump is in progress.
 
Command Example
!cb-memdump path="c:\Users\All Users\Desktop" sensor=17
Context Example
Human Readable Output

20. Create a live response command


Creates a Carbon Black Live Response command.

Base Command

cb-command-create

Input
Parameter Description Required
name Command name Required
timeout Command timeout Optional
object the object the command operates on. This is specific to the command but has meaning in a generic way for logging, and display purposes Optional
compress "true" or "false" - an optional parameter to specify whether to compress resulting memory dump Optional
working-dir An optional parameter to specify the working directory of the executable Optional
output-file An option file that STDERR and STDOUT will be redirected to. Optional
value-data the data associated with the registry value Optional
value-type the string representation of the registry value type (ie REG_DWORD, REG_QWORD, ….) Optional
overwrite “true” or “false”. An optional parameter to specify whether to overwrite the value if it already exists (default value is “false”) Optional
offset a byte offset to start getting the file. Supports a partial get. Optional
get-count the number of bytes to grab Optional
session Session ID to create command for Required
 
Context Output
Path Description
CbLiveResponse.Commands.Status The Command Status
CbLiveResponse.Commands.Hostname The hostname running the command
CbLiveResponse.Commands.CbLiveResponse.Commands.CbSensorID The Sensor ID
CbLiveResponse.Commands.CommandName The Command name
CbLiveResponse.Commands.CbSessionID The Session ID
CbLiveResponse.Commands.CbCommandID The Command ID
CbLiveResponse.Commands.OperandObject Object argument for the CbLive command - e.g. for 'directory list' this is the path of the dir to list. For more information, see the Carbon Black documentation.
CbLiveResponse.Commands.CreateTime Command create time
CbLiveResponse.Commands.CommandCompletionTime The time the command completed or 0 if still in progres.
CbLiveResponse.Commands.Result.Desc Result description
CbLiveResponse.Commands.Result.Type Result type
CbLiveResponse.Commands.Result.Code Result code
 
Command Example
!cb-command-create session=337 name="process-list"
!cb-command-create session=337 name="directory-list" object="c:\Users\" (path)
!cb-command-create session=337 name=kill object=1 (pid)
Context Example
Human Readable Output

21. Create a Live Response command and wait


Creates a Live Response command and waits for it to finish executing.

Base Command

cb-command-create-and-wait

Input
Parameter Description Required
name Command name Required
timeout Command timeout Optional
object the object the command operates on. This is specific to the command but has meaning in a generic way for logging, and display purposes Optional
compress "true" or "false" - an optional parameter to specify whether to compress resulting memory dump Optional
working-dir An optional parameter to specify the working directory of the executable Optional
output-file An option file that STDERR and STDOUT will be redirected to. Optional
value-data the data associated with the registry value Optional
value-type the string representation of the registry value type (ie REG_DWORD, REG_QWORD, ….) Optional
overwrite “true” or “false”. An optional parameter to specify whether to overwrite the value if it already exists (default value is “false”) Optional
offset a byte offset to start getting the file. Supports a partial get. Optional
get-count the number of bytes to grab Optional
session Session ID to create command for Required
wait-timeout Time to wait in seconds to wait for command to finish executing Optional
 
Context Output

There is no context output for this command.

Command Example
!cb-command-create-and-wait session=337 name="process-list"
!cb-command-create-and-wait session=337 name="directory-list" object="c:\Users\" (path)
!cb-command-create-and-wait session=337 name=kill object=1 (pid)
Context Example
Human Readable Output

22. Terminate a process


Terminates the specified process at the sensor endpoint.

Base Command

cb-terminate-process

Input
Parameter Description Required
session Session ID Required
pid The PID of the process to terminate Required
wait-timeout Time to wait in seconds for process to complete termination Optional
 
Context Output

There is no context output for this command.

Command Example
Context Example
Human Readable Output

23. Delete a file from an endpoint


Deletes the specified file from an endpoint.

Base Command

cb-file-delete-from-endpoint

Input
Parameter Description Required
session The session ID. Optional
sensor The sensor ID. Provided the sensor ID to run the command with a new session. The session will be created and closed automatically. Optional
path The source path of the object to delete. Required
wait-timeout Time to wait (in seconds) for Cb command to be executed (change status from 'pending' to 'in-progress'/'complete'). Optional
cancel-on-timeout Cancel the command if still 'pending' after timeout. Optional
 
Context Output
Path Description
CbLiveResponse.Commands.CbCommandID Unique command ID
CbLiveResponse.Commands.CommandName The command name
CbLiveResponse.Commands.Status

The command status

  • pending
  • in progress
  • complete
  • error
  • canceled
CbLiveResponse.Commands.CommandCompletionTime The command completion time (0 if not complete).
CbLiveResponse.Commands.OperandObject The source path of the object to delete
 
Command Example
!cb-file-delete-from-endpoint sensor="17" path="c:\Users\All Users\Desktop\mooncake.jpg" wait-timeout="20"
Context Example
{
    "CbLiveResponse": {
        "Commands": {
            "CbCommandID": 1,
            "CbSensorID": 17,
            "CbSessionID": 339,
            "CommandCompletionTime": 1540224791.225669,
            "CommandName": "delete file",
            "CreateTime": 1540224791.197925,
            "OperandObject": "c:\\Users\\All Users\\Desktop\\mooncake.jpg",
            "Result": {
                "Code": 2147942402,
                "Desc": "",
                "Type": "WinHresult"
            },
            "Status": "error"
        }
    }
}
Human Readable Output

CB Response - Delete File From Endpoint: Command Status

Cb Sensor ID Cb Session ID Cb Command ID Command Name Status Create Time Command Completion Time Operand Object Result Desc Result Type Result Code
17 339 1 delete file error 1540224791.197925 1540224791.225669 c:\Users\All Users\Desktop\mooncake.jpg   WinHresult 2147942402

 

24. Enumerate registry values


Enumerates the registry values.

Base Command

cb-registry-get-values

Input
Parameter Description Required
session The session ID. Optional
sensor The sensor ID. Provided the sensor ID to run the command with a new session. The session will be created and closed automatically. Optional
path The path of the key to query Required
wait-timeout Time to wait (in seconds) for Cb command to be executed (change status from 'pending' to 'in-progress'/'complete'). Optional
cancel-on-timeout Cancel the command if still 'pending' after timeout. Optional
 
Context Output
Path Description
CbLiveResponse.Commands.CbCommandID Unique command ID
CbLiveResponse.Commands.CommandName The command name
CbLiveResponse.Commands.Status

The command status

  • pending
  • in progress
  • complete
  • error
  • canceled
CbLiveResponse.Commands.CommandCompletionTime The command completion time (0 if not complete).
CbLiveResponse.Commands.OperandObject The path of the key to queried
CbLiveResponse.Commands.Values.RegKeyType Registry value type
CbLiveResponse.Commands.Values.RegKeyName The name of the registry value
CbLiveResponse.Commands.Values.RegKeyData The data associated with the registry value
CbLiveResponse.Commands.SubKeys List of subkey names
 
Command Example
Context Example
Human Readable Output

25. Query for a registry value


Query for registry value.

Base Command

cb-registry-query-value

Input
Parameter Description Required
session The session ID. Optional
sensor The sensor ID. Provided the sensor ID to run the command with a new session. The session will be created and closed automatically. Optional
path The path of the key + the path of the value (e.g. HKEY_LOCAL_MACHINE\blah\key\value). Required
wait-timeout Time to wait (in seconds) for Cb command to be executed (change status from 'pending' to 'in-progress'/'complete'). Optional
cancel-on-timeout Cancel the command if still 'pending' after timeout. Optional
 
Context Output
Path Description
CbLiveResponse.Commands.CbCommandID Unique command identifier.
CbLiveResponse.Commands.CommandName The command name.
CbLiveResponse.Commands.Status The command Status ('pending', 'in progress', 'complete', 'error', 'canceled').
CbLiveResponse.Commands.CommandCompletionTime The command completion time (0 if not complete).
CbLiveResponse.Commands.OperandObject the path of the key + the path of the value (ie HKEY_LOCAL_MACHINE\blah\key\value).
CbLiveResponse.Commands.Registry.QueryValue.Values.RegKeyType Registry value type.
CbLiveResponse.Commands.RegKeyName the name of the registry value.
CbLiveResponse.Commands.RegKeyData The data associated with the registry value.
CbLiveResponse.Commands.SubKeys List of subkey names.
 
Command Example
Context Example
Human Readable Output

26. Create a new registry key


Creates a new registry key.

Base Command

cb-registry-create-key

Input
Parameter Description Required
session The session ID. Optional
sensor The sensor ID. Provided the sensor ID to run the command with a new session. The session will be created and closed automatically. Optional
path The key path to create. Required
wait-timeout Time to wait (in seconds) for Cb command to be executed (change status from 'pending' to 'in-progress'/'complete'). Optional
cancel-on-timeout Cancel the command if still 'pending' after timeout. Optional
 
Context Output
Path Description
CbLiveResponse.Commands.CbCommandID Unique command ID
CbLiveResponse.Commands.CommandName The command name
CbLiveResponse.Commands.Status

The command status

  • pending
  • in progress
  • complete
  • error
  • canceled
CbLiveResponse.Commands.CommandCompletionTime The command completion time (0 if not complete)
CbLiveResponse.Commands.OperandObject The key path
 
Command Example
Context Example
Human Readable Output

27. Delete a registry key


Deletes the specified registry key.

Base Command

cb-registry-delete-key

Input
Parameter Description Required
session The session ID. Optional
sensor The sensor ID. Provided the sensor ID to run the command with a new session. The session will be created and closed automatically. Optional
path The key path to delete. Required
wait-timeout Time to wait (in seconds) for Cb command to be executed (change status from 'pending' to 'in-progress'/'complete'). Optional
cancel-on-timeout Cancel the command if still 'pending' after timeout. Optional
 
Context Output
Path Description
CbLiveResponse.Commands.CbCommandID Unique command ID
CbLiveResponse.Commands.CommandName The command name
CbLiveResponse.Commands.Status

The command status

  • pending
  • in progress
  • complete
  • error
  • canceled
CbLiveResponse.Commands.CommandCompletionTime The command completion time (0 if not complete)
CbLiveResponse.Commands.OperandObject the key path
 
Command Example
Context Example
Human Readable Output

28. Delete a registry value


Delete registry value.

Base Command

cb-registry-delete-value

Input
Parameter Description Required
session The session ID. Optional
sensor The sensor ID. Provided the sensor ID to run the command with a new session. The session will be created and closed automatically. Optional
path The path of the key + the path of the value. Required
wait-timeout Time to wait (in seconds) for Cb command to be executed (change status from 'pending' to 'in-progress'/'complete'). Optional
cancel-on-timeout Cancel the command if still 'pending' after timeout. Optional
 
Context Output
Path Description
CbLiveResponse.Commands.CbCommandID Unique command ID
CbLiveResponse.Commands.CommandName The command name
CbLiveResponse.Commands.Status

The command status

  • pending
  • in progress
  • complete
  • error
  • canceled
CbLiveResponse.Commands.CommandCompletionTime The command completion time (0 if not complete).
CbLiveResponse.Commands.OperandObject The key path
 
Command Example
Context Example
Human Readable Output

29. Set a registry value


Sets a registry value.

Base Command

cb-registry-set-value

Input
Parameter Description Required
session The session ID. Optional
sensor The sensor ID. Provided the sensor ID to run the command with a new session. The session will be created and closed automatically. Optional
path The path of the key + the path of the value. Required
data The data to set for the value. Note if the value type ‘REG_MULTI_SZ’ then multiple values should be separated by a comma (e.g. value1, value2, value3). Required
type One of common registry value types (REG_DWORD, REG_QWORD, REG_SZ etc). Required
overwrite An optional parameter to specify whether to overwrite the value if it already exists (default value is ’no’). Optional
wait-timeout Time to wait (in seconds) for Cb command to be executed (change status from 'pending' to 'in-progress'/'complete'). Optional
cancel-on-timeout Cancel the command if still 'pending' after timeout. Optional
 
Context Output
Path Description
CbLiveResponse.Commands.CbCommandID Unique command ID
CbLiveResponse.Commands.CommandName The command name
CbLiveResponse.Commands.Status

The command status

  • pending
  • in progress
  • complete
  • error
  • canceled
CbLiveResponse.Commands.CommandCompletionTime The command completion time (0 if not complete)
CbLiveResponse.Commands.OperandObject The key path
 
Command Example
Context Example
Human Readable Output

30. Get a list processes running on an endpoint


Returns a list of processes running on the endpoint.

Base Command

cb-process-list

Input
Parameter Description Required
session The session ID. Optional
sensor The sensor ID. Provided the sensor ID to run the command with a new session. The session will be created and closed automatically. Optional
wait-timeout Time to wait (in seconds) for Cb command to be executed (change status from 'pending' to 'in-progress'/'complete'). Optional
cancel-on-timeout Cancel the command if still 'pending' after timeout. Optional
 
Context Output
Path Description
CbLiveResponse.Commands.CbCommandID Unique command identifier.
CbLiveResponse.Commands.CommandName The command name.
CbLiveResponse.Commands.Status The command Status ('pending', 'in progress', 'complete', 'error', 'canceled').
CbLiveResponse.Commands.CommandCompletionTime The command completion time (0 if not complete).
CbLiveResponse.Commands.Processes.ProcessID Process ID.
CbLiveResponse.Commands.Processes.CreateTime The creation time of the process in Unix time.
CbLiveResponse.Commands.Processes.ProcessGuid The process guid of the process.
CbLiveResponse.Commands.Processes.Path The execution path of the process.
CbLiveResponse.Commands.Processes.SecurityIdentifier The Security Identifier (SID) of the default process token.
CbLiveResponse.Commands.Processes.Username The username of the default process token.
CbLiveResponse.Commands.Processes.Parent The pid (process id ) of the parent.
CbLiveResponse.Commands.Processes.ParentGuid The process guid of the parent process.
 
Command Example
!cb-process-list sensor=1
Context Example
{
    "CbLiveResponse": {
        "Commands": {
            "CbCommandID": 1,
            "CbSensorID": 17,
            "CbSessionID": 327,
            "CommandCompletionTime": 1540219086.030599,
            "CommandName": "process list",
            "CreateTime": 1540219085.939409,
            "OperandObject": null,
            "Process": [
                {
                    "CommandLine": "",
                    "CreateTime": 1535357799,
                    "Parent": 0,
                    "ParentGuid": "00000011-0000-0000-0000-000000000000",
                    "Path": "c:\\windows\\system32\\ntoskrnl.exe",
                    "ProcessGuid": "00000011-0000-0004-01d4-3dde478174d0",
                    "ProcessID": 4,
                    "SecurityIdentifier": "s-1-5-18",
                    "Username": "NT AUTHORITY\\SYSTEM"
                },
                {
                    "CommandLine": "\\SystemRoot\\System32\\smss.exe",
                    "CreateTime": 1535357799,
                    "Parent": 4,
                    "ParentGuid": "00000011-0000-0004-01d4-3dde478174d0",
                    "Path": "c:\\windows\\system32\\smss.exe",
                    "ProcessGuid": "00000011-0000-0188-01d4-3dde4783d56b",
                    "ProcessID": 392,
                    "SecurityIdentifier": "s-1-5-18",
                    "Username": "NT AUTHORITY\\SYSTEM"
                }
    ]
}
Human Readable Output

CB Response - List Processes: Command Status

Cb Sensor ID Cb Session ID Cb Command ID Command Name Status Create Time Command Completion Time Operand Object Result Desc Result Type Result Code
17 327 1 process list complete 1540219085.939409 1540219086.030599     WinHresult 0

 

CB Response - Processes

Process ID Create Time Process Guid Path Command Line Security Identifier Username Parent Parent Guid
4 1535357799 00000011-0000-0004-01d4-3dde478174d0 c:\windows\system32\ntoskrnl.exe   s-1-5-18 NT AUTHORITY\SYSTEM 0 00000011-0000-0000-0000-000000000000

 

31. Get a file from an endpoint


Retrieves a file from a path on the endpoint.

Base Command

cb-get-file-from-endpoint

Input
Parameter Description Required
session The session ID. Optional
sensor The sensor ID. Provided the sensor ID to run the command with a new session. The session will be created and closed automatically. Optional
path The source path of the file. Required
wait-timeout Time to wait (in seconds) for Cb command to be executed (change status from 'pending' to 'in-progress'/'complete'). Optional
 
Context Output
Path Description
CbLiveResponse.Commands.CbCommandID Unique command identifier.
CbLiveResponse.Commands.CommandName The command name.
CbLiveResponse.Commands.Status The command Status ('pending', 'in progress', 'complete', 'error', 'canceled').
CbLiveResponse.Commands.CommandCompletionTime The command completion time (0 if not complete).
CbLiveResponse.Commands.OperandObject The source path of the file.
CbLiveResponse.Commands.FileID Unique file ID.
CbLiveResponse.File.Size File size.
CbLiveResponse.File.SHA1 File SHA1.
CbLiveResponse.File.SHA256 File SHA256.
CbLiveResponse.File.Name File name.
CbLiveResponse.File.SSDeep File SSDeep.
CbLiveResponse.File.EntryID File EntryID.
CbLiveResponse.File.Info File info.
CbLiveResponse.File.Type File type.
CbLiveResponse.File.MD5 File MD5 hash
CbLiveResponse.File.Extension File extension.
 
Command Example
!cb-get-file-from-endpoint path="c:\Users\All Users\Desktop\mooncake.jpg" sensor=17
Context Example
{
    "CbLiveResponse": {
        "Commands": {
            "CbCommandID": 2,
            "CbSensorID": 17,
            "CbSessionID": 356,
            "CommandCompletionTime": 1540229207.655335,
            "CommandName": "get file",
            "CreateTime": 1540229207.608662,
            "FileID": 1,
            "OperandObject": "c:\\Users\\All Users\\Desktop\\mooncake.jpg",
            "Result": {
                "Code": 0,
                "Desc": "",
                "Type": "WinHresult"
            },
            "Status": "complete"
        }
    },
    "File": {
        "EntryID": "168@583490",
        "Extension": "jpg",
        "Info": "image/jpeg",
        "MD5": "1fe52b291d16c7f9a6eaf43074024011",
        "Name": "mooncake.jpg",
        "SHA1": "30bd2461d6cee80227bcf557a6fd47922b96263c",
        "SHA256": "a87b0fa1006b301b7ef2259cfa9aed2ff12c15217796b5dd08b36e006a137cd2",
        "SSDeep": "192:pAzQbZ/ujghzcZHcsWw6o6E7ODeADcBwjZ4P:pAzG/ujgh6xCo60ODe3wj8",
        "Size": 11293,
        "Type": "data\n"
    }
}
Human Readable Output

screen shot 2018-10-22 at 20 27 52

32. Save a file to an endpoint


Saves a file to a specific path on an endpoint.

Base Command

cb-push-file-to-endpoint

Input
Parameter Description Required
session The session ID. Optional
sensor The sensor ID. Provided the sensor ID to run the command with a new session. The session will be created and closed automatically. Optional
entry-id The file entry ID. Required
wait-timeout Time to wait (in seconds) for Cb command to be executed (change status from 'pending' to 'in-progress'/'complete'). Optional
path The destination path of the file. Include file name and type (e.g. "c:\Users\USER\Desktop\log.txt"). Required
 
Context Output
Path Description
CbLiveResponse.Commands.CbCommandID Unique command identifier.
CbLiveResponse.Commands.CommandName The command name.
CbLiveResponse.Commands.Status The command Status ('pending', 'in progress', 'complete', 'error', 'canceled').
CbLiveResponse.Commands.CommandCompletionTime The command completion time (0 if not complete).
CbLiveResponse.Commands.OperandObject The destination path of the file.
 
Command Example

!cb-push-file-to-endpoint entry-id=84@583490 path="c:\Users\All Users\Desktop" sensor=17

Context Example
{
    "CbLiveResponse": {
        "Commands": {
            "CbCommandID": 1,
            "CbSensorID": 17,
            "CbSessionID": 338,
            "CommandCompletionTime": 1540224253.942851,
            "CommandName": "put file",
            "CreateTime": 1540224253.915233,
            "OperandObject": "c:\\Users\\All Users\\Desktop",
            "Result": {
                "Code": 2147942405,
                "Desc": "",
                "Type": "WinHresult"
            },
            "Status": "error"
        },
        "Files": {
            "CbFileID": 1,
            "Delete": false,
            "Filename": "mooncake.jpg",
            "Size": 6167,
            "SizeUploaded": 6167,
            "Status": 0
        }
    },
    "File": {
        "EntryID": "84@583490",
        "Extension": "jpg",
        "Info": "image/jpeg",
        "MD5": "e42a08714529d9c78cce07a04d2e5e7c",
        "Name": "mooncake.jpg",
        "SHA1": "d5b5f31018a1d6d51ff1857d3d79cda60ae525ac",
        "SHA256": "769509b39aad9992435bf900dd9c96ac409be154eaae5c52f40393e9a9c2ffb4",
        "SSDeep": "96:dkwEkdwRnxWUfLO//UTDEuDQ/qBIG9ywAPIloeAIVvx7TM01LT9C:9z2JQLGDQkRzoeAIvlRT9C",
        "Size": 6167,
        "Type": "JPEG image data, JFIF standard 1.01\n"
    }
}
Human Readable Output

CB Response - Push File: Command Status

Cb Sensor ID Cb Session ID Cb Command ID Command Name Status Create Time Command Completion Time Operand Object Result Desc Result Type Result Code
17 338 1 put file error 1540224253.915233 1540224253.942851 c:\Users\All Users\Desktop   WinHresult 2147942405

 

CB Response - File Info

Cb File ID Filename Size Size Uploaded Status Delete
1 mooncake.jpg 6167 6167 0 false

Configuration parameters

  • serverurl — Server URL (required)
  • apitoken — API Token (CB Response)
  • credentials_api_token
  • apikey — API Key (CB Defense)
  • credentials_api_key
  • connector — Connector ID (CB Defense)
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (33)

  • cb-archive

    Archive the given session (If the session has no content it will fail)

  • cb-command-cancel Deprecated

    Cancel the given command. Only pending commands can be canceled.

  • cb-command-create Deprecated

    Create a live response command. Use cb-session-create instead.

  • cb-command-create-and-wait Deprecated

    Create a live response command and wait for it to finish executing

  • cb-command-info

    Display information on command

  • cb-directory-listing

    List directories on the endpoint.

  • cb-file-delete

    Delete a given file in the session from Cb server.

  • cb-file-delete-from-endpoint

    Delete a file from the endpoint.

  • cb-file-get

    Download a file from Cb server in a given session.

  • cb-file-info

    Get file info for a given file in a session

  • cb-file-upload Deprecated

    Uploads the file to the Cb server. Use cb-push-file-to-endpoint instead.

  • cb-get-file-from-endpoint

    Retrieves a file from a path on the endpoint. For large files, set the "download" argument to "false". Verify that the command completed by using the !cb-command-info command. After the command completes, download the file using the !cb-file-get command.

  • cb-keepalive

    Keep the session alive to avoid closing due to timeout

  • cb-list-commands

    List the CarbonBlack existing commands for a given session

  • cb-list-files

    List files in a given session

  • cb-list-sessions

    List the CarbonBlack sessions

  • cb-memdeump Deprecated

    Deprecated - use cb-memdump instead.

  • cb-memdump

    Executes an endpoint memory dump.

  • cb-process-execute

    Run executable on the endpoint.

  • cb-process-kill

    Terminates a process at the sensor/endpoint

  • cb-process-list

    List processes running on the endpoint.

  • cb-push-file-to-endpoint

    Save a file to a specific path on the endpoint.

  • cb-registry-create-key

    Create a new registry key.

  • cb-registry-delete-key

    Delete registry key.

  • cb-registry-delete-value

    Delete registry value.

  • cb-registry-get-values

    Enumerate registry values

  • cb-registry-query-value

    Query for registry value.

  • cb-registry-set-value

    Set registry value.

  • cb-session-close

    Close the given session

  • cb-session-create

    Create a new CarbonBlack session for a given sensor

  • cb-session-create-and-wait

    Create a new CarbonBlack session for a given sensor and wait for it to be active

  • cb-session-info

    Display session info

  • cb-terminate-process Deprecated

    Terminates a process at the sensor/endpoint

"use strict";

/// Global Vars
let CB_PRODUCT;
let BASE_URL;
let AUTH;
let COMMAND_DATA;
let SLEEP_BETWEEN_RETRIES = 1000 * 5;
let DEFAULT_WAIT_TIMEOUT = 1000 * 60 * 2;
let ERROR_MESSAGE = 'Use Live Response for Cb Defense or Cb Response.\nFor Cb Defense: Provide \'Live Response\' API key and connector.\nFor Cb Response: Provide API Token.';
//validate the credentials are provided to match only one of the products
let API_TOKEN = (params.credentials_api_token)? params.credentials_api_token.password : params.apitoken;
let API_KEY = (params.credentials_api_key)? params.credentials_api_key.password : params.apikey;
if (API_TOKEN && (API_KEY || params.connector) ) {
    throw ERROR_MESSAGE;
}
//determain Cb product
if (API_TOKEN) {
    CB_PRODUCT = 'Response';
    BASE_URL = `${params.serverurl}/api/v1/cblr`;
    AUTH = API_TOKEN;
    COMMAND_DATA = [
        {to: 'CbSensorID', from: 'sensor_id'},
        {to: 'CbSessionID', from: 'session_id'},
        {to: 'CbCommandID', from: 'id'},
        {to: 'CommandName', from: 'name'},
        {to: 'Status', from: 'status'},
        {to: 'CreateTime', from: 'create_time'},
        {to: 'CommandCompletionTime', from: 'completion'},
        {to: 'OperandObject', from: 'object'},
        {to: 'Result.Desc', from: 'result_desc'},
        {to: 'Result.Type', from: 'result_type'},
        {to: 'Result.Code', from: 'result_code'}
    ];
} else if (API_KEY && params.connector){
    CB_PRODUCT = 'Defense';
    BASE_URL = `${params.serverurl}/integrationServices/v3/cblr`
    AUTH = API_KEY + '/' + params.connector;
    COMMAND_DATA = [
        {to: 'CbSensorID', from: 'sensor_id'},
        {to: 'CbSessionID', from: 'session_id'},
        {to: 'CbCommandID', from: 'id'},
        {to: 'CommandName', from: 'name'},
        {to: 'Status', from: 'status'},
        {to: 'CreateTime', from: 'create_time'},
        {to: 'CommandCompletionTime', from: 'completion_time'},
        {to: 'OperandObject', from: 'obj.object'},
        {to: 'Result.Desc', from: 'result_desc'},
        {to: 'Result.Type', from: 'result_type'},
        {to: 'Result.Code', from: 'result_code'}
    ];
} else {
    throw ERROR_MESSAGE;
}

/// Base Functions

function splitCamelCase(str) {
    return str
    .replace(/([a-z])([A-Z])/g, '$1 $2')
    .replace('.', ' ');
}

function sendRequest(path, method, requestParams, headers, ignoredStatusCodes) {

    if (!headers) {
        headers = {};
    }
    if (!headers['X-Auth-Token']) {
        headers['X-Auth-Token'] = [AUTH];
    }
    if (!headers['Accept']) {
        headers['Accept'] = ['application/json'];
    }
    if (!headers['Content-Type']) {
        headers['Content-Type'] = ['application/json'];
    }

    let request = {
        Method: method,
        Headers: headers
    };
    let querystring = '';
    if (requestParams) {
        if (typeof requestParams === 'string') {
            querystring = requestParams;
        } else {
            request.Body = JSON.stringify(requestParams);
        }
    }
    let result = http(BASE_URL + path + querystring, request, params.insecure, params.proxy);
    if (!ignoredStatusCodes || ignoredStatusCodes.indexOf(result.StatusCode) === -1) {
        if (result.StatusCode < 200 || result.StatusCode >= 300) {
            if (result.StatusCode === 404) {
                throw `Cannot find the requested resource\nError message: ${result.Body}\nStatus Code: 404`;
            }
            throw `Request Failed.\nStatus code: ${result.StatusCode}.\nMessage: ${result.Body}.`;
        }
    }
    return result;
}

function sendFileRequest(path, fileId, requestParams, headers, ignoredStatusCodes) {

    if (!headers) {
        headers = {};
    }
    if (!headers['X-Auth-Token']) {
        headers['X-Auth-Token'] = [AUTH];
    }
    if (!headers['Accept']) {
        headers['Accept'] = ['application/json'];
    }
    if (!headers['Content-Type']) {
        headers['Content-Type'] = ['application/json'];
    }

    let request = {
        Method: 'POST',
        Headers: headers
    };

    let result = httpMultipart(BASE_URL + path, fileId, request, requestParams, params.insecure, params.proxy);

    if (result.StatusCode < 200 || result.StatusCode >= 300) {
        if (result.StatusCode === 404) {
            throw `${result.Body} (Status Code: 404)`;
        }
        throw `Request Failed.\nStatus code: ${result.StatusCode}.\nMessage: ${JSON.stringify(result.Body)}`;
    }
    return result;
}

function createEntry(title, data, dataMap, contextKeys, headerTransformer) {
    let headers = dataMap.map(cn => cn.to);
    let translatedData = mapObjFunction(dataMap)(data);
    let humanReadable = tableToMarkdown(title, translatedData, headers, undefined, headerTransformer);
    let contextData = createContext(translatedData);
    let context = {};
    for (let i = 0 ; i < contextKeys.length; i++) {
        let key = contextKeys[i];
        context[key] = contextData;
    }
    return {
        Type: entryTypes.note,
        Contents: data,
        ContentsType: formats.json,
        ReadableContentsFormat: formats.markdown,
        HumanReadable: humanReadable,
        EntryContext: context,
    };
}

/// Cb Live Response Session

function testModule() {
    let res = sendRequest('/session', 'GET');
    if (res.StatusCode === 200) {
        return 'ok';
    }
    // 405 - Method Not Allowed.
    // This error can raise when using CB Defence; This URL (which is used to list sessions) is theoretically not available for CB Defence. In practice it works for some cases.
    // 401 is the status code used for 'UNAUTHORIZED' error
    if (CB_PRODUCT === 'Defense' && res.StatusCode === 405) {
        return 'ok';
    }
    return `Test failed. Status Code: ${res.StatusCode}`
}

const sessionData = [
    {to: 'CbSensorID', from: 'sensor_id'},
    {to: 'CbSessionID', from: 'id'},
    {to: 'Hostname', from: 'hostname'},
    {to: 'Status', from: 'status'},
    {to: 'WaitTimeout', from: 'sensor_wait_timeout'},
    {to: 'SessionTimeout', from: 'session_timeout'},
    {to: 'SupportedCommands', from: 'supported_commands'}
];

function getSessionsRequest(sessionId, sensorId, status) {
    let path = `/session`;
    if (sessionId) {
        path += '/' + sessionId;
    }

    let response = sendRequest(path, 'GET').Body;
    let result;
    try {
        result = JSON.parse(response);
    } catch (err) {
        throw `Could not parse response.\nError: ${err}.\nResponse: ${response}`;
    }

    // If optional sensor argument is given, filter the results by it.
    if (!sessionId && sensorId) {
        sensorId = parseInt(sensorId);
        result = result.filter(session => (parseInt(session.sensor_id) === sensorId));
    }
    if (!sessionId && status) {
        result = result.filter(session => (status.indexOf(session.status) > -1));
    }

    return result;
}

function getSessions() {
    let result = getSessionsRequest(args.session, args.sensor, args.status);

    let title = `Cb ${CB_PRODUCT} - Get Sessions`;
    let dataMap = sessionData;
        //keep CbResponse context for backward competability
    let contextKeys = [
        'CbResponse.Sessions(val.CbSessionID==obj.CbSessionID)',
        'CbLiveResponse.Sessions(val.CbSessionID==obj.CbSessionID)'
    ];
    return createEntry(title, result, dataMap, contextKeys, splitCamelCase);
}

function createSessionRequest(sensorId, commandTimeout, keepaliveTimeout) {
    let queryParams = {
        sensor_id: parseInt(sensorId)
    };
    if (commandTimeout) {
        queryParams.session_timeout = keepaliveTimeout;
    }
    if (keepaliveTimeout) {
        queryParams.sensor_wait_timeout = commandTimeout;
    }
    let path = CB_PRODUCT === 'Response' ?  '/session' : `/session/${sensorId}`;
    let response = sendRequest(path, 'POST', queryParams).Body;
    try {
        return JSON.parse(response);
    } catch (err) {
        throw `Could not parse response.\nError: ${err}.\nResponse: ${response}`;
    }
}

function createSession() {
    let result = createSessionRequest(args.sensor, args['command-timeout'], args['keepalive-timeout']);

    let title = `CB ${CB_PRODUCT} - Create Session`;
    let dataMap = sessionData;
    //keep CbResponse context for backward competability
    let contextKeys = [
        'CbResponse.Sessions(val.CbSessionID==obj.CbSessionID)',
        'CbLiveResponse.Sessions(val.CbSessionID==obj.CbSessionID)'
    ];
    return createEntry(title, result, dataMap, contextKeys, splitCamelCase);
}

function createSessionAndWait() {
    let result = createSessionRequest(args.sensor, args['command-timeout'], args['keepalive-timeout']);
    sleep(1000);
    let sessionId = result.id;
    let timeout = (args['wait-timeout']) ? parseInt(args['wait-timeout']) * 1000 : DEFAULT_WAIT_TIMEOUT ;
    let retries = Math.ceil(timeout / SLEEP_BETWEEN_RETRIES);

    let curTry = 0;
    while (curTry < retries) {
        let result = getSessionsRequest(sessionId, args.sensor);
        let status = result.status.toLowerCase()
        if (status === 'active' ) {
            let title = `CB ${CB_PRODUCT} - Create Session And Wait`;
            let dataMap = sessionData;
            //keep CbResponse context for backward competability
            let contextKeys = [
                'CbResponse.Sessions(val.CbSessionID==obj.CbSessionID)',
                'CbLiveResponse.Sessions(val.CbSessionID==obj.CbSessionID)'
            ];
            return createEntry(title, result, dataMap, contextKeys, splitCamelCase);
        } else if (status !== 'pending') {
            throw `Executing session ${sessionId} failed, status: ${result.status}`;
        }
        sleep(SLEEP_BETWEEN_RETRIES);
        curTry++;
    }
    throw `Exceeded timeout.\nNew session for sensor ${args.sensor} was created with ID: ${sessionId}.\nSession status remains '${result.status}'. Wait for session to become active (you may query for session staus with 'cb-session-info').\nIt is recomended to increase wait-timeout for this command.`;
}

function closeSessionRequest(sessionId) {
    let queryParams = {
        session_id: sessionId
    };
    queryParams.status = CB_PRODUCT === 'Response' ? 'close' : 'CLOSE';
    let path = CB_PRODUCT === 'Response' ? `/session/${sessionId}` : '/session';
    let response = sendRequest(path, 'PUT', queryParams).Body;
    try {
        return JSON.parse(response);
    } catch (err) {
        throw `Could not parse response.\nError: ${err}.\nResponse: ${response}`;
    }
}

function closeSession() {
    let result = closeSessionRequest(args.session);
    let title = `CB ${CB_PRODUCT} - Session Closed`;
    let dataMap = sessionData;
    //keep CbResponse context for backward competability
    let contextKeys = [
        'CbResponse.Sessions(val.CbSessionID==obj.CbSessionID)',
        'CbLiveResponse.Sessions(val.CbSessionID==obj.CbSessionID)'
    ];
    // cb response - session will have 'active' value for 'status' field although status is 'closed'
    if (CB_PRODUCT === 'Response') {
        // retrieving closed session info returns inconsistent results (expected to return the updated info with correct status, but in practice this may return an error)
        // do not try to retrieve updated session info, simply change the session status in the result to avoid confusion
        // see https://developer.carbonblack.com/reference/enterprise-response/6.1/live-response-api/#close-sessions
        result.status = 'close'
    }
    return createEntry(title, result, dataMap, contextKeys, splitCamelCase);
}

function sessionKeepaliveRequest(sessionId) {
    let response = sendRequest(`/session/${sessionId}/keepalive`, 'GET', undefined, undefined, [404]);

    if (response.StatusCode === 404) {
        throw `Session ${sessionId} has expired and is now closed. Create a new session to continue working.`;
    }

    try {
        return JSON.parse(response.Body);
    } catch (err) {
        throw `Could not parse response.\nError: ${err}.\nResponse: ${response.Body}`;
    }
}

function sessionKeepAlive() {
    let result = sessionKeepaliveRequest(args.session);

    let translatedData = mapObjFunction(sessionData)(result);
    let contextData = createContext(translatedData);
    //keep CbResponse context for backward competability
    let context = {
        'CbResponse.Sessions(val.CbSessionID==obj.CbSessionID)': contextData,
        'CbLiveResponse.Sessions(val.CbSessionID==obj.CbSessionID)': contextData
    };

    return {
        Type: entryTypes.note,
        Contents: result,
        ContentsType: formats.json,
        ReadableContentsFormat: formats.text,
        HumanReadable: `Keepalive successful for session ${args.session}`,
        EntryContext: context,
    };
}

function archiveSessionRequest(sessionId) {
    let response = sendRequest(`/session/${sessionId}/archive`, 'GET', undefined, undefined, [500]);
    if (response.StatusCode === 500) {  // Current bug in CBResponse returns 500 for empty sessions
        throw `Session ${sessionId} is empty and so it has no archive.`;
    }
    return response;
}

function archiveSession() {
    let response = archiveSessionRequest(args.session);
    let fileEntryId = saveFile(response.Bytes);
    let fileName = `session-${args.session}-archive.zip`;
    return {
        Type: entryTypes.file,
        FileID: fileEntryId,
        File: fileName,
        Contents: fileName
    };
}
/// Cb Live Response file operations

const fileData = [
    {to: 'CbFileID', from: 'id'},
    {to: 'Filename', from: 'file_name'},
    {to: 'Size', from: 'size'},
    {to: 'SizeUploaded', from: 'size_uploaded'},
    {to: 'Status', from: 'status'},
    {to: 'Delete', from: 'delete'}
];

function listFilesRequest(sessionId, fileId) {
    if (!sessionId) {
        throw 'Session ID is required';
    }
    let path = `/session/${sessionId}/file`;
    if (fileId) {
        path += '/' + fileId;
    }

    let response = sendRequest(path, 'GET').Body;
    try {
        return JSON.parse(response);
    } catch (err) {
        throw `Could not parse response.\nError: ${err}.\nResponse: ${response}`;
    }
}

function listFiles() {
    let result = listFilesRequest(args.session, args['file-id']);

    let title = `CB ${CB_PRODUCT} - List Files`;
    let dataMap = fileData;
    //keep CbResponse context for backward competability
     let contextKeys = [
        'CbResponse.Files(val.CbFileID==obj.CbFileID)',
        'CbLiveResponse.Files(val.CbFileID==obj.CbFileID)'
    ];
    return createEntry(title, result, dataMap, contextKeys, splitCamelCase);
}

function downloadFileRequest(sessionId, fileId) {
    var headers = {Accept: ['*/*']};
    if (!sessionId) {
        throw 'Session ID is required';
    }
    if (!fileId) {
        throw 'File ID is required';
    }
    let path = `/session/${sessionId}/file/${fileId}/content`;
    return sendRequest(path, 'GET', null, headers);
}

function downloadFileEntry(sessionId, fileId) {
    let fileInfo = listFilesRequest(sessionId, fileId);
    let fileContentResponse = downloadFileRequest(sessionId, fileId);
    let fileEntryId = saveFile(fileContentResponse.Bytes);
    let fileName = fileInfo.file_name.split('\\').pop();
    return {
        Type: entryTypes.file,
        FileID: fileEntryId,
        File: fileName,
        Contents: fileInfo.file_name
    };
}

function downloadFile() {
    return downloadFileEntry(args['session'], args['file-id']);
}

function uploadFileRequest(sessionId, fileId) {
    if (!sessionId) {
        throw 'Session ID is required';
    }
    if (!fileId) {
        throw 'File ID is required';
    }
    let response = sendFileRequest(`/session/${sessionId}/file`, fileId);
    try {
        return JSON.parse(response.Body);
    } catch (err) {
        throw `Could not parse response.\nError: ${err}.\nResponse: ${response}`;
    }
}

function uploadFile() {
    let result = uploadFileRequest(args.session, args['file-id']);

    let title = `CB ${CB_PRODUCT} - Upload File`;
    let dataMap = fileData;
    //keep CbResponse context for backward competability
    let contextKeys = [
        'CbResponse.Files(val.CbFileID==obj.CbFileID)',
        'CbLiveResponse.Files(val.CbFileID==obj.CbFileID)'
    ];
    return createEntry(title, result, dataMap, contextKeys, splitCamelCase);
}

function deleteFileRequest(sessionId, fileId) {
    if (!sessionId) {
        throw 'Session ID is required';
    }
    if (!fileId) {
        throw 'File ID is required';
    }
    let path = `/session/${sessionId}/file/${fileId}`;
    let response = sendRequest(path, 'DELETE').Body;
}

function deleteFile() {
    deleteFileRequest(args.session, args['file-id']);
    return {
        Type: entryTypes.note,
        Contents: `File ${args['file-id']} deleted successfully`,
        ContentsType: formats.text
    };
}

/// Cb Live Response Commands

//generic  function to create a new command
function createCommandRequest(sessionId, name, timeout, object, compress, wait, workingDir, outputFile, valueData,
                              valueType, overwrite, offset, getCount) {
    let queryParams = {
        name: name.split('-').join(' ')
    };
    if (timeout) {
        queryParams.timeout = timeout;
    }
    if (object) {
        queryParams.object = object;
    }
    if (compress) {
        queryParams.compress = compress;
    }
    queryParams.wait = true;
    if (wait !== undefined && wait === false) {
        queryParams = wait;
    }
    if (workingDir) {
        queryParams.working_directory = workingDir;
    }
    if (outputFile) {
        queryParams.output_file = outputFile;
    }
    if (valueData) {
        queryParams.value_data = valueData;
    }
    if (valueType) {
        queryParams.value_type = valueType;
    }
    if (overwrite) {
        queryParams.overwrite = overwrite;
    }
    if (offset) {
        queryParams.offset = offset;
    }
    if (getCount) {
        queryParams.get_count = getCount;
    }

    let response = sendRequest(`/session/${sessionId}/command`, 'POST', queryParams).Body;
    try {
        return JSON.parse(response);
    } catch (err) {
        throw `Could not parse response.\nError: ${err}.\nResponse: ${response}`;
    }
}

//TODO: Spec for commands interface
function createCommand() {
    let result = createCommandRequest(args.session, args.name, args.timeout, args.object, args.compress, args.wait,
        args['working-dir'], args['output-file'], args['value-data'], args['value-type'], args.overwrite, args.offset,
        args['get-count']);

    let title = `CB Response - Run Command ${args.name}`;
    let dataMap = COMMAND_DATA;
    let contextKeys = [
        'CbResponse.Commands(val.CbCommandID == obj.CbCommandID && val.CbSessionID == obj.CbSessionID)',
        'CbLiveResponse.Commands(val.CbCommandID == obj.CbCommandID && val.CbSessionID == obj.CbSessionID)'
    ];
    return createEntry(title, command, dataMap, contextKeys, splitCamelCase);
}

function getCommandRequest(sessionId, commandId) {
    let path = `/session/${sessionId}/command/${commandId}`;
    let response = sendRequest(path, 'GET').Body;
    try {
        return JSON.parse(response);
    } catch (err) {
        throw `Could not parse response.\nError: ${err}.\nResponse: ${response}`;
    }
}

function getCommandsRequest(sessionId) {
    let path = `/session/${sessionId}/command`;
    let response = sendRequest(path, 'GET').Body;
    try {
        return JSON.parse(response);
    } catch (err) {
        throw `Could not parse response.\nError: ${err}.\nResponse: ${response}`;
    }
}

function getCommands() {
    let result = getCommandsRequest(args.session);
    let title = `CB ${CB_PRODUCT} - Get Commands`;
    let dataMap = COMMAND_DATA;
    //keep CbResponse context for backward competability
    let contextKeys = [
        'CbResponse.Commands(val.CbCommandID == obj.CbCommandID && val.CbSessionID == obj.CbSessionID)',
        'CbLiveResponse.Commands(val.CbCommandID == obj.CbCommandID && val.CbSessionID == obj.CbSessionID)'
    ];
    return createEntry(title, result, dataMap, contextKeys, splitCamelCase);
}

function createCommandAndWait() {
    let result = createCommandRequest(args.session, args.name, args.timeout, args.object, args.compress, args.wait,
        args['working-dir'], args['output-file'], args['value-data'], args['value-type'], args.overwrite, args.offset,
        args['get-count']);
    sleep(1000);
    let commandId = result.id;
    let timeout = (args['wait-timeout']) ? parseInt(args['wait-timeout']) * 1000 : DEFAULT_WAIT_TIMEOUT;
    let retries = Math.ceil(timeout / SLEEP_BETWEEN_RETRIES);

    let curTry = 0;
    while (curTry < retries) {
        let result = getCommandRequest(args.session, commandId);

        if (result.status === 'complete') {
            let entries = [];
            let title = 'CB Response - Execute Command And Wait';
            let dataMap = COMMAND_DATA;
            let headers = dataMap.map(cn => cn.to);
            let translatedData = mapObjFunction(dataMap)(result);
            let humanReadable = tableToMarkdown(title, translatedData, headers, undefined, dotToSpace);
            let context = {
                'CbResponse.Commands(val.CbCommandID == obj.CbCommandID && val.CbSessionID == obj.CbSessionID)': createContext(translatedData)
            };
            entries.push({
                Type: entryTypes.note,
                Contents: result,
                ContentsType: formats.json,
                ReadableContentsFormat: formats.markdown,
                HumanReadable: humanReadable,
                EntryContext: context
            });

            // If we have the command in args then we get info for the command,
            // in this case we want to parse the result:
            let contents = result;
            switch (result.name) {
                case "directory list":
                    contents = result.files;
                    break;
                case "process list":
                    contents = result.processes;
                    break;
            }
            logInfo("Here2");
            entries.push({
                Type: entryTypes.note,
                Contents: contents,
                ContentsType: formats.json,
                // TODO: Add human readable and context for specific commands
            });

            return entries;

        } else if (result.status !== 'pending') {
            throw `Executing command ${commandId} failed, status: ${result.status}`;
        }
        sleep(SLEEP_BETWEEN_RETRIES);
        curTry++;
    }
    throw `Executing command ${commandId} timedout (${timeout / 1000} seconds), increase wait-timeout and try again`;
}

function cancelCommandRequest(sessionId, commandId) {
    let queryParams = {cmdid: commandId};
    let response = sendRequest(`/session/${sessionId}/command/${commandId}`, 'PUT', queryParams).Body;
    try {
        return JSON.parse(response);
    } catch (err) {
        throw `Could not parse response.\nError: ${err}.\nResponse: ${response}`;
    }
}

function cancelCommand() {
    let result = cancelCommandRequest(args.session, args.command);

    let title = `CB ${CB_PRODUCT} - Cancel Command`;
    let dataMap = COMMAND_DATA;
    //keep CbResponse context for backward competability
    let contextKeys = [
        'CbResponse.Commands(val.CbCommandID == obj.CbCommandID && val.CbSessionID == obj.CbSessionID)',
        'CbLiveResponse.Commands(val.CbCommandID == obj.CbCommandID && val.CbSessionID == obj.CbSessionID)'
    ];
    return createEntry(title, result, dataMap, contextKeys, splitCamelCase);
}

/// Explicit Commands

const directoryData = [
    {to: 'FileAttributes', from: 'attributes'},
    {to: 'CreateTime', from: 'create_time'},
    {to: 'LastAccessTime', from: 'last_access_time'},
    {to: 'LastWriteTime', from: 'last_write_time'},
    {to: 'FileSize', from: 'size'},
    {to: 'FileName', from: 'filename'},
    {to: 'AlternativeName', from:'alt_name'}
];

const processesData = [
    {to: 'ProcessID', from: 'pid'},
    {to: 'CreateTime', from: 'create_time'},
    {to: 'ProcessGuid', from: 'proc_guid'},
    {to: 'Path', from: 'path'},
    {to: 'CommandLine', from: 'command_line'},
    {to: 'SecurityIdentifier', from: 'sid'},
    {to: 'Username', from: 'username'},
    {to: 'Parent', from: 'parent'},
    {to: 'ParentGuid', from: 'parent_guid'}
];

const processData = [
    {to: 'ProcessID', from: 'pid'},
    {to: 'ReturnCode', from: 'return_code'}
];

const memdumpData = [
    {to: 'ReturnCode', from: 'return_code'},
    {to: 'CompressingEnabled', from: 'compressing'},
    {to: 'Complete', from: 'complete'},
    {to: 'PercentDone', from: 'percentdone'},
    {to: 'DumpingInProgress', from: 'dumping'}
];

const regKeysData = [
    {to: 'RegKeyType', from: 'value_type'},
    {to: 'RegKeyName', from: 'value_name'},
    {to: 'RegKeyData', from: 'value_data'}
];

const regKeyData = [
    {to: 'RegKeyType', from: 'value.value_type'},
    {to: 'RegKeyName', from: 'value.value_name'},
    {to: 'RegKeyData', from: 'value.value_data'}
];

function collectRegistryDataToGeneralContext(data) {
    let regKey = CB_PRODUCT === 'Response' ?  data.object : data.obj.object;
    let RegistryKeys = [];
    for (let value of data.values) {
        let entry = {
            Path: regKey,
            Name: value.value_name,
            Value: value.value_data
        };
        RegistryKeys.push(entry);
    }
    return RegistryKeys;
};

const commandEntries = {
    'directory list' : function(data) {
        let dataMap = COMMAND_DATA;
        let title = `CB ${CB_PRODUCT} - Directory Listing: Command Status`;
        let contextKeys = ['CbLiveResponse.Commands(val.CbCommandID == obj.CbCommandID && val.CbSessionID == obj.CbSessionID)'];
        let commandInfoEntry = createEntry(
            title,
            data,
            dataMap,
            contextKeys,
            splitCamelCase
        );
        if (data.status !== 'complete') {
            return commandInfoEntry;
        }
        //create entry to hold directory data
        dataMap = directoryData;
        title = `CB ${CB_PRODUCT} - Directory Listing`;
        contextKeys = ['CbLiveResponse.Commands(val.CbCommandID == obj.CbCommandID && val.CbSessionID == obj.CbSessionID).Files'];
        let directoryListEntry = createEntry(
            title,
            data.files,
            dataMap,
            contextKeys,
            splitCamelCase
        );
        return [commandInfoEntry, directoryListEntry];
    },
    'put file': function(data) {
        let dataMap = COMMAND_DATA;
        let title = `CB ${CB_PRODUCT} - Push File: Command Status`;
        let contextKeys = ['CbLiveResponse.Commands(val.CbCommandID == obj.CbCommandID && val.CbSessionID == obj.CbSessionID)'];
        let commandInfoEntry = createEntry(
            title,
            data,
            dataMap,
            contextKeys,
            splitCamelCase
        );
        return commandInfoEntry;
    },
    'get file': function(data) {
        let dataMap = COMMAND_DATA;
        let title = `CB ${CB_PRODUCT} - Get File From Path ${args.path}: Command Status`;
        let contextKeys = ['CbLiveResponse.Commands(val.CbCommandID==obj.CbCommandID&&val.CbSessionID==obj.CbSessionID)'];
        if (data.status === 'complete') {
            dataMap.push({to: 'FileID', from: 'file_id'});
        }
        let commandInfoEntry = createEntry(
            title,
            data,
            dataMap,
            contextKeys,
            splitCamelCase
        );
        return commandInfoEntry;
    },
    'kill': function(data) {
        let dataMap = COMMAND_DATA;
        let title = `CB ${CB_PRODUCT} - Kill Process ${args.pid}: Command Status`;
        let contextKeys = ['CbLiveResponse.Commands(val.CbCommandID == obj.CbCommandID && val.CbSessionID == obj.CbSessionID)'];
        let commandInfoEntry = createEntry(
            title,
            data,
            dataMap,
            contextKeys,
            splitCamelCase
        );
        return commandInfoEntry;
    },
    'create process' : function(data) {
        let dataMap = COMMAND_DATA;
        if (data.status === 'complete') {
            dataMap = dataMap.concat(processData);
        }
        let title = `CB ${CB_PRODUCT} - Execute Process: Command Status`;
        let contextKeys = ['CbLiveResponse.Commands(val.CbCommandID == obj.CbCommandID && val.CbSessionID == obj.CbSessionID)'];
        let commandInfoEntry = createEntry(
            title,
            data,
            dataMap,
            contextKeys,
            splitCamelCase
        );
        return commandInfoEntry;
    },
     'memdump': function(data) {
        let dataMap = COMMAND_DATA;
        if (data.status === 'complete') {
            dataMap = dataMap.concat(memdumpData);
        }
        let title = `CB ${CB_PRODUCT} - Memdump: Command Status`;
        let contextKeys = ['CbLiveResponse.Commands(val.CbCommandID == obj.CbCommandID && val.CbSessionID == obj.CbSessionID)'];
        let commandInfoEntry = createEntry(
            title,
            data,
            dataMap,
            contextKeys,
            splitCamelCase
        );
        return commandInfoEntry;
    },
     'delete file': function(data) {
        let dataMap = COMMAND_DATA;
        let title = `CB ${CB_PRODUCT} - Delete File From Endpoint: Command Status`;
        let contextKeys = ['CbLiveResponse.Commands(val.CbCommandID == obj.CbCommandID && val.CbSessionID == obj.CbSessionID)'];
        let commandInfoEntry = createEntry(
            title,
            data,
            dataMap,
            contextKeys,
            splitCamelCase
        );
        return commandInfoEntry;
    },
     'reg enum key': function(data) {
        let dataMap =  COMMAND_DATA;
        if (data.status === 'complete'){
            dataMap.push({to: 'SubKeys', from: 'sub_keys'});
        }
        let commandData = mapObjFunction(dataMap)(data);
        let commandMD = tableToMarkdown(
            `CB ${CB_PRODUCT} - Registry Keys: Command Status`,
            commandData,
            dataMap.map(cn => cn.to),
            undefined,
            splitCamelCase
        );

        if (data.status !== 'complete' || !data.values) {
            return {
                Type: entryTypes.note,
                Contents: data,
                ContentsType: formats.json,
                ReadableContentsFormat: formats.markdown,
                HumanReadable: commandMD,
                EntryContext: {
                    'CbLiveResponse.Commands(val.CbCommandID == obj.CbCommandID && val.CbSessionID == obj.CbSessionID)': commandData
                }
            };
        }

        let registryEntry = mapObjFunction(regKeysData)(data.values);
        let registryMD = tableToMarkdown(
            `Registry Values`,
            registryEntry,
            regKeysData.map(cn => cn.to),
            undefined,
            splitCamelCase
        );

        //collect registry data for general context
        let generalConetxt = collectRegistryDataToGeneralContext(data);

        return {
            Type: entryTypes.note,
            Contents: data,
            ContentsType: formats.json,
            ReadableContentsFormat: formats.markdown,
            HumanReadable: commandMD + '\n\n' + registryMD,
            EntryContext: {
                'CbLiveResponse.Commands(val.CbCommandID == obj.CbCommandID && val.CbSessionID == obj.CbSessionID)': commandEntry,
                'CbLiveResponse.Commands(val.CbCommandID == obj.CbCommandID && val.CbSessionID == obj.CbSessionID).Values': registryEntry,
                'RegistryKey': generalConetxt
            }
        };
    },
     'reg query value': function(data) {
        let dataMap = COMMAND_DATA;
        if (data.status === 'complete') {
            dataMap = dataMap.concat(regKeyData);
        }
        let commandData = mapObjFunction(dataMap)(data);
        let commandMD = tableToMarkdown(
            `CB ${CB_PRODUCT} - Query Registry Value: Command Status`,
            commandData,
            dataMap.map(cn => cn.to),
            undefined,
            splitCamelCase
        );

        let context = {
            'CbLiveResponse.Commands(val.CbCommandID == obj.CbCommandID && val.CbSessionID == obj.CbSessionID)': commandData
        };
        if (data.status !== 'complete') {
            context.RegistryKey = collectRegistryDataToGeneralContext(data);
        }
        return {
            Type: entryTypes.note,
            Contents: data,
            ContentsType: formats.json,
            ReadableContentsFormat: formats.markdown,
            HumanReadable: commandMD,
            EntryContext: context
        };
    },
     'reg create key': function(data) {
        let dataMap = COMMAND_DATA;
        let title = `CB ${CB_PRODUCT} - Create Registry Key: Command Status`;;
        let contextKeys = ['CbLiveResponse(val.CbCommandID == obj.CbCommandID && val.CbSessionID == obj.CbSessionID)'];
        let commandInfoEntry = createEntry(
            title,
            data,
            dataMap,
            contextKeys,
            splitCamelCase
        );
        return commandInfoEntry;
    },
     'reg delete key': function(data) {
        let dataMap = COMMAND_DATA;
        let title = `CB ${CB_PRODUCT} - Create Registry Key: Command Status`;;
        let contextKeys = ['CbLiveResponse.Commands(val.CbCommandID == obj.CbCommandID && val.CbSessionID == obj.CbSessionID)'];
        let commandInfoEntry = createEntry(
            title,
            data,
            dataMap,
            contextKeys,
            splitCamelCase
        );
        return commandInfoEntry;
    },
     'reg delete values': function(data) {
        let dataMap = COMMAND_DATA;
        let title = `CB ${CB_PRODUCT} - Delete Registry Value: Command Status`;;
        let contextKeys =  ['CbLiveResponse.Commands(val.CbCommandID == obj.CbCommandID && val.CbSessionID == obj.CbSessionID)'];
        let commandInfoEntry = createEntry(
            title,
            data,
            dataMap,
            contextKeys,
            splitCamelCase
        );
        return commandInfoEntry;
    },
     'reg set values': function(data) {
        let dataMap = COMMAND_DATA;
        let title = `CB ${CB_PRODUCT} - Delete Registry Value: Command Status`;;
        let contextKeys =  ['CbLiveResponse.Commands(val.CbCommandID == obj.CbCommandID && val.CbSessionID == obj.CbSessionID)'];
        let commandInfoEntry = createEntry(
            title,
            data,
            dataMap,
            contextKeys,
            splitCamelCase
        );
        return commandInfoEntry;
    },
    'process list' : function(data) {
        let commandData = mapObjFunction(COMMAND_DATA)(data);
        let commandMD = tableToMarkdown(
            `CB ${CB_PRODUCT} - List Processes: Command Status`,
            commandData,
            COMMAND_DATA.map(cn => cn.to),
            undefined,
            splitCamelCase
        );
        if (data.status !== 'complete') {
            return {
                Type: entryTypes.note,
                Contents: data,
                ContentsType: formats.json,
                ReadableContentsFormat: formats.markdown,
                HumanReadable: commandMD,
                EntryContext: {
                   'CbLiveResponse.Commands(val.CbCommandID == obj.CbCommandID && val.CbSessionID == obj.CbSessionID)': commandData
                }
            };
        }
        let processes = mapObjFunction(processesData)(data.processes);
        let processesMD = tableToMarkdown(
            `CB ${CB_PRODUCT} - Processes`,
            processes,
            processesData.map(cn => cn.to),
            undefined,
            splitCamelCase
        );

        // collect processes data for general context
        let processesCollection = [];
        for (let process of data.processes) {
            processesCollection.push({
                'PID': process.pid,
                'CommandLine': process.command_line,
                'Path': process.path,
                'Start Time': process.create_time,
                'Parent': process.parent
            });
        }

        return {
            Type: entryTypes.note,
            Contents: data,
            ContentsType: formats.json,
            ReadableContentsFormat: formats.markdown,
            HumanReadable: commandMD + '\n\n' + processesMD,
            EntryContext: {
                'CbLiveResponse.Commands(val.CbCommandID == obj.CbCommandID && val.CbSessionID == obj.CbSessionID)': commandData,
                'CbLiveResponse.Commands(val.CbCommandID == obj.CbCommandID && val.CbSessionID == obj.CbSessionID).Process': processes,
                'Process': processesCollection
            }
        };
    }
};

function getCommand() {
    let command = getCommandRequest(args.session, args.command);
    if (commandEntries[command.name]){
        return commandEntries[command.name](command);
    }
    //create generic entry
    let title = `CB ${CB_PRODUCT} - Get Command`;
    let dataMap = COMMAND_DATA;
    //keep CbResponse context for backward competability
    let contextKeys = [
        'CbResponse.Commands(val.CbCommandID == obj.CbCommandID && val.CbSessionID == obj.CbSessionID)',
        'CbLiveResponse.Commands(val.CbCommandID == obj.CbCommandID && val.CbSessionID == obj.CbSessionID)'
    ];
    return createEntry(
        title,
        result,
        dataMap,
        contextKeys,
        splitCamelCase
    );
}

function getCommandInfo(sessionId, commandId, timeout, timeInterval, cancelOnPending) {
    let retries = timeout ? Math.ceil(timeout / timeInterval) : 1;
    //loop to get command info. Stop when command status is no longer 'pending' or when exeeded wait-time.
    let result;
    let curTry = 0;
    while (curTry < retries) {
        result = getCommandRequest(sessionId, commandId);
        if (result.status !== 'pending') {
            return result;
        }
        curTry++;
        sleep(timeInterval);
    }
    if (cancelOnPending && cancelOnPending === 'yes') {
        cancelCommandRequest(sessionId, commandId);
        throw 'Wait-time expired. Canceled command';
    }
    return result;
}

function terminateProcess() {
    let result = createCommandRequest(args.session, 'kill', undefined, args.pid, undefined, args.wait);
    sleep(1000);
    let commandId = result.id;
    let timeout = (args['wait-timeout']) ? parseInt(args['wait-timeout']) * 1000 : DEFAULT_WAIT_TIMEOUT;
    let retries = Math.ceil(timeout / SLEEP_BETWEEN_RETRIES);

    let curTry = 0;
    while (curTry < retries) {
        let result = getCommandRequest(args.session, commandId);
        if (result.status === 'complete') {
            let title = `CB Response - Terminate Process ${args.pid}`;
            let dataMap = COMMAND_DATA;
            let headers = dataMap.map(cn => cn.to);
            let translatedData = mapObjFunction(dataMap)(result);
            let humanReadable = tableToMarkdown(title, translatedData, headers, undefined, dotToSpace);
            let context = {
                'CbResponse.Commands(val.CbCommandID == obj.CbCommandID && val.CbSessionID == obj.CbSessionID)': createContext(translatedData)
            };
            return {
                Type: entryTypes.note,
                Contents: result,
                ContentsType: formats.json,
                ReadableContentsFormat: formats.markdown,
                HumanReadable: humanReadable,
                EntryContext: context,
            };
        } else if (result.status !== 'pending') {
            throw `Terminating process failed, status: ${result.status}`;
        }
        sleep(SLEEP_BETWEEN_RETRIES);
        curTry++;
    }
    throw `Terminating process timedout (${timeout / 1000} seconds), increase wait-timeout and try again`;
}

function putFileRequest(sessionId, fileId, path) {
    let queryParams = {
        name: 'put file',
        object: path,
        file_id: fileId
    };

    let response = sendRequest(`/session/${sessionId}/command`, 'POST', queryParams).Body;
    try {
        return JSON.parse(response);
    } catch (err) {
        throw `Could not parse response.\nError: ${err}.\nResponse: ${response}`;
    }
}

function putFile() {
    let fileInfo = uploadFileRequest(args['session'], args['entry-id']);
    let result = putFileRequest(args['session'], fileInfo.id, args.path);
    //wait for 1 second before trying to get command information
    sleep(1000);
    let timeout = (args['wait-timeout']) ? parseInt(args['wait-timeout']) * 1000 : DEFAULT_WAIT_TIMEOUT;

    let command = getCommandInfo(args['session'], result.id, timeout, SLEEP_BETWEEN_RETRIES);
    let commandEntry = commandEntries['put file'](command);
    //add entry to hold gile information
    let title = `CB ${CB_PRODUCT} - File Info`;
    let dataMap = fileData;
    let contextKeys = ['CbLiveResponse.Files(val.CbFileID==obj.CbFileID)'];
    let fileInfoEntry = createEntry(
        title,
        fileInfo,
        dataMap,
        contextKeys,
        splitCamelCase
    );
    return [commandEntry, fileInfoEntry];
}

function getFileRequest(sessionId, path, offset, bytes)   {
    let queryParams = {
        name: 'get file',
        object: path,
        offset: offset
    };
    if (bytes) {
        queryParams['get_count'] = bytes;
    }

    let response = sendRequest(`/session/${sessionId}/command`, 'POST', queryParams).Body;
    try {
        return JSON.parse(response);
    } catch (err) {
        throw `Could not parse response.\nError: ${err}.\nResponse: ${response}`;
    }
}

function getFile() {
    let command = getFileRequest(args.session, args.path, 0);
    //wait for 1 second before trying to get command information
    sleep(1000);
    let timeout = (args['wait-timeout']) ? parseInt(args['wait-timeout']) * 1000 : DEFAULT_WAIT_TIMEOUT;
    try{
        command = getCommandInfo(args['session'], command.id, timeout, SLEEP_BETWEEN_RETRIES, args['cancel-on-timeout']);
    }
    catch(err) {
        throw `Failed to get the file.\nError: ${err}.`;
    }
    let commandEntry = commandEntries['get file'](command);
    let fileEntry = {}
    if (args.download == 'true') {
      if (command.status !== 'complete') {
          return commandEntry;
      }
      //download the file from Cb server and add file entry to the war room
      fileEntry = downloadFileEntry(args['session'], command['file_id']);

      return [commandEntry, fileEntry];
    }

    return commandEntry;
}

function directoryListRequest(sessionId, path)   {
    let queryParams = {
        name: 'directory list',
        object: path
    };

    let response = sendRequest(`/session/${sessionId}/command`, 'POST', queryParams).Body;
    try {
        return JSON.parse(response);
    } catch (err) {
        throw `Could not parse response.\nError: ${err}.\nResponse: ${response}`;
    }
}

function directoryList() {
    let result = directoryListRequest(args['session'], args.path);
    //wait for 1 second before trying to get command information
    sleep(1000);
    let timeout = args['wait-timeout'] ? parseInt(args['wait-timeout']) * 1000 : DEFAULT_WAIT_TIMEOUT;
    let command = getCommandInfo(args['session'], result.id, timeout, SLEEP_BETWEEN_RETRIES, args['cancel-on-timeout']);
    return commandEntries['directory list'](command);
}

function processKillRequest(sessionId, pid) {
    let queryParams = {
        name: 'kill',
        object: pid
    };
    let response = sendRequest(`/session/${sessionId}/command`, 'POST', queryParams).Body;
    try {
        return JSON.parse(response);
    } catch (err) {
        throw `Could not parse response.\nError: ${err}.\nResponse: ${response}`;
    }
}

//equivalent to 'terminateProcess' function
function processKill() {
    let result = processKillRequest(args['session'], args.pid);
    //wait for 1 second before trying to get command information
    sleep(1000);
    let timeout = (args['wait-timeout']) ? parseInt(args['wait-timeout']) * 1000 : DEFAULT_WAIT_TIMEOUT;

    let command = getCommandInfo(args['session'], result.id, timeout, SLEEP_BETWEEN_RETRIES, args['cancel-on-timeout']);
    return commandEntries['kill'](command);
}

function processExecRequest(sessionId, path, wait, workingDirectory, outputFile) {
    let queryParams = {
        name: 'create process',
        object: path
    };
    if (wait !== undefined) {
        queryParams.wait = wait;
    }
    if (workingDirectory) {
        queryParams.working_directory = workingDirectory;
    }
    if (outputFile) {
        queryParams.output_file = outputFile;
    }

    let response = sendRequest(`/session/${sessionId}/command`, 'POST', queryParams).Body;
    try {
        return JSON.parse(response);
    } catch (err) {
        throw `Could not parse response.\nError: ${err}.\nResponse: ${response}`;
    }
}

function processExec() {
    if (args.wait) {
        args.wait = args.wait === 'yes';
    }
    let result = processExecRequest(args['session'], args.path, args.wait, args['working-directory'], args['output-file']);
    //wait for 1 second before trying to get command information
    sleep(1000);
    let timeout = (args['wait-timeout']) ? parseInt(args['wait-timeout']) * 1000 : DEFAULT_WAIT_TIMEOUT;

    let command = getCommandInfo(args['session'], result.id, timeout, SLEEP_BETWEEN_RETRIES, args['cancel-on-timeout']);
    return commandEntries['create process'](command);
}

function memdumpRequest(sessionId, path, compress) {
    let queryParams = {
        name: 'memdump',
        object: path,
        compress: false //in the API there is a typo that says this field is spelled 'commpress'
    };
    if (compress === 'true') {
        queryParams.compress = true;
    }
    let response = sendRequest(`/session/${sessionId}/command`, 'POST', queryParams).Body;
    try {
        return JSON.parse(response);
    } catch (err) {
        throw `Could not parse response.\nError: ${err}.\nResponse: ${response}`;
    }
}

function memdump() {
    let result = memdumpRequest(args['session'], args.path, args.compress);
    //wait for 1 second before trying to get command information
    sleep(1000);
    let timeout = (args['wait-timeout']) ? parseInt(args['wait-timeout']) * 1000 : DEFAULT_WAIT_TIMEOUT;

    let command = getCommandInfo(args['session'], result.id, timeout, SLEEP_BETWEEN_RETRIES, args['cancel-on-timeout']);
    return commandEntries['memdump'](command);
}

function deleteFileFromEndpointRequest(sessionId, path){
    let queryParams = {
        name: 'delete file',
        object: path
    };
    let response = sendRequest(`/session/${sessionId}/command`, 'POST', queryParams).Body;
    try {
        return JSON.parse(response);
    } catch (err) {
        throw `Could not parse response.\nError: ${err}.\nResponse: ${response}`;
    }
}

function deleteFileFromEndpoint() {
    let result = deleteFileFromEndpointRequest(args['session'], args.path);
    //wait for 1 second before trying to get command information
    sleep(1000);
    let timeout = (args['wait-timeout']) ? parseInt(args['wait-timeout']) * 1000 : DEFAULT_WAIT_TIMEOUT;

    let command = getCommandInfo(args['session'], result.id, timeout, SLEEP_BETWEEN_RETRIES, args['cancel-on-timeout']);
    return commandEntries['delete file'](command);
}

function regEnumKeyRequest(sessionId, path){
    let queryParams = {
        name: 'reg enum key',
        object: path
    };
    let response = sendRequest(`/session/${sessionId}/command`, 'POST', queryParams).Body;
    try {
        return JSON.parse(response);
    } catch (err) {
        throw `Could not parse response.\nError: ${err}.\nResponse: ${response}`;
    }
}

function regEnumKey() {
    let result = regEnumKeyRequest(args.session, args.path);
    //wait for 1 second before trying to get command information
    sleep(1000);
    let timeout = (args['wait-timeout']) ? parseInt(args['wait-timeout']) * 1000 : DEFAULT_WAIT_TIMEOUT;

    let command = getCommandInfo(args['session'], result.id, timeout, SLEEP_BETWEEN_RETRIES, args['cancel-on-timeout']);
    return commandEntries['reg enum key'](command);
}

function regQueryValueRequest(sessionId, path){
    let queryParams = {
        name: 'reg query value',
        object: path
    };
    let response = sendRequest(`/session/${sessionId}/command`, 'POST', queryParams).Body;
    try {
        return JSON.parse(response);
    } catch (err) {
        throw `Could not parse response.\nError: ${err}.\nResponse: ${response}`;
    }
}

function regQueryValue() {
    let result = regQueryValueRequest(args.session, args.path);
    //wait for 1 second before trying to get command information
    sleep(1000);
    let timeout = (args['wait-timeout']) ? parseInt(args['wait-timeout']) * 1000 : DEFAULT_WAIT_TIMEOUT;

    let command = getCommandInfo(args['session'], result.id, timeout, SLEEP_BETWEEN_RETRIES, args['cancel-on-timeout']);
    return commandEntries['reg query value'](command);
}

function regCreateRequest(sessionId, path){
    let queryParams = {
        name: 'reg create key',
        object: path
    };
    let response = sendRequest(`/session/${sessionId}/command`, 'POST', queryParams).Body;
    try {
        return JSON.parse(response);
    } catch (err) {
        throw `Could not parse response.\nError: ${err}.\nResponse: ${response}`;
    }
}

function regCreate() {
    let result = regCreateRequest(args.session, args.path, args.timeout);
    //wait for 1 second before trying to get command information
    sleep(1000);
    let timeout = (args['wait-timeout']) ? parseInt(args['wait-timeout']) * 1000 : DEFAULT_WAIT_TIMEOUT;

    let command = getCommandInfo(args['session'], result.id, timeout, SLEEP_BETWEEN_RETRIES, args['cancel-on-timeout']);
    return commandEntries['reg create key'](command);
}

function regDeleteKeyRequest(sessionId, path){
    let queryParams = {
        name: 'reg delete key',
        object: path
    };
    let response = sendRequest(`/session/${sessionId}/command`, 'POST', queryParams).Body;
    try {
        return JSON.parse(response);
    } catch (err) {
        throw `Could not parse response.\nError: ${err}.\nResponse: ${response}`;
    }
}

function regDeleteKey() {
    let result = regDeleteKeyRequest(args.session, args.path);
    //wait for 1 second before trying to get command information
    sleep(1000);
    let timeout = (args['wait-timeout']) ? parseInt(args['wait-timeout']) * 1000 : DEFAULT_WAIT_TIMEOUT;

    let command = getCommandInfo(args['session'], result.id, timeout, SLEEP_BETWEEN_RETRIES, args['cancel-on-timeout']);
    return commandEntries['reg delete key'](command);
}

function regDeleteValueRequest(sessionId, path){
    let queryParams = {
        name: 'reg delete value',
        object: path
    };
    let response = sendRequest(`/session/${sessionId}/command`, 'POST', queryParams).Body;
    try {
        return JSON.parse(response);
    } catch (err) {
        throw `Could not parse response.\nError: ${err}.\nResponse: ${response}`;
    }
}

function regDeleteValue() {
    let result = regDeleteValueRequest(args.session, args.path);
    //wait for 1 second before trying to get command information
    sleep(1000);
    let timeout = (args['wait-timeout']) ? parseInt(args['wait-timeout']) * 1000 : DEFAULT_WAIT_TIMEOUT;

    let command = getCommandInfo(args['session'], result.id, timeout, SLEEP_BETWEEN_RETRIES, args['cancel-on-timeout']);
    return commandEntries['reg delete value'](command);
}

function regSetValueRequest(sessionId, path, data, type, overwrite){
    let queryParams = {
        name: 'reg set value',
        object: path,
        value_data: data,
        value_type: type
    }
    if (overwrite) {
        queryParams.overwrite = true;
    }
    let response = sendRequest(`/session/${sessionId}/command`, 'POST', queryParams).Body;
    try {
        return JSON.parse(response);
    } catch (err) {
        throw `Could not parse response.\nError: ${err}.\nResponse: ${response}`;
    }
}

function regSetValue() {
    if (args.type = 'REG_MULTI_SZ') {
        args.data = args.data.split(',');
    }
    if (args.overwrite) {
        args.overwrite = args.overwrite === 'yes';
    }
    let result = regSetValueRequest(args.session, args.path, args.data, args.type, args.overwrite);
    //wait for 1 second before trying to get command information
    sleep(1000);
    let timeout = (args['wait-timeout']) ? parseInt(args['wait-timeout']) * 1000 : DEFAULT_WAIT_TIMEOUT;

    let command = getCommandInfo(args['session'], result.id, timeout, SLEEP_BETWEEN_RETRIES, args['cancel-on-timeout']);
    return commandEntries['reg set value'](command);
}

function listProcessesRequest(sessionId, path){
    let queryParams = {
        name: 'process list'
    }
    let response = sendRequest(`/session/${sessionId}/command`, 'POST', queryParams).Body;
    try {
        return JSON.parse(response);
    } catch (err) {
        throw `Could not parse response.\nError: ${err}.\nResponse: ${response}`;
    }
}

function listProcesses() {
    let result = listProcessesRequest(args['session'], args.path);
    //wait for 1 second before trying to get command information
    sleep(1000);
    let timeout = (args['wait-timeout']) ? parseInt(args['wait-timeout']) * 1000 : DEFAULT_WAIT_TIMEOUT;
    let command = getCommandInfo(args['session'], result.id, timeout, SLEEP_BETWEEN_RETRIES, args['cancel-on-timeout']);
    return commandEntries['process list'](command);
}

/// Execution

try {
    switch (command) {
        case 'test-module':
            return testModule();
        case 'cb-list-sessions':
            if (CB_PRODUCT == 'Defense') {
                throw '\'cb-list-sessions\' is not available for Cb Defense.';
            }
            return getSessions();
        case 'cb-session-info':
            return getSessions();
        case 'cb-session-create':
            return createSession();
        case 'cb-session-create-and-wait':
            return createSessionAndWait();
        case 'cb-session-close':
            return closeSession();
        case 'cb-keepalive':
            return sessionKeepAlive();
        case 'cb-archive':
            if (CB_PRODUCT == 'Defense') {
                throw '\'cb-archive\' is not available for Cb Defense.';
            }
            return archiveSession();
        case 'cb-list-commands':
            return getCommands();
        case 'cb-command-info':
            return getCommand();
        case 'cb-terminate-process':
            return terminateProcess();
        case 'cb-command-create':
            return createCommand();
        case 'cb-command-create-and-wait':
            return createCommandAndWait();
        case 'cb-command-cancel':
            return cancelCommand();
        case 'cb-file-get':
            return downloadFile();
        case 'cb-list-files':
        case 'cb-file-info':
            return listFiles();
        case 'cb-file-upload':
            return uploadFile();
        case 'cb-file-delete':
            return deleteFile();
    }
} catch (err) {
    return {
        Type: entryTypes.error,
        Contents: err,
        ContentsType: formats.json,
        ReadableContentsFormat: formats.text,
        HumanReadable: err.message
    };
}

// execute Cb commands
let closeSessionAfterExecution = false;
try {
    //validate either sensor or session was passed
    if ((!args.session && !args.sensor) || (args.session && args.sensor)) {
        throw 'Provide either the session ID or the sensor ID';
    }
    if (args.sensor) {
        let session = createSessionRequest(args.sensor);
        let wait = 3 * 1000;
        while (session.status === 'pending' || session.status === 'PENDING') {
            sleep(wait);
            session = getSessionsRequest(session.id);
        }
        if (session.status !== 'active' && session.status !== 'ACTIVE') {
            throw 'Failed to start a new session';
        }
        closeSessionAfterExecution = true;
        args.session = session.id;
    }
    switch (command) {
        case 'cb-process-kill':
            return processKill();
        case 'cb-directory-listing':
            return directoryList();
        case 'cb-process-execute':
            return processExec();
        case 'cb-memdeump':
            return memdump();
        case 'cb-memdump':
            return memdump();
        case 'cb-file-delete-from-endpoint':
            return deleteFileFromEndpoint();
        case 'cb-registry-get-values':
            return regEnumKey();
        case 'cb-registry-query-value':
            return regQueryValue();
        case 'cb-registry-create-key':
            return regCreate();
        case 'cb-registry-delete-key':
            return regDeleteKey();
        case 'cb-registry-delete-value':
            return regDeleteValue();
        case 'cb-registry-set-value':
            return regSetValue();
        case 'cb-process-list':
            return listProcesses();
        case 'cb-get-file-from-endpoint':
            return getFile();
        case 'cb-push-file-to-endpoint':
            return putFile();
    }
} catch (err) {
    return {
        Type: entryTypes.error,
        Contents: err,
        ContentsType: formats.json,
        ReadableContentsFormat: formats.text,
        HumanReadable: err.message
    };
} finally {
    if (closeSessionAfterExecution) {
        closeSessionRequest(args.session);
    }
}

/// Util methods

function sleep(ms) {
    var start = new Date().getTime();
    var expire = start + ms;
    while (new Date().getTime() < expire) {
        /*Do nothing*/
    }
    return;
}