示例#1
0
def test_rules_namespace( oid, key ):
    lc = limacharlie.Manager( oid, key )

    testRuleName = 'test-lc-python-sdk-rule'
    testNamespace = 'managed'

    if testRuleName in lc.rules():
        assert( {} == lc.del_rule( testRuleName ) )

    if testRuleName in lc.rules( namespace = testNamespace ):
        assert( {} == lc.del_rule( testRuleName, namespace = testNamespace ) )

    assert( {} == lc.add_rule( testRuleName, {
        'op' : 'is tagged',
        'tag' : 'test-tag-python-sdk',
    }, [ {
        'action' : 'report',
        'name' : 'test-sdk-detection',
    } ], isReplace = True, namespace = testNamespace ) )

    try:
        rules = lc.rules( namespace = testNamespace )
        assert( testRuleName in rules )

        rules = lc.rules( namespace = None )
        assert( testRuleName not in rules )
    finally:
        assert( {} == lc.del_rule( testRuleName, namespace = testNamespace ) )

    assert( testRuleName not in lc.rules( namespace = testNamespace ) )
示例#2
0
def test_spout(oid, key):
    lc = limacharlie.Manager(oid,
                             key,
                             inv_id='test-lc-python-sdk-inv',
                             is_interactive=True)

    try:
        # First we need to make sure we have a sensor to test against.
        sensors = lc.sensors()
        assert (0 != len(sensors))

        # We will pick the first sensor in the list that is online.
        targetSensor = None
        for sensor in sensors:
            if sensor.isOnline():
                targetSensor = sensor
                print("Found sensor %s online, using it for test." %
                      (sensor, ))
                break

        assert (targetSensor is not None)

        resp = targetSensor.simpleRequest('os_version')

        assert (resp is not None)
        assert (resp.get('event', None) is not None)
    finally:
        try:
            lc.shutdown()
        except:
            # In Python3 the underlying http client has issues
            # with this call being reentrant. It should not be
            # an issue for us here.
            pass
示例#3
0
def test_batch_object_information(oid, key):
    lc = limacharlie.Manager(oid, key)

    objects = lc.getBatchObjectInformation(
        {'domain': ['www.google.com', 'www.apple.com']})

    assert (isinstance(objects, dict))
示例#4
0
def main():
    parser = argparse.ArgumentParser( prog = 'python -m lcservice.simulator' )
    parser.add_argument( 'url',
                         type = str,
                         help = 'the URL of the service to call.' )
    parser.add_argument( 'action',
                         type = str,
                         help = 'action to run, one of supported callbacks (see doc).' )
    parser.add_argument( '-s', '--secret',
                         type = str,
                         required = False,
                         dest = 'secret',
                         default = '',
                         help = 'optionally specify the shared secret, you can omit if the service was started with secret disabled.' )
    parser.add_argument( '-d', '--data',
                         type = eval,
                         default = {},
                         dest = 'data',
                         help = 'data to include in the request, this string gets evaluated as python code' )

    args = parser.parse_args()

    if args.url.startswith( 'https://' ) and args.url.startswith( 'http://' ):
        print( "url must start with http or https." )
        sys.exit( 1 )

    lc = limacharlie.Manager()
    lc.whoAmI()
    oid = lc._oid
    jwt = lc._jwt
    secret = args.secret

    print( json.dumps( postData( args.url, secret, oid, jwt, args.action, data = args.data ), indent = 2 ) )
def test_api_keys(oid, key):
    lc = limacharlie.Manager(oid, key)

    keyName = 'automated-test-key-name'
    perms = ['org.get', 'sensor.task', 'sensor.get']
    perms.sort()

    keys = lc.getApiKeys()
    assert (0 != len(keys))

    response = lc.addApiKey(keyName, perms)
    assert (response)
    assert (response['success'])
    assert (response['api_key'])
    assert (response['key_hash'])

    keys = lc.getApiKeys()
    assert (response['key_hash'] in keys)
    tmpKey = keys[response['key_hash']]
    assert (keyName == tmpKey['name'])
    tmpKey['priv'].sort()
    assert (tmpKey['priv'] == perms)

    lc.removeApiKey(response['key_hash'])
    keys = lc.getApiKeys()
    assert (response['key_hash'] not in keys)
def test_credentials(oid, key):
    lc = limacharlie.Manager(oid, key)

    assert (lc.testAuth([
        'org.get',
        'sensor.get',
        'sensor.list',
        'replicant.get',
        'replicant.task',
    ]))
示例#7
0
def test_credentials(oid, key):
    lc = limacharlie.Manager(oid, key)

    assert (lc.testAuth([
        'org.get',
        'sensor.list',
        'sensor.get',
        'output.list',
        'output.set',
        'output.del',
    ]))
示例#8
0
def test_detections(oid, key):
    lc = limacharlie.Manager(oid, key)

    detections = lc.getHistoricDetections(int(time.time()) - (60 * 60 * 24),
                                          int(time.time()),
                                          limit=10)

    # The return is a generator so we
    # will unravel it.
    detections = list(detections)

    assert (isinstance(detections, list))
示例#9
0
def test_credentials(oid, key):
    lc = limacharlie.Manager(oid, key)

    assert (lc.testAuth([
        'org.get',
        'sensor.get',
        'sensor.list',
        'insight.evt.get',
        'insight.det.get',
        'insight.list',
        'insight.stat',
    ]))
示例#10
0
def test_ingestion_keys( oid, key ):
    lc = limacharlie.Manager( oid, key )

    testIngestionKeyName = 'test-python-sdk-key'

    assert( {} == lc.setIngestionKey( testIngestionKeyName ) )

    try:
        assert( testIngestionKeyName in lc.getIngestionKeys() )
    finally:
        assert( {} == lc.delIngestionKey( testIngestionKeyName ) )

    assert( testIngestionKeyName not in lc.getIngestionKeys() )
def test_isolation(oid, key):
    lc = limacharlie.Manager(oid, key)

    for sensor in lc.sensors():
        if sensor.isChrome():
            continue
        if not (sensor.isMac() or sensor.isWindows()):
            continue
        if not sensor.isOnline():
            continue
        assert (not sensor.isIsolatedFromNetwork())
        sensor.isolateNetwork()
        assert (sensor.isIsolatedFromNetwork())
        sensor.rejoinNetwork()
        assert (not sensor.isIsolatedFromNetwork())
        break
示例#12
0
def test_fps( oid, key ):
    lc = limacharlie.Manager( oid, key )

    testRuleName = 'test-lc-python-sdk-fp'

    assert( {} == lc.add_fp( testRuleName, {
        'op' : 'is',
        'path' : 'cat',
        'value' : 'test-sdk-detection'
    }, isReplace = True ) )

    try:
        rules = lc.fps()
        assert( testRuleName in rules )
    finally:
        assert( {} == lc.del_fp( testRuleName ) )

    assert( testRuleName not in lc.fps() )
def test_rules(oid, key):
    lc = limacharlie.Manager(oid, key)

    testRuleName = 'test-lc-python-sdk-rule'

    assert ({} == lc.add_rule(testRuleName, {
        'op': 'is tagged',
        'tag': 'test-tag-python-sdk',
        'event': 'NEW_PROCESS',
    }, [{
        'action': 'report',
        'name': 'test-sdk-detection',
    }],
                              isReplace=True))

    try:
        rules = lc.rules()
        assert (testRuleName in rules)
    finally:
        assert ({} == lc.del_rule(testRuleName))

    assert (testRuleName not in lc.rules())
示例#14
0
def test_outputs( oid, key ):
    lc = limacharlie.Manager( oid, key )

    testOutputName = 'test-lc-python-sdk-out'
    testDest = '1.1.1.1:22'

    assert( lc.add_output(
        testOutputName,
        'syslog',
        'event',
        dest_host = testDest,
        is_tls = True,
        is_strict_tls = True,
        is_no_header = True,
    ) )

    try:
        outputs = lc.outputs()
        assert( outputs.get( testOutputName, {} ).get( 'dest_host', None ) == testDest )
    finally:
        assert( {} == lc.del_output( testOutputName ) )

    assert( testOutputName not in lc.outputs() )
示例#15
0
def test_credentials( oid, key ):
    lc = limacharlie.Manager( oid, key )

    assert( lc.testAuth( [
        'org.get',
        'sensor.get',
        'sensor.list',
        'dr.list',
        'dr.set',
        'dr.del',
        'dr.list.managed',
        'dr.set.managed',
        'dr.del.managed',
        'ikey.list',
        'ikey.set',
        'ikey.del',
        'output.list',
        'output.set',
        'output.del',
        'org.conf.get',
        'ingestkey.ctrl',
        'audit.get',
        'fp.ctrl',
    ] ) )
示例#16
0
def test_hosts( oid, key ):
    lc = limacharlie.Manager( oid, key )

    hosts = lc.hosts( 'a' )
    assert( isinstance( hosts, list ) )
示例#17
0
def test_sensors( oid, key ):
    lc = limacharlie.Manager( oid, key )

    sensors = lc.sensors()
    assert( isinstance( sensors, list ) )
示例#18
0
def test_whoami( oid, key ):
    lc = limacharlie.Manager( oid, key )

    who = lc.whoAmI()
    assert( 0 != len( who.get( 'perms', [] ) ) )
    assert( 0 != len( who.get( 'orgs', [] ) ) )
示例#19
0
def test_object_informaton(oid, key):
    lc = limacharlie.Manager(oid, key)

    objects = lc.getObjectInformation('domain', 'www.google.com', 'summary')

    assert (isinstance(objects, dict))
示例#20
0
def test_org_config( oid, key ):
    lc = limacharlie.Manager( oid, key )

    val = lc.getOrgConfig( 'vt' )

    assert( val )
示例#21
0
def test_org_urls( oid, key ):
    lc = limacharlie.Manager( oid, key )

    urls = lc.getOrgURLs()

    assert( isinstance( urls, dict ) )
示例#22
0
    def _processEvent(self, data):
        version = data.get('version', None)
        jwt = data.get('jwt', None)
        oid = data.get('oid', None)
        msgId = data.get('mid', None)
        deadline = data.get('deadline', None)
        eType = data.get('etype', None)
        data = data.get('data', {})

        if version is not None and version > PROTOCOL_VERSION:
            return self.response(isSuccess=False,
                                 isDoRetry=False,
                                 data={
                                     'error':
                                     'unsupported version (> %s)' %
                                     (PROTOCOL_VERSION, )
                                 })

        if self._isTraceComms:
            dataNoJwt = data.copy()
            dataNoJwt.pop('jwt', None)
            self.log("REQ (%s): %s => %s" %
                     (msgId, eType, json.dumps(dataNoJwt)))

        request = Request(eType, msgId, data)

        # If the eType is 'request' and the service specifies
        # some request parameter definitions we'll do some
        # validation on the parameters.
        if 'request' == eType and 0 != len(self._supportedRequestParameters):
            for k, v in request.data.items():
                if v is None:
                    continue
                definition = self._supportedRequestParameters.get(k, None)
                if definition is None:
                    continue
                validationResult = self._validateRequestParameter(
                    definition, v)
                if validationResult is None:
                    continue
                return self.response(isSuccess=False,
                                     error="invalid parameter %s: %s" %
                                     (k, validationResult))
            for k, v in self._supportedRequestParameters.items():
                if not v.get('is_required', False):
                    continue
                if request.data.get(k, None) is None:
                    return self.response(isSuccess=False,
                                         error="missing parameter %s" % (k, ))

        handler = self._handlers.get(eType, None)
        if handler is None:
            return self.responseNotImplemented()

        lcApi = None
        if oid is not None and jwt is not None:
            invId = str(uuid.uuid4())
            # We support a special function to wrap the LC API
            # if needed to provide some added magic.
            if hasattr(self, 'wrapSdk'):
                lcApi = getattr(self, 'wrapSdk')(oid=oid,
                                                 jwt=jwt,
                                                 inv_id=invId)
            else:
                lcApi = limacharlie.Manager(oid=oid, jwt=jwt, inv_id=invId)

        try:
            with self._lock:
                self._nCallsInProgress += 1
            resp = handler(lcApi, oid, request)
            if resp is True:
                # Shotcut for simple success.
                resp = self.response(isSuccess=True)
            elif resp is False:
                # Shortcut for simple failure no retry.
                resp = self.response(isSuccess=False, isDoRetry=False)
            elif resp is None:
                # Shortcut for simple failure with retry.
                resp = self.response(isSuccess=False, isDoRetry=True)
            elif not isinstance(resp, dict):
                self.logCritical(
                    'no valid response specified in %s, assuming success' %
                    (eType, ))
                resp = self.response(isSuccess=True, isDoRetry=False, data={})

            if self._isTraceComms:
                self.log("REP (%s): %s" % (msgId, json.dumps(resp)))

            return resp
        except:
            exc = traceback.format_exc()
            self.logCritical(exc)
            return self.response(isSuccess=False,
                                 isDoRetry=True,
                                 data={'exception': exc})
        finally:
            with self._lock:
                self._nCallsInProgress -= 1
            now = time.time()
            if deadline is not None and now > deadline:
                self.logCritical('event %s over deadline by %ss' %
                                 (eType, now - deadline))
示例#23
0
def test_host_count_platform(oid, key):
    lc = limacharlie.Manager(oid, key)

    counts = lc.getInsightHostCountPerPlatform()

    assert (isinstance(counts, dict))
def test_replicants_available(oid, key):
    lc = limacharlie.Manager(oid, key)

    replicants = lc.getAvailableReplicants()

    assert (isinstance(replicants, list))
import json
import uuid
import getpass

if __name__ == "__main__":

    def debugPrint(msg):
        print msg

    # This example uses interactive credentials, but see the README for alternative
    # ways of getting credentials.

    print("We are starting in interactive mode.")
    man = limacharlie.Manager(
        oid=raw_input('Enter OID: '),
        secret_api_key=getpass.getpass(prompt='Enter secret API key: '),
        print_debug_fn=None,
        inv_id=str(uuid.uuid4()),
        is_interactive=True)

    # Starting the Manager with is_interactive = True means that Sensors accessed
    # through this Manager will support the .request() API which behaves similarly
    # to .task(), but instead of being unidirectional, it returns a FutureResponses
    # object which can be used to get the response to the task.

    print("Getting a list of sensors.")
    sensors = man.sensors()

    print("Got %s sensors." % len(sensors))

    # This is a very naive way to proceed. We could issue all tasks, accumulate the
    # futures and then wait on all of them, that would be MUCH faster.
示例#26
0
import limacharlie
from limacharlie.utils import parallelExec
import argparse
from datetime import datetime

if __name__ == "__main__":
    parser = argparse.ArgumentParser( description = 'Delete duplicate sensors.' )
    parser.add_argument( '--dry-run', action = 'store_true', default = False, dest = 'isDryRun' )

    args = parser.parse_args()

    if args.isDryRun:
        print( "---=== DRY RUN ===---" )

    # Instantiate the SDK
    lc = limacharlie.Manager()

    # We will accumulate sensors by hostname.
    sensorsByHostname = {}
    allSensors = []

    # Get all the sensor info. Do this in parallel since it
    # could take a while on a large organization.
    def _getSensorInfo( s ):
        sensorInfo = s.getInfo()
        sensorsByHostname.setdefault( sensorInfo[ 'hostname' ], [] ).append( sensorInfo )
        allSensors.append( sensorInfo )

    print( "Getting all sensor info..." )

    parallelExec( _getSensorInfo, lc.sensors(), maxConcurrent = 5 )
def test_artifact_lifecycle(oid, key):
    lc = limacharlie.Manager(oid, key)

    assert (lc.testAuth([
        'org.get',
        'insight.evt.get',
        'insight.list',
        'ingestkey.ctrl',
    ]))

    # Create a new ingestion key.
    keyName = "test_ingestion_%s" % (uuid.uuid4(), )

    keyVal = lc.setIngestionKey(keyName)
    assert (keyVal.get('key', False))
    keyVal = keyVal['key']

    source = "test-%s" % (uuid.uuid4(), )

    try:
        artifactService = limacharlie.Artifacts(lc, keyVal)

        # Create 3 test artifacts locally.
        assert (0 == os.system("echo 'test file 1' > test1.txt"))
        assert (0 == os.system("echo 'test file 2' > test2.txt"))
        assert (0 == os.system("echo 'test file 3' > test3.txt"))

        # Upload 3 test artifacts.
        uploadTime = int(time.time())

        for filePath in ('test1.txt', 'test2.txt', 'test3.txt'):
            resp = artifactService.upload(filePath,
                                          source=source,
                                          hint='txt',
                                          originalPath=filePath,
                                          nDaysRetention=2)
            assert (resp)

        # Give it a few seconds to make sure the new artifacts
        # have made it through ingestion.
        time.sleep(10)

        # Iterate over them to make sure we see them.
        nArtifacts = 0
        for artifactInfo, artifactTmpFile in artifactService.listArtifacts(
                type='txt',
                source=source,
                after=uploadTime - 60,
                before=int(time.time()) + 60,
                withData=True):
            try:
                nArtifacts += 1
                assert (artifactInfo)
                artifactData = open(artifactTmpFile, 'rb').read().decode()
                assert (artifactData.startswith('test file '))
            finally:
                os.remove(artifactTmpFile)

        assert (3 == nArtifacts)

    finally:
        lc.delIngestionKey(keyName)
示例#28
0
        '--category',
        type=str,
        dest='cat',
        default=None,
        help='spout should only receive detections from this category.')
    parser.add_argument(
        '-s',
        '--sid',
        type=lambda x: str(uuid.UUID(x)),
        dest='sid',
        default=None,
        help='spout should only receive detections or events from this sensor.'
    )
    args = parser.parse_args()
    secretApiKey = getpass.getpass(prompt='Enter secret API key: ')

    _printToStderr("Registering...")
    man = limacharlie.Manager(oid=args.oid, secret_api_key=secretApiKey)
    sp = limacharlie.Spout(man,
                           args.data_type,
                           inv_id=args.inv_id,
                           tag=args.tag,
                           cat=args.cat,
                           sid=args.sid)

    _printToStderr("Starting to listen...")
    while True:
        data = sp.queue.get()
        print(json.dumps(data, indent=2))

    _printToStderr("Exiting.")
示例#29
0
import signal
import sys
import getpass

if __name__ == "__main__":

    def signal_handler():
        global sp
        print('You pressed Ctrl+C!')
        sp.shutdown()
        sys.exit(0)

    gevent.signal(signal.SIGINT, signal_handler)

    def debugPrint(msg):
        print msg

    # This example uses interactive credentials, but see the README for alternative
    # ways of getting credentials.

    man = limacharlie.Manager(
        oid=raw_input('Enter OID: '),
        secret_api_key=getpass.getpass(prompt='Enter secret API key: '),
        print_debug_fn=debugPrint)

    sp = limacharlie.Spout(man, 'event')

    while True:
        data = sp.queue.get()
        print(json.dumps(data, indent=2) + "\n\n")
示例#30
0
def test_insight_status(oid, key):
    lc = limacharlie.Manager(oid, key)

    assert (lc.isInsightEnabled())