BitcoinAbuse Deprecated

Deprecated. No available replacement.

Data Enrichment & Threat Intelligence · BitcoinAbuse Feed (Deprecated) · Feed

Details

IDBitcoinAbuse
ProviderBitcoinAbuse
CategoryData Enrichment & Threat Intelligence
From Version5.5.0
Docker Imagedemisto/python3:3.10.12.63474
Supported ModulesAgentix XSIAM

README

BitcoinAbuse.com is a public database of bitcoin addresses used by hackers and criminals.
Supported Cortex XSOAR versions: 5.5.0 and later.

Get Your API Key

In order to use Bitcoin Abuse service, you need to get your API key.
The API key is free and can be achieved by doing the following:

  1. Navigate to https://www.bitcoinabuse.com and click on “Register” on top right corner of your screen.
  2. Fill in your details (Name, Email, Password, etc…)
  3. After your account have been set, go to Settings, and click on “API” section.
  4. Give your API token a name, and click on “Create”, a screen containing your generated API key
    will appear.

Configure BitcoinAbuse in Cortex

Parameter Description Required
feed Fetch indicators False
api_key API Key True
insecure Trust any certificate (not secure) False
proxy Use system proxy settings False
initial_fetch_interval First Fetch Time True
feedReputation Indicator Reputation False
feedReliability Source Reliability True
feedExpirationPolicy   False
tlp_color Traffic Light Protocol Color False
feedFetchInterval Feed Fetch Interval False
feedExpirationInterval   False
feedBypassExclusionList Bypass exclusion list False
feedTags Tags False

Fetching indicators

Initial Fetch

When configuring an integration instance, you will be required to enter the first fetch parameter which will set the timeframe to pull Indicators in the first fetch, Two options are available:

  • 30 Days - Indicators recorded in the last 30 days (updates every Sunday between 2am-3am UTC.)
  • Forever - All recorded indicators (updates every 15th of the month between 2am-3am UTC.)

Note:

  • Whenever Forever is selected, in order to bring as much data as possible in the first fetch, we merge the Forever CSV together the 30 Days CSV file to avoid missing as much data as possible.
  • Restrictions will be that any data reported between Sunday (after 30 Days file update) to the day of the first fetch
    will not be fetched

Each fetch after the initial fetch

Each fetch after the initial fetch will return indicators reported on the previous day (updates once a day between 2am-3am UTC). Therefore, fetching more than once a day will not have any effect.

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.

bitcoinabuse-report-address


Reports an abuser to Bitcoin Abuse service. ‘abuse_type_other’ field is required when ‘abuse_type’ is other

Base Command

bitcoinabuse-report-address

Input

Argument Name Description Required
address Address of the abuser. Required
abuser Information about the abuser. Required
description Description of the abuse. Optional
abuse_type Type of abuse. The “abuse_type_other” field is required when the value of the “abuse_type” field is “other”. Possible values are “ransomware”, “darknet market”, “bitcoin tumber”, “blackmail scam”, “sextortion”, and “other”. Possible values are: ransomware, darknet market, bitcoin tumbler, blackmail scam, sextortion, other. Required
abuse_type_other Description of the abuse type. The “abuse_type_other” field is required when the value of the “abuse_type” field is “other”. Optional

Context Output

There is no context output for this command.

Command Example

!bitcoinabuse-report-address address=abcde12345 abuser=abuser@abuse.net abuse_type="bitcoin tumbler" description="this is a description of the abuse"

Human Readable Output

Bitcoin address abcde12345 by abuse bitcoin user abuser@abuse.net was reported to BitcoinAbuse API

bitcoinabuse-get-indicators


Gets indicators from the feed.

Base Command

bitcoinabuse-get-indicators

Input

Argument Name Description Required
limit The maximum number of results to return. Default is 50. Optional

Context Output

There is no context output for this command.

Command Example

!bitcoinabuse-get-indicators limit=1

Context Example

{}

Human Readable Output

Indicators

value type fields
bitcoin:1MfhfDZdv2QXmBBZMom5ZnZzp8VVrJUENw Cryptocurrency Address Value: bitcoin:1MfhfDZdv2QXmBBZMom5ZnZzp8VVrJUENw
rawaddress: 1MfhfDZdv2QXmBBZMom5ZnZzp8VVrJUENw
countryname: Australia
creationdate: 2021-01-17T00:30:36.000000Z
description: I know **** is one of your password on day of hack..

Lets get directly to the point.
Not one person has paid me to check about you.

You do not know me and you’re probably thinking why you are getting this email?
in fact, i actually placed a malware on the adult vids (adult porn) website and you know what, you visited this site to experience fun (you know what i mean).
When you were viewing videos, your browser started out operating as a RDP having a key logger which provided me with accessibility to your display and web cam.


immediately after that, my malware obtained every one of your contacts from your Messenger, FB, as well as email account.


after that i created a double-screen video. 1st part shows the video you were viewing (you have a nice taste omg), and 2nd part displays the recording of your cam, and its you.
Best solution would be to pay me $2763.


We are going to refer to it as a donation. in this situation, i most certainly will without delay remove your video.



Bitcoin address: 1MfhfDZdv2QXmBBZMom5ZnZzp8VVrJUENw

[case SeNSiTiVe, copy & paste it]


You could go on your life like this never happened and you will not ever hear back again from me.


You’ll make the payment via Bitcoin (if you do not know this, search ‘how to buy bitcoin’ in Google).
if you are planning on going to the law, surely, this e-mail can not be traced back to me, because it’s hacked too.
I have taken care of my actions. i am not looking to ask you for a lot, i simply want to be paid.
if i do not receive the bitcoin;, i definitely will send out your video recording to all of your contacts including friends and family, co-workers, and so on.
Nevertheless, if i do get paid, i will destroy the recording immediately.
If you need proof, reply with Yeah then i will send out your video recording to your 8 friends.
it’s a nonnegotiable offer and thus please don’t waste mine time & yours by replying to this message.
abusetype: ransomware
tags:
reportscount: 1
cryptocurrencyaddresstype: bitcoin

Configuration parameters

  • feed — Fetch indicators
  • api_key — API Key
  • credentials_api_key
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings
  • initial_fetch_interval — First Fetch Time (required)
  • feedReputation — Indicator Reputation
  • feedReliability — Source Reliability (required)
  • feedExpirationPolicy
  • tlp_color — Traffic Light Protocol Color
  • feedFetchInterval — Feed Fetch Interval
  • feedExpirationInterval
  • feedBypassExclusionList — Bypass exclusion list
  • feedTags — Tags

Commands (2)

  • bitcoinabuse-get-indicators Deprecated

    Gets indicators from the feed.

  • bitcoinabuse-report-address Deprecated

    Reports an abuser to Bitcoin Abuse service. 'abuse_type_other' field is required when 'abuse_type' is other

"""
Bitcoin Abuse Integration for Cortex XSOAR - Unit Tests file
"""

import io

import pytest

from BitcoinAbuse import BitcoinAbuseClient, bitcoin_abuse_report_address_command, bitcoin_abuse_get_indicators_command, \
    update_indicator_occurrences, READER_CONFIG, bitcoin_abuse_fetch_indicators_command
from CommonServerPython import DemistoException, Dict, json

SERVER_URL = 'https://www.bitcoinabuse.com/api/'
client = BitcoinAbuseClient(
    base_url=SERVER_URL,
    insecure=True,
    proxy=False,
    api_key='',
    initial_fetch_interval='',
    reader_config=READER_CONFIG,
    have_fetched_first_time=False,
    feed_tags=['Tag1', 'Tag2'],
    tlp_color='WHITE'
)


def util_load_json(path):
    with io.open(path, mode='r', encoding='utf-8') as f:
        return json.loads(f.read())


bitcoin_responses = util_load_json('test_data/bitcoin_responses.json')
report_address_scenarios = util_load_json('test_data/report_command.json')
successful_bitcoin_report_command_output = 'Bitcoin address 12xfas41 by abuse bitcoin user ' \
                                           'blabla@blabla.net was reported to ' \
                                           'BitcoinAbuse service'
failure_bitcoin_report_command_output = 'bitcoin report address did not succeed: {}'.format(
    bitcoin_responses['failure']['response'])
get_indicators_scenarios = util_load_json('test_data/get_indicators_command.json')


@pytest.mark.parametrize('response, address_report, expected',
                         [(bitcoin_responses['success'],
                           report_address_scenarios['valid'],
                           successful_bitcoin_report_command_output
                           ),
                          (bitcoin_responses['success'],
                           report_address_scenarios['valid_other'],
                           successful_bitcoin_report_command_output)
                          ])
def test_report_address_successful_command(requests_mock, response: Dict, address_report: Dict, expected: str):
    """
        Given:
         - Bitcoin address to report.

        When:
         - Reporting valid address to Bitcoin Abuse service.

        Then:
         - When reporting to the API should return failure - the command fails and the correct output is given.
         - When reporting to the API should success - the command succeeds and the correct output is given.
        """
    requests_mock.post(
        'https://www.bitcoinabuse.com/api/reports/create',
        json=response
    )
    assert bitcoin_abuse_report_address_command(client, address_report).readable_output == expected


@pytest.mark.parametrize('address_report, expected',
                         [(report_address_scenarios['other_type_missing'],
                           'Bitcoin Abuse: abuse_type_other is mandatory when abuse type is other'),
                          (report_address_scenarios['unknown_type'],
                           'Bitcoin Abuse: invalid type of abuse, please insert a correct abuse type')
                          ])
def test_report_address_command_invalid_arguments(address_report: Dict, expected: str):
    """
       Given:
        - Invalid bitcoin address report.

       When:
        - Trying to report the address to Bitcoin Abuse service.

       Then:
        - Ensure the command throws an error.
        - Ensure the expected error with the expected error message is returned.
       """

    with pytest.raises(DemistoException, match=expected):
        bitcoin_abuse_report_address_command(client, address_report)


def test_failure_response_from_bitcoin_abuse(requests_mock):
    """
       Given:
        - bitcoin address report.

       When:
        - Trying to report the address to Bitcoin Abuse Api, and receiving a failure response from Bitcoin Abuse service.

       Then:
        - Ensure the command throws an error.
        - Ensure the expected error with the expected error message is returned.
       """
    requests_mock.post(
        'https://www.bitcoinabuse.com/api/reports/create',
        json=bitcoin_responses['failure']
    )
    with pytest.raises(DemistoException, match=failure_bitcoin_report_command_output):
        bitcoin_abuse_report_address_command(client, report_address_scenarios['valid'])


@pytest.mark.parametrize(
    'initial_fetch_interval, have_fetched_first_time, expected_url_suffix, expected_have_fetched_first_time',
    [('30 Days', False, {'download/30d'}, True),
     ('Forever', False, {'download/forever', 'download/30d'}, True),
     ('30 Days', True, {'download/1d'}, True)
     ])
def test_url_suffixes_builder(initial_fetch_interval, have_fetched_first_time, expected_url_suffix,
                              expected_have_fetched_first_time):
    """
    Given:
     - Request for url to fetch indicators.

    When:
     - Case a: First fetch time is 30 Days, fetching for the first time.
     - Case b: First fetch time is Forever, fetching for first time.
     - Case c: First fetch time is 30 Days, not fetching for first time.

    Then:
     - Case a: Ensure that the monthly download suffix is returned.
     - Case b: Ensure that the monthly and forever download suffix is returned.
     - Case c: Ensure that the daily download suffix is returned.
    """
    client.have_fetched_first_time = have_fetched_first_time
    client.initial_fetch_interval = initial_fetch_interval
    assert client.build_fetch_indicators_url_suffixes() == expected_url_suffix


def test_get_indicators_command(requests_mock):
    """
    Given:
        - params: Demisto params for get-indicators command.
        - args: Demisto args for get-indicators command.
    When:
        - Command `bitcoinabuse-get-indicators` is being called.
    Then:
        - Assert the CommandResults object returned is as expected.
    """
    requests_mock.get(
        'https://www.bitcoinabuse.com/api/download/30d?api_token=123',
        content=get_indicators_scenarios['mock_response'].encode('utf-8')
    )
    client.api_key = '123'
    client.have_fetched_first_time = False
    results = bitcoin_abuse_get_indicators_command(client, args={'limit': 1})
    assert results.raw_response == get_indicators_scenarios['expected']['raw_response']
    assert results.readable_output == get_indicators_scenarios['expected']['readable_output']


def test_update_indicator_occurrences():
    """
    Given:
        - indicator: Indicator fetched from Bitcoin Abuse service.
        - address_to_count_dict: Dict of Bitcoin addresses to count of occurrences.
    When:
        - Update_indicator_occurrences is being called.
    Then:
        - Assert that 'address_to_count_dict' is updated as expected.
    """
    first_ind = {'value': '12345abcde'}
    second_ind = {'value': '67890fghij'}
    address_to_count_dict = {}
    update_indicator_occurrences(first_ind, address_to_count_dict)
    update_indicator_occurrences(first_ind, address_to_count_dict)
    update_indicator_occurrences(second_ind, address_to_count_dict)
    assert (address_to_count_dict.get('12345abcde')) == 2
    assert (address_to_count_dict.get('67890fghij', 0)) == 1
    assert (address_to_count_dict.get('12bxcas', 0)) == 0


def test_bitcoin_abuse_fetch_indicators_command(mocker):
    """
    Given:
    - A BitcoinAbuseClient object.

    When:
    - Running the bitcoin_abuse_fetch_indicators_command function.

    Then:
    - Ensure that indicators are fetched successfully and created in Demisto.
    - Ensure that integration context is updated after successful fetch.
    - Tests that indicators are fetched successfully and created in Demisto..
    """
    import demistomock as demisto
    mocker.patch.object(demisto, 'getIntegrationContext', return_value={'have_fetched_first_time': False})
    mock_create_indicator = mocker.patch.object(demisto, 'createIndicators')
    mocker.patch.object(client, 'get_indicators', return_value=([{'value': 'address1'}, {'value': 'address2'}], False))
    bitcoin_abuse_fetch_indicators_command(client)
    assert demisto.createIndicators.call_count == 1
    assert mock_create_indicator.call_count == 1
    assert demisto.createIndicators.call_args[0][0] == [{'value': 'address1'}, {'value': 'address2'}]
    assert not(demisto.createIndicators.call_args[1]['noUpdate'])