USTA Stolen Credit Cards

This integration offers organizations the ability to track stolen credit card data across the web, providing comprehensive insight into compromised card information sourced from underground markets, dark web forums, and other malicious platforms.

Data Enrichment & Threat Intelligence · USTAv4 Cyber Threat Intelligence Platform

Details

IDUSTA Stolen Credit Cards
ProviderPRODAFT
CategoryData Enrichment & Threat Intelligence
From Version6.10.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix XSIAM

README

This integration offers organizations the ability to track stolen credit card data across the web, providing comprehensive insight into compromised card information sourced from underground markets, dark web forums, and other malicious platforms.

Configure USTAv4 Stolen Credit Cards in Cortex

  1. Navigate to Settings > Integrations > Servers & Services.
  2. Search for USTAv4 Stolen Credit Cards.
  3. Click Add instance to create and configure a new integration instance.

    Parameter Description Required
    Your server URL   True
    API Key The API Key to use for connection True
    Fetch incidents by status   False
    Trust any certificate (not secure)   False
    Use system proxy settings   False
    Fetch incidents   False
    First Fetch Time The time range to consider for the initial data fetch. Warning: Fetching a large time range may cause performance issues! True
  4. Click Test to validate the URLs, token, and connection.

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.

usta-scc-search


Search for stolen credit card number

Base Command

usta-scc-search

Input

Argument Name Description Required
card_number Credit card number to search. Required
page_size Number of vendors that should appear on each page. Each page of data will have at most this many vendors. Optional
page 1-indexed page number to get a particular page of results. Optional

Context Output

Path Type Description
USTA.StolenCreditCards.id Number The ticket ID of the alert
USTA.StolenCreditCards.card_number String The stolen credit card number
USTA.StolenCreditCards.expire String The expiration date of the stolen credit card
USTA.StolenCreditCards.created String The creation date of the stolen credit card

Command Example

!usta-scc-search card_number=133713371337 page=1 page_size=1

Context Example

{
    "USTA" : {
        "StolenCreditCards": {
            "id": 133737,
            "card_number": "133713371337",
            "expire": "06/31",
            "created": "2024-11-19T07:42:01.388163Z"
        }
    }
}

Configuration parameters

  • url — Your server URL (required)
  • api_key — API Key (required)
  • status — Fetch incidents by status
  • max_fetch — Maximum number of alerts per fetch
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings
  • isFetch — Fetch incidents
  • incidentFetchInterval — Incidents Fetch Interval
  • incidentType — Incident type
  • first_fetch — First Fetch Time (required)

Commands (1)

  • usta-scc-search

    Search for stolen credit card number.

"""Base Integration for Cortex XSOAR - Unit Tests file

Pytest Unit Tests: all funcion names must start with "test_"

More details: https://xsoar.pan.dev/docs/integrations/unit-testing

MAKE SURE YOU REVIEW/REPLACE ALL THE COMMENTS MARKED AS "TODO"

You must add at least a Unit Test function for every XSOAR command
you are implementing with your integration
"""

import json

import demistomock as demisto  # noqa: F401
from USTAStolenCreditCards import (
    Client,
    check_module,
    create_paging_header,
    fetch_incidents,
    main,
    stolen_credit_cards_search_command,
)


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


def test_check_module(mocker):
    """Tests test_module command function.

    Checks the output of the command function with the expected output.
    """
    mock_response = util_load_json("test_data/auth_success_response.json")

    client = Client(base_url="", verify=False, headers={}, proxy=False)

    mocker.patch.object(client, "check_auth", return_value=mock_response)

    response = check_module(client)
    assert response == "ok"


def test_fetch_incidents(mocker):
    """Tests fetch_incidents function.

    Checks the output of the function with the expected output.
    """
    mock_response = util_load_json("test_data/stolen_credit_cards_incidents_response.json")
    expected_output = util_load_json("test_data/stolen_credit_cards_incidents_expected_output.json")

    client = Client(base_url="", verify=False, headers={}, proxy=False)

    mocker.patch.object(client, "stolen_credit_cards_incidents", return_value=mock_response)

    last_run = {}
    first_fetch_time = "2023-01-01T00:00:00Z"
    max_results = 10
    status = "open"

    next_run, incidents = fetch_incidents(client, max_results, last_run, first_fetch_time, status)

    assert len(incidents) == len(mock_response)
    assert incidents == expected_output
    assert next_run["last_fetch"] == mock_response[0]["created"]


def test_stolen_credit_cards_search_command(mocker):
    """Tests stolen_credit_cards_search_command function.

    Checks the output of the command function with the expected output.
    """
    mock_response = util_load_json("test_data/search_empty_response.json")

    client = Client(base_url="", verify=False, headers={}, proxy=False)

    mocker.patch.object(client, "stolen_credit_cards_search_api_request", return_value=mock_response)

    args = {"card_number": "1234567890123456", "page_size": 10, "page": 1}

    result = stolen_credit_cards_search_command(client, args)

    assert result.outputs == mock_response
    assert result.outputs_prefix == "USTA.StolenCreditCards"
    assert result.outputs_key_field == "id"


def test_stolen_credit_cards_search_command_no_result(mocker):
    """Tests stolen_credit_cards_search_command function when there are no results.

    Checks the output of the command function with the expected output.
    """
    mock_response = util_load_json("test_data/search_empty_response.json")

    client = Client(base_url="", verify=False, headers={}, proxy=False)

    mocker.patch.object(client, "stolen_credit_cards_search_api_request", return_value=mock_response)

    args = {"card_number": "1234567890123456", "page_size": 10, "page": 1}

    result = stolen_credit_cards_search_command(client, args)

    # make sure result.readable_output contains "No results found"
    assert result.readable_output == "Showing 0 results, Size=10, from Page 1\n### Stolen Credit Cards\n**No entries.**\n"
    assert len(result.outputs["results"]) == 0


def test_create_paging_header():
    """
    Given:
        - A number of results, page number and page size.

    When:
        - Running the 'create_paging_header' function.

    Then:
        - Verify that the function returns the correct paging header.
    """
    results_num = 10
    page = 2
    size = 5

    expected_output = "Showing 10 results, Size=5, from Page 2\n"
    assert create_paging_header(results_num, page, size) == expected_output


def test_subsequent_run(mocker):
    """Tests fetch_incidents function.

    Checks the output of the function with the expected output.
    """
    mock_response = util_load_json("test_data/stolen_credit_cards_incidents_response.json")
    util_load_json("test_data/stolen_credit_cards_incidents_expected_output.json")

    client = Client(base_url="", verify=False, headers={}, proxy=False)

    mocker.patch.object(client, "stolen_credit_cards_incidents", return_value=mock_response)

    last_run = {"last_fetch": "2024-11-27T08:04:45.106412Z"}
    first_fetch_time = "2024-11-27T08:04:45.106412Z"
    max_results = 10
    status = "open"

    next_run, incidents = fetch_incidents(client, max_results, last_run, first_fetch_time, status)

    assert len(incidents) == 2
    assert next_run["last_fetch"] == "2024-11-27T08:04:45.106412Z"
    assert next_run["last_ids"] == [13371337]


def test_main_fetch_incidents_cmd(mocker):
    """Tests main function.

    Checks the output of the function with the expected output.
    """
    mock_response = util_load_json("test_data/stolen_credit_cards_incidents_response.json")

    Client(base_url="", verify=False, headers={}, proxy=False)

    mocker.patch.object(Client, "stolen_credit_cards_incidents", return_value=mock_response)

    mocker.patch.object(demisto, "command", return_value="fetch-incidents")
    mocker.patch.object(
        demisto,
        "params",
        return_value={
            "url": "https://example.com",
            "api_key": "API_KEY",
            "insecure": True,
            "proxy": False,
            "first_fetch": "3 days",
        },
    )
    mocker.patch.object(demisto, "args", return_value={})
    mocker.patch.object(demisto, "results")
    mocker.patch.object(demisto, "setLastRun")
    mocker.patch.object(demisto, "incidents")
    main()

    demisto.incidents.assert_called_once()
    demisto.results.assert_not_called()
    demisto.setLastRun.assert_called_once()


def test_main_test_module_cmd(mocker):
    """Tests main function.

    Checks the output of the function with the expected output.
    """
    mock_response = util_load_json("test_data/stolen_credit_cards_search_response.json")

    Client(base_url="", verify=False, headers={}, proxy=False)
    mocker.patch.object(
        demisto,
        "params",
        return_value={
            "url": "https://example.com",
            "api_key": "API_KEY",
            "insecure": True,
            "proxy": False,
            "first_fetch": "3 days",
        },
    )
    mocker.patch.object(Client, "check_auth", return_value=mock_response)
    mocker.patch.object(Client, "stolen_credit_cards_search_api_request", return_value=mock_response)
    mocker.patch.object(demisto, "command", return_value="usta-scc-search")
    mocker.patch.object(
        demisto,
        "args",
        return_value={
            "card_number": "1234567890123456",
        },
    )
    main()

    # make sure check_module and return_results functions were called