Esempio n. 1
0
    def test_send_analysis_by_file_with_zip_password_adds_zip_extension(self):
        # Arrange
        with responses.RequestsMock() as mock:
            mock.add('POST',
                     url=self.full_url + '/analyze',
                     status=201,
                     json={'result_url': 'a/sd/asd'})
            mock.add('GET',
                     url=self.full_url + '/analyses/asd',
                     status=200,
                     json={
                         'result': 'report',
                         'status': 'succeeded'
                     })
            analysis = FileAnalysis(file_path='a', zip_password='******')

            with patch(self.patch_prop, mock_open(read_data='data')):
                # Act
                analysis.send(wait=True)

            # Assert
            self.assertEqual(analysis.status, consts.AnalysisStatusCode.FINISH)
            self.assertEqual(analysis.result(), 'report')
            request_body = mock.calls[0].request.body.decode()
            self.assertTrue(
                'Content-Disposition: form-data; name="zip_password"\r\n\r\nasd'
                in request_body)
            self.assertTrue(
                'Content-Disposition: form-data; name="file"; filename="a.zip"'
                in request_body)
Esempio n. 2
0
    def test_send_analysis_by_file_and_get_dynamic_ttps(self):
        # Arrange
        with responses.RequestsMock() as mock:
            mock.add('POST',
                     url=self.full_url + '/analyze',
                     status=201,
                     json={'result_url': 'a/sd/asd'})
            mock.add('GET',
                     url=self.full_url + '/analyses/asd',
                     status=200,
                     json={
                         'result': 'report',
                         'status': 'succeeded'
                     })
            mock.add('GET',
                     url=self.full_url + '/analyses/asd/dynamic-ttps',
                     status=200,
                     json={'result': 'ttps_report'})
            analysis = FileAnalysis(file_path='a')
            with patch(self.patch_prop, mock_open(read_data='data')):
                # Act
                analysis.send(wait=True)
                ttps = analysis.dynamic_ttps

        # Assert
        self.assertEqual(analysis.status, consts.AnalysisStatusCode.FINISH)
        self.assertEqual(ttps, 'ttps_report')
Esempio n. 3
0
    def test_send_analysis_by_file_with_disable_unpacking(self):
        # Arrange
        with responses.RequestsMock() as mock:
            mock.add('POST',
                     url=self.full_url + '/analyze',
                     status=201,
                     json={'result_url': 'a/sd/asd'})
            mock.add('GET',
                     url=self.full_url + '/analyses/asd',
                     status=200,
                     json={
                         'result': 'report',
                         'status': 'succeeded'
                     })
            analysis = FileAnalysis(file_path='a',
                                    disable_dynamic_unpacking=True,
                                    disable_static_unpacking=True)
            with patch(self.patch_prop, mock_open(read_data='data')):
                # Act
                analysis.send(wait=True)

            # Assert
            self.assertEqual(analysis.status, consts.AnalysisStatusCode.FINISH)
            self.assertEqual(analysis.result(), 'report')
            request_body = mock.calls[0].request.body.decode()
            self.assertTrue(
                'Content-Disposition: form-data; name="disable_static_extraction"\r\n\r\nTrue'
                in request_body)
            self.assertTrue(
                'Content-Disposition: form-data; name="disable_dynamic_execution"\r\n\r\nTrue'
                in request_body)
Esempio n. 4
0
    def test_send_analysis_by_file_sends_analysis_and_waits_specific_time_until_compilation(
            self):
        # Arrange
        with responses.RequestsMock() as mock:
            mock.add('POST',
                     url=self.full_url + '/analyze',
                     status=201,
                     json={'result_url': 'a/sd/asd'})
            mock.add('GET',
                     url=self.full_url + '/analyses/asd',
                     status=200,
                     json={
                         'result': 'report',
                         'status': 'succeeded'
                     })
            analysis = FileAnalysis(file_path='a')
            wait = 1

            with patch(self.patch_prop, mock_open(read_data='data')):
                # Act
                start = datetime.datetime.utcnow()
                analysis.send(wait=wait)
                duration = (datetime.datetime.utcnow() - start).total_seconds()

        # Assert
        self.assertEqual(analysis.status, consts.AnalysisStatusCode.FINISH)
        self.assertGreater(duration, wait)
Esempio n. 5
0
    def test_send_analysis_by_sha256_with_expired_jwt_token_gets_new_token(
            self):
        # Arrange
        analysis = FileAnalysis(file_hash='a' * 64)

        # FileAnalysis attempt will initiate an access-token refresh by getting UNAUTHORIZED 401
        with responses.RequestsMock() as mock:

            def request_callback(request):
                if request.headers[
                        'Authorization'] == 'Bearer newer-access-token':
                    return HTTPStatus.CREATED, {}, json.dumps(
                        {'result_url': 'https://analyze.intezer.com/test-url'})
                if request.headers['Authorization'] == 'Bearer access-token':
                    return HTTPStatus.UNAUTHORIZED, {}, json.dumps({})
                # Fail test completley is unexpected access token received
                return HTTPStatus.SERVICE_UNAVAILABLE, {}, json.dumps({})

            mock.add_callback('POST',
                              url=self.full_url + '/analyze-by-hash',
                              callback=request_callback)
            mock.add('POST',
                     url=self.full_url + '/get-access-token',
                     status=HTTPStatus.OK,
                     json={'result': 'newer-access-token'})

            # Act & Assert
            analysis.send()
            self.assertEqual(
                3, len(mock.calls
                       ))  # analyze -> refresh access_token -> analyze retry
Esempio n. 6
0
    def test_send_analysis_by_file_sent_analysis_with_pulling_and_get_status_finish(
            self):
        # Arrange
        with responses.RequestsMock() as mock:
            mock.add('POST',
                     url=self.full_url + '/analyze',
                     status=201,
                     json={'result_url': 'a/sd/asd'})
            mock.add('GET', url=self.full_url + '/analyses/asd', status=202)
            mock.add('GET', url=self.full_url + '/analyses/asd', status=202)
            mock.add('GET',
                     url=self.full_url + '/analyses/asd',
                     status=200,
                     json={
                         'result': 'report',
                         'status': 'succeeded'
                     })
            analysis = FileAnalysis(file_path='a')

            with patch(self.patch_prop, mock_open(read_data='data')):
                # Act
                analysis.send()
                analysis.check_status()
                analysis.check_status()
                analysis.check_status()

        # Assert
        self.assertEqual(analysis.status, consts.AnalysisStatusCode.FINISH)
Esempio n. 7
0
    def test_send_analysis_and_get_root_analyses(self):
        # Arrange
        with responses.RequestsMock() as mock:
            mock.add('POST',
                     url=self.full_url + '/analyze-by-hash',
                     status=201,
                     json={'result_url': 'a/sd/asd'})
            mock.add('GET',
                     url=self.full_url + '/analyses/asd/sub-analyses',
                     status=200,
                     json={
                         'sub_analyses': [{
                             'source': 'root',
                             'sub_analysis_id': 'ab',
                             'sha256': 'axaxaxax'
                         }, {
                             'source': 'static_extraction',
                             'sub_analysis_id': 'ac',
                             'sha256': 'ba'
                         }]
                     })

            analysis = FileAnalysis(file_hash='a' * 64)

            # Act
            analysis.send()

            analysis.get_root_analysis()

        # Assert
        self.assertEqual(analysis.status, consts.AnalysisStatusCode.CREATED)
        self.assertEqual(len(analysis.get_sub_analyses()), 1)
        self.assertIsNotNone(analysis.get_root_analysis())
Esempio n. 8
0
def analyze_by_hash_command(intezer_api: IntezerApi,
                            args: Dict[str, str]) -> CommandResults:
    file_hash = args.get('file_hash')

    if not file_hash:
        raise ValueError('Missing file hash')

    analysis = FileAnalysis(file_hash=file_hash, api=intezer_api)

    try:
        analysis.send(requester=REQUESTER)
        analysis_id = analysis.analysis_id

        context_json = {
            'ID': analysis.analysis_id,
            'Status': 'Created',
            'type': 'File'
        }

        return CommandResults(
            outputs_prefix='Intezer.Analysis',
            outputs_key_field='ID',
            outputs=context_json,
            readable_output='Analysis created successfully: {}'.format(
                analysis_id))
    except HashDoesNotExistError:
        return _get_missing_file_result(file_hash)
    except AnalysisIsAlreadyRunning as error:
        return _get_analysis_running_result(response=error.response)
Esempio n. 9
0
def analyze_threat(threat_id: str, threat: dict = None):
    _logger.info(f'incoming threat: {threat_id}')
    try:
        if not threat:
            threat = get_threat(threat_id)
        if not filter_threat(threat):
            _logger.info(f'threat {threat_id} is been filtered')
            return

        threat_info = threat['threatInfo']
        file_hash = threat_info.get('sha256') or threat_info.get('sha1') or threat_info.get('md5')
        analysis = None
        if file_hash:
            _logger.debug(f'trying to analyze by hash {file_hash}')
            try:
                analysis = FileAnalysis(file_hash=file_hash)
                analysis.send()
            except errors.HashDoesNotExistError:
                _logger.debug(f'hash {file_hash} not found on server, fetching the file from endpoint')
                analysis = None

        if not analysis:
            analysis = analyze_by_file(threat_id)
            analysis.send(requester='s1')

        _logger.debug('waiting for analysis completion')
        analysis.wait_for_completion()
        _logger.debug('analysis completed')

        send_note(threat_id, analysis)
    except Exception as ex:
        _logger.exception(f'failed to process threat {threat_id}')
        send_failure_note(str(ex), threat_id)
Esempio n. 10
0
 def test_send_analysis_by_sha256_that_dont_exist_raise_error(self):
     # Arrange
     with responses.RequestsMock() as mock:
         mock.add('POST',
                  url=self.full_url + '/analyze-by-hash',
                  status=404)
         analysis = FileAnalysis(file_hash='a' * 64)
         # Act + Assert
         with self.assertRaises(errors.HashDoesNotExistError):
             analysis.send()
Esempio n. 11
0
 def test_send_analysis_that_running_on_server_raise_error(self):
     # Arrange
     with responses.RequestsMock() as mock:
         mock.add('POST',
                  url=self.full_url + '/analyze-by-hash',
                  status=409,
                  json={'result_url': 'a/sd/asd'})
         analysis = FileAnalysis(file_hash='a' * 64)
         # Act + Assert
         with self.assertRaises(errors.AnalysisIsAlreadyRunningError):
             analysis.send()
Esempio n. 12
0
    def test_send_analysis_by_sha256_sent_analysis_and_sets_status(self):
        # Arrange
        with responses.RequestsMock() as mock:
            mock.add('POST',
                     url=self.full_url + '/analyze-by-hash',
                     status=201,
                     json={'result_url': 'a/sd/asd'})
            analysis = FileAnalysis(file_hash='a' * 64)

            # Act
            analysis.send()

        # Assert
        self.assertEqual(analysis.status, consts.AnalysisStatusCode.CREATED)
Esempio n. 13
0
    def test_send_analysis_by_file_with_file_stream_sent_analysis(self):
        # Arrange
        with responses.RequestsMock() as mock:
            mock.add('POST',
                     url=self.full_url + '/analyze',
                     status=201,
                     json={'result_url': 'a/sd/asd'})
            analysis = FileAnalysis(file_stream=__file__)

            # Act
            analysis.send()

        # Assert
        self.assertEqual(analysis.status, consts.AnalysisStatusCode.CREATED)
Esempio n. 14
0
    def test_send_analysis_by_file_sent_analysis_and_sets_status(self):
        # Arrange
        with responses.RequestsMock() as mock:
            mock.add('POST',
                     url=self.full_url + '/analyze',
                     status=201,
                     json={'result_url': 'a/sd/asd'})
            analysis = FileAnalysis(file_path='a')

            with patch(self.patch_prop, mock_open(read_data='data')):
                # Act
                analysis.send()

        # Assert
        self.assertEqual(analysis.status, consts.AnalysisStatusCode.CREATED)
Esempio n. 15
0
    def test_send_analysis_by_sha256_with_expired_jwt_token_doesnt_loop_indefinitley(
            self):
        # Arrange
        with responses.RequestsMock() as mock:
            mock.add('POST',
                     url=self.full_url + '/analyze-by-hash',
                     status=HTTPStatus.UNAUTHORIZED)
            mock.add('POST',
                     url=self.full_url + '/get-access-token',
                     status=HTTPStatus.OK,
                     json={'result': 'newer-access-token'})

            analysis = FileAnalysis(file_hash='a' * 64)

            # Act & Assert
            with self.assertRaises(errors.IntezerError):
                analysis.send()

            # analyze -> get_access token -> analyze -> 401Exception
            self.assertEqual(3, len(mock.calls))
Esempio n. 16
0
 def test_send_analysis_by_file_and_get_dynamic_ttps_handle_no_ttps(self):
     # Arrange
     with responses.RequestsMock() as mock:
         mock.add('POST',
                  url=self.full_url + '/analyze',
                  status=201,
                  json={'result_url': 'a/sd/asd'})
         mock.add('GET',
                  url=self.full_url + '/analyses/asd',
                  status=200,
                  json={
                      'result': 'report',
                      'status': 'succeeded'
                  })
         mock.add('GET',
                  url=self.full_url + '/analyses/asd/dynamic-ttps',
                  status=404)
         analysis = FileAnalysis(file_path='a')
         with patch(self.patch_prop, mock_open(read_data='data')):
             # Act
             analysis.send(wait=True)
             self.assertIsNone(analysis.dynamic_ttps)
Esempio n. 17
0
def analyze_by_uploaded_file_command(intezer_api: IntezerApi,
                                     args: dict) -> CommandResults:
    file_id = args.get('file_entry_id')
    file_data = demisto.getFilePath(file_id)

    try:
        analysis = FileAnalysis(file_path=file_data['path'], api=intezer_api)
        analysis.send(requester=REQUESTER)

        context_json = {
            'ID': analysis.analysis_id,
            'Status': 'Created',
            'type': 'File'
        }

        return CommandResults(
            outputs_prefix='Intezer.Analysis',
            outputs_key_field='ID',
            outputs=context_json,
            readable_output='Analysis created successfully: {}'.format(
                analysis.analysis_id))
    except AnalysisIsAlreadyRunning as error:
        return _get_analysis_running_result(response=error.response)
Esempio n. 18
0
    def test_analysis_check_status_after_analysis_finish_raise_error(self):
        # Arrange
        with responses.RequestsMock() as mock:
            mock.add('POST',
                     url=self.full_url + '/analyze',
                     status=201,
                     json={'result_url': 'a/sd/asd'})
            mock.add('GET',
                     url=self.full_url + '/analyses/asd',
                     status=200,
                     json={
                         'result': 'report',
                         'status': 'succeeded'
                     })
            analysis = FileAnalysis(file_path='a')

            with patch(self.patch_prop, mock_open(read_data='data')):
                # Act
                analysis.send(wait=True)

            # Assert
            with self.assertRaises(errors.IntezerError):
                analysis.check_status()
Esempio n. 19
0
    def test_send_analysis_by_file_sends_analysis_with_waits_to_compilation_when_requested(
            self):
        # Arrange
        with responses.RequestsMock() as mock:
            mock.add('POST',
                     url=self.full_url + '/analyze',
                     status=201,
                     json={'result_url': 'a/sd/asd'})
            mock.add('GET',
                     url=self.full_url + '/analyses/asd',
                     status=200,
                     json={
                         'result': 'report',
                         'status': 'succeeded'
                     })
            analysis = FileAnalysis(file_path='a')

            with patch(self.patch_prop, mock_open(read_data='data')):
                # Act
                analysis.send(wait=True)

        # Assert
        self.assertEqual(analysis.status, consts.AnalysisStatusCode.FINISH)
Esempio n. 20
0
def send_analysis(analysis: FileAnalysis):
    analysis.send(wait=True)
    return analysis.result()
def analysis_by_hash_without_wait(file_hash: str):
    api.set_global_api('<api_key>')
    analysis = FileAnalysis(file_hash=file_hash)
    analysis.send()
    analysis.wait_for_completion()
    pprint(analysis.result())
def analysis_by_hash_with_wait(file_hash: str):
    api.set_global_api('<api_key>')
    analysis = FileAnalysis(file_hash=file_hash)
    analysis.send(wait=True)
    pprint(analysis.result())
def send_file_without_wait(file_path):
    api.set_global_api('<api_key>')
    analysis = FileAnalysis(file_path=file_path)
    analysis.send()
    analysis.wait_for_completion()
    pprint(analysis.result())
def send_file_with_wait(file_path):
    api.set_global_api('<api_key>')
    analysis = FileAnalysis(file_path=file_path)
    analysis.send(wait=True)
    pprint(analysis.result())
def analysis_by_hash_with_wait_timeout(file_hash: str):
    api.set_global_api('<api_key>')
    analysis = FileAnalysis(file_hash=file_hash)
    analysis.send(wait=True, wait_timeout=datetime.timedelta(minutes=1))
    pprint(analysis.result())