Accessdata Deprecated

Deprecated. Use Exterro FTK instead.

Forensics & Malware Analysis · Accessdata (Deprecated)

Details

IDAccessdata
ProviderExterro
CategoryForensics & Malware Analysis
From Version5.0.0
Docker Imagedemisto/python3:3.10.5.31928
Supported ModulesAgentix

README

Use the Quin-C AccessData integration to protect against and provide additional visibility into phishing and other malicious email attacks. This integration was integrated and tested with version 20190926 of Quin-C Accessdata.

Documentation for the integration was provided by Quin-C.

AccessData Playbook

For example, you can look at “Accessdata: Dump memory for malicious process” playbook to understand how to use this integration.

Configure AccessData in Cortex

Parameter Description Example
Name A meaningful name for the integration instance. Quin-C Instance Alpha
Server URL The URL to the AccessData server, including the scheme. FQDN or IP address in X.X.X.X format with scheme specified.
Token A piece of data that servers use to verify for authenticity eea810f5-a6f6
Trust any certificate (not secure) When selected, certificates are not checked. N/A
Use system proxy settings Runs the integration instance using the proxy server (HTTP or HTTPS) that you defined in the server configuration. https://proxyserver.com

Commands

You can execute these commands from the 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.

Get a process list


Returns a list of processes from the legacy agent.

Base Command

accessdata-legacyagent-get-processlist

Input
Argument Name Description Required
caseid The ID of the case. Optional
target_ip The IP address of the agent. Required
Context Output
Path Type Description
Accessdata.Job.ID string The ID of the job.
Accessdata.Job.CaseID string The ID of the case.
Accessdata.Job.CaseJobID string The concatenated CaseID and JobID, for example, like “1_800”.
Accessdata.Job.Type string The job type.
Accessdata.Job.State string The execution state of the job.
Command Example
accessdata-legacyagent-get-processlist caseid=2 target_ip=X.X.X.X
Context Example
{
    "Accessdata.Job": {
        "ID": 157, 
        "Type": "Volatile", 
        "CaseID": "2", 
        "State": "Unknown", 
        "CaseJobID": "2_157"
    }
}
Human Readable Output

JobID: 157

Create a legacy agent memory dump


Creates a legacy agent memory dump.

Base Command

accessdata-legacyagent-get-memorydump

Input
Argument Name Description Required
caseid The ID of the case. Optional
target_ip The IP address of the agent. Required
Context Output
Path Type Description
Accessdata.Job.ID string The ID of the job.
Accessdata.Job.CaseID string The ID of the case.
Accessdata.Job.CaseJobID string The concatenated CaseID and JobID, for example, like “1_800”.
Accessdata.Job.Type string The job type.
Accessdata.Job.State string The execution state of the job.
Command Example
accessdata-legacyagent-get-memorydump caseid=2 target_ip=X.X.X.X
Context Example
{
    "Accessdata.Job": {
        "ID": 158, 
        "Type": "LegacyMemoryDump", 
        "CaseID": "2", 
        "State": "Unknown", 
        "CaseJobID": "2_158"
    }
}
Human Readable Output

JobID: 158

Read a file from a case folder


Reads a file from a case folder and puts the contents into the context output.

Base Command

accessdata-read-casefile

Input
Argument Name Description Required
filepath The path to the case file. Required
Context Output
Path Type Description
Accessdata.File.Contents string The contents of the file.
Command Example
accessdata-read-casefile filepath="\\X.X.X.X\D$\paths\cases\ProcessingHelperCase\b389a8e9-4ce4-473d-8d2e-9026f53f925c\Jobs\job_153\fa9787a3-49a1-4d73-a194-7c944eb9a3bf\1\snapshot.xml"
Context Example
{
    "Accessdata.File.Contents": "<?xml version=\"1.0\"?>\r\n<root>\r\n<Process resultitemtype=\"15\"><Name>addm.exe</Name><Path/><StartTi ... ress>0</baseAddress><ImageSize>0</ImageSize><ProcessName/><FromAgent/></DLL>\r\n</root>\r\n"
}
Human Readable Output
<?xml version="1.0"?>
<root>
<Process resultitemtype="15">\<Name>addm.exe</Name>\<Path/>\<StartTi ... ress>0</baseAddress>\<ImageSize>0</ImageSize>\<ProcessName/>\<FromAgent/>\</DLL>
</root>

Check the status of a job


Checks the status of a job.

Base Command

accessdata-jobstatus-scan

Input
Argument Name Description Required
caseJobID The concatenated CaseID and JobID, for example, “1_800”. Required
Context Output
Path Type Description
Accessdata.Job.CaseID string The ID of the case.
Accessdata.Job.ID string The ID of the job.
Accessdata.Job.CaseJobID string The concatenated CaseID and JobID, for example, like “1_800”.
Accessdata.Job.State string The execution state of the job.
Command Example
accessdata-jobstatus-scan caseJobID=2_153
Context Example
{
    "Accessdata.Job": {
        "ID": "153", 
        "CaseID": "2", 
        "State": "Success", 
        "CaseJobID": "2_153"
    }
}
Human Readable Output

Current job state: Success

Get a snapshot of a path


Gets a snapshot of the path from the results of the process list job.

Base Command

accessdata-get-jobstatus-processlist

Input
Argument Name Description Required
caseID The ID of the case. Required
jobID The ID of the job. Required
Context Output
Path Type Description
Accessdata.Job.State string The state of the job.
Accessdata.Job.Result string The snapshot of the path with the processes list.
Accessdata.Job.ID number The ID of the job.
Accessdata.Job.CaseID number The case ID of the job.
Accessdata.Job.CaseJobID string The concatenated CaseID and JobID, for example, like “1_800”.
Command Example
accessdata-get-jobstatus-processlist caseID=2 jobID=153
Context Example
{
    "Accessdata.Job": {
        "ID": "153", 
        "Result": "\\\\X.X.X.X\\D$\\paths\\cases\\ProcessingHelperCase\\b389a8e9-4ce4-473d-8d2e-9026f53f925c\\Jobs\\job_153\\fa9787a3-49a1-4d73-a194-7c944eb9a3bf\\1\\snapshot.xml", 
        "CaseID": "2", 
        "State": "Success", 
        "CaseJobID": "2_153"
    }
}
Human Readable Output

\X.X.X.X\D$\paths\cases\ProcessingHelperCase\b389a8e9-4ce4-473d-8d2e-9026f53f925c\Jobs\job_153\fa9787a3-49a1-4d73-a194-7c944eb9a3bf\1\snapshot.xml

Get a memory dump


Gets a memory dump path from the results of a memory dump job.

Base Command

accessdata-get-jobstatus-memorydump

Input
Argument Name Description Required
caseID The ID of the case. Required
jobID The ID of the job. Required
Context Output
Path Type Description
Accessdata.Job.State string The state of the job.
Accessdata.Job.Result string The path of the memory dump.
Accessdata.Job.ID number The ID of the job.
Accessdata.Job.CaseID number The case ID of the job.
Accessdata.Job.CaseJobID string The concatenated CaseID and JobID, for example, like “1_800”.
Command Example
accessdata-get-jobstatus-memorydump caseID=2 jobID=154
Context Example
{
    "Accessdata.Job": {
        "ID": "154", 
        "Result": "\\\\X.X.X.X\\data\\SiteServer\\storage\\60564598-ca55-475c-9f27-ab4992e8ff46\\1\\memdump.mem", 
        "CaseID": "2", 
        "State": "Success", 
        "CaseJobID": "2_154"
    }
}
Human Readable Output

\X.X.X.X\data\SiteServer\storage\60564598-ca55-475c-9f27-ab4992e8ff46\1\memdump.mem

Get an ID


Returns the ID of the processing case.

Base Command

accessdata-get-processing-case-id

Input

There are no input arguments for this command.

Context Output
Path Type Description
Accessdata.ProcessingCaseId string The ID of the processing case.
Command Example
accessdata-get-processing-case-id
Context Example
{
    "Accessdata.ProcessingCaseId": 2
}
Human Readable Output

2

Configuration parameters

  • server_name — Server URL with scheme (FQDN or IP address in X.X.X.X format with scheme specified) (required)
  • Token — The token is required to connect to Quinc. (required)
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (7)

  • accessdata-get-jobstatus-memorydump

    Returns the memory dump path from the result of the memory dump job.

  • accessdata-get-jobstatus-processlist

    Returns a snapshot path from the results of the process list job.

  • accessdata-get-processing-case-id

    Returns the ID of the Quin-C processing case.

  • accessdata-jobstatus-scan

    Checks status of the job.

  • accessdata-legacyagent-get-memorydump

    Creates a legacy agent memory dump.

  • accessdata-legacyagent-get-processlist

    Returns a list of processes from the legacy agent.

  • accessdata-read-casefile

    Reads the file from a case folder and returns the contents to the current context.

import demistomock as demisto
from CommonServerPython import *
from Accessdata import Client, create_jobstate_context, create_contents, wrap_jobstate_context, main
from test_data.constants import MOCK_URL, FAKE_SITESERVER_TOKEN, JOB_JUST_WITHOUT_CASEJOBID, JOB_JUST_WITH_CASEJOBID, \
    MOCK_PARAMS, MOCK_TEST_MODULE_RESPONSE, MOCK_GET_STATUS_ARGS, MOCK_GET_JOBSTATUS_PROCESSLIST_RESPONSE, MOCK_BASE_URL, \
    MOCK_GET_JOBSTATUS_MEMORYDUMP_RESPONSE, MOCK_ADD_JOB_ARGS, MOCK_READ_CASEFILE_ARGS, MOCK_READ_CASEFILE_RESPONSE


def create_client():
    return Client(base_url=MOCK_URL, verify=None, proxy=None, token=FAKE_SITESERVER_TOKEN)


def test_create_jobstate_context_WITHOUT_CASEJOBID():
    assert create_jobstate_context(JOB_JUST_WITHOUT_CASEJOBID) == {
        'Accessdata.Job(val.ID == obj.ID)': {
            'CaseID': 1,
            'ID': 2,
            'Type': 'JobType',
            'State': 'Unknown',
            'Result': 'Some result'
        }
    }


def test_create_jobstate_context_WITH_CASEJOBID():
    assert create_jobstate_context(JOB_JUST_WITH_CASEJOBID) == {
        'Accessdata.Job(val.CaseJobID == obj.CaseJobID)': {
            'CaseID': 1,
            'ID': 2,
            'CaseJobID': '1_2',
            'Type': 'JobType',
            'State': 'Unknown',
            'Result': 'Some result'
        }
    }


def test_create_contents():
    assert create_contents(1, 2) == {
        'CaseID': 1,
        'ID': 2,
        'CaseJobID': '1_2'
    }
    assert create_contents(1, 2, state='Unknown') == {
        'CaseID': 1,
        'ID': 2,
        'CaseJobID': '1_2',
        'State': 'Unknown'
    }
    assert create_contents(1, 2, result='Some result') == {
        'CaseID': 1,
        'ID': 2,
        'CaseJobID': '1_2',
        'Result': 'Some result'
    }


def test_wrap_jobstate_context():
    assert wrap_jobstate_context(JOB_JUST_WITH_CASEJOBID) == {
        'Type': entryTypes['note'],
        'ContentsFormat': formats['json'],
        'Contents': {
            'CaseID': 1,
            'ID': 2,
            'CaseJobID': '1_2',
            'Type': 'JobType',
            'State': 'Unknown',
            'Result': 'Some result'
        },
        'HumanReadable': "",
        'EntryContext': {
            'Accessdata.Job(val.CaseJobID == obj.CaseJobID)': {
                'CaseID': 1,
                'ID': 2,
                'CaseJobID': '1_2',
                'Type': 'JobType',
                'State': 'Unknown',
                'Result': 'Some result'
            }
        }
    }


def mock_demisto(mocker, mock_args, command):
    mocker.patch.object(demisto, 'params', return_value=MOCK_PARAMS)
    mocker.patch.object(demisto, 'args', return_value=mock_args)
    mocker.patch.object(demisto, 'command', return_value=command)
    mocker.patch.object(demisto, 'results')


def test_command_test_module(mocker, requests_mock):
    mock_demisto(mocker, None, 'test-module')
    test_route = 'api/v2/enterpriseapi/statuscheck'
    requests_mock.get(MOCK_URL + test_route, text=MOCK_TEST_MODULE_RESPONSE)
    main()
    results = demisto.results.call_args[0]
    assert results[0] == 'ok'


def test_command_accessdata_get_jobstatus_processlist(mocker, requests_mock):
    mock_demisto(mocker, MOCK_GET_STATUS_ARGS, 'accessdata-get-jobstatus-processlist')
    status_route = 'api/v2/enterpriseapi/core/' + str(MOCK_GET_STATUS_ARGS["caseID"]) + \
        '/getjobstatus/' + str(MOCK_GET_STATUS_ARGS["jobID"])
    requests_mock.get(MOCK_URL + status_route, json=MOCK_GET_JOBSTATUS_PROCESSLIST_RESPONSE)
    main()
    results = demisto.results.call_args[0]
    entry_context = results[0]['EntryContext']['Accessdata.Job(val.CaseJobID == obj.CaseJobID)']
    assert entry_context['CaseID'] == MOCK_GET_STATUS_ARGS["caseID"]
    assert entry_context['ID'] == MOCK_GET_STATUS_ARGS["jobID"]
    assert entry_context['CaseJobID'] == str(MOCK_GET_STATUS_ARGS["caseID"]) + "_" + str(MOCK_GET_STATUS_ARGS["jobID"])
    assert entry_context['State'] == 'Success'
    assert entry_context['Result'] == '\\\\' + MOCK_BASE_URL + '\\D$\\Program Files\\AccessData\\' + \
        'QuinC\\app\\demo\\Demo Case\\c00a2abf-1076-412b-8dea-67305fb8015f\\Jobs\\job_967\\' + \
        'eb849680-2e81-4416-b1b5-5047fd1bc4b1\\1\\snapshot.xml'


def test_command_accessdata_get_jobstatus_memorydump(mocker, requests_mock):
    mock_demisto(mocker, MOCK_GET_STATUS_ARGS, 'accessdata-get-jobstatus-memorydump')
    status_route = 'api/v2/enterpriseapi/core/' + str(MOCK_GET_STATUS_ARGS["caseID"]) + \
        '/getjobstatus/' + str(MOCK_GET_STATUS_ARGS["jobID"])
    requests_mock.get(MOCK_URL + status_route, json=MOCK_GET_JOBSTATUS_MEMORYDUMP_RESPONSE)
    main()
    results = demisto.results.call_args[0]
    entry_context = results[0]['EntryContext']['Accessdata.Job(val.CaseJobID == obj.CaseJobID)']

    assert entry_context['CaseID'] == MOCK_GET_STATUS_ARGS["caseID"]
    assert entry_context['ID'] == MOCK_GET_STATUS_ARGS["jobID"]
    assert entry_context['CaseJobID'] == str(MOCK_GET_STATUS_ARGS["caseID"]) + "_" + str(MOCK_GET_STATUS_ARGS["jobID"])
    assert entry_context['State'] == 'Success'
    assert entry_context['Result'] == '\\\\' + MOCK_BASE_URL + '\\data\\SiteServer\\storage\\' + \
        '8ffafb2e-d077-4165-9aa7-f00cda29cce2\\1\\memdump.mem'


def test_command_accessdata_jobstatus_scan(mocker, requests_mock):
    mock_demisto(mocker, MOCK_GET_STATUS_ARGS, 'accessdata-jobstatus-scan')
    status_route = 'api/v2/enterpriseapi/core/' + str(MOCK_GET_STATUS_ARGS["caseID"]) + \
        '/getjobstatus/' + str(MOCK_GET_STATUS_ARGS["jobID"])
    requests_mock.get(MOCK_URL + status_route, json=MOCK_GET_JOBSTATUS_MEMORYDUMP_RESPONSE)
    main()
    results = demisto.results.call_args[0]
    entry_context = results[0]['EntryContext']['Accessdata.Job(val.CaseJobID == obj.CaseJobID)']

    assert results[0]['HumanReadable'] == 'Current job state: Success'
    assert entry_context['CaseID'] == str(MOCK_GET_STATUS_ARGS["caseID"])
    assert entry_context['ID'] == str(MOCK_GET_STATUS_ARGS["jobID"])
    assert entry_context['CaseJobID'] == str(MOCK_GET_STATUS_ARGS["caseID"]) + "_" + str(MOCK_GET_STATUS_ARGS["jobID"])
    assert entry_context['State'] == 'Success'


def test_command_accessdata_legacyagent_get_processlist(mocker, requests_mock):
    mock_demisto(mocker, MOCK_ADD_JOB_ARGS, 'accessdata-legacyagent-get-processlist')
    add_job_route = 'api/v2/enterpriseapi/agent/' + str(MOCK_ADD_JOB_ARGS['caseid']) + '/volatile'
    requests_mock.post(MOCK_URL + add_job_route, text="333")
    main()
    results = demisto.results.call_args[0]
    entry_context = results[0]['EntryContext']['Accessdata.Job(val.CaseJobID == obj.CaseJobID)']

    assert results[0]['HumanReadable'] == 'JobID: 333'
    assert entry_context['CaseID'] == MOCK_GET_STATUS_ARGS["caseID"]
    assert entry_context['ID'] == 333
    assert entry_context['CaseJobID'] == str(MOCK_GET_STATUS_ARGS["caseID"]) + "_333"
    assert entry_context['Type'] == 'Volatile'
    assert entry_context['State'] == 'Unknown'


def test_command_accessdata_legacyagent_get_memorydump(mocker, requests_mock):
    mock_demisto(mocker, MOCK_ADD_JOB_ARGS, 'accessdata-legacyagent-get-memorydump')
    add_job_route = 'api/v2/enterpriseapi/agent/' + str(MOCK_ADD_JOB_ARGS['caseid']) + '/memoryacquistion'
    requests_mock.post(MOCK_URL + add_job_route, text="333")
    main()
    results = demisto.results.call_args[0]
    entry_context = results[0]['EntryContext']['Accessdata.Job(val.CaseJobID == obj.CaseJobID)']

    assert results[0]['HumanReadable'] == 'JobID: 333'
    assert entry_context['CaseID'] == MOCK_GET_STATUS_ARGS["caseID"]
    assert entry_context['ID'] == 333
    assert entry_context['CaseJobID'] == str(MOCK_GET_STATUS_ARGS["caseID"]) + "_333"
    assert entry_context['Type'] == 'LegacyMemoryDump'
    assert entry_context['State'] == 'Unknown'


def test_command_accessdata_read_casefile(mocker, requests_mock):
    mock_demisto(mocker, MOCK_READ_CASEFILE_ARGS, 'accessdata-read-casefile')
    read_casefile_route = 'api/v2/enterpriseapi/core/readfilecontents'
    requests_mock.post(MOCK_URL + read_casefile_route, text=MOCK_READ_CASEFILE_RESPONSE)
    main()
    results = demisto.results.call_args[0]
    entry_context = results[0]['EntryContext']['Accessdata.File.Contents']
    assert entry_context == MOCK_READ_CASEFILE_RESPONSE