Skip to main content
 
 
Splunk Lantern

Monitoring for account abuse with the Splunk platform

 

You work for a financial services company where customer accounts are occasionally misused for activities that violate your policies, such as money laundering, fraudulent transactions, or spamming. This kind of account abuse can harm your customers and damage your business's reputation. Your aim is to identify suspicious behaviors such as excessive transaction volumes, use of multiple accounts for transfers, and patterns indicative of mule accounts being used for illegal activities.

Account abuse occurs when an individual misuses their authorized access to an account to perform unauthorized or malicious activities. Unlike account takeover (ATO), which specifically involves unauthorized access by external actors, account abuse can encompass a broader range of activities, including:

  • Insider threats: Legitimate users exploiting their access for malicious purposes.
  • Privilege misuse: Users exceeding their authorized privileges to access sensitive information or perform restricted actions.
  • Automated abuse: Bots or scripts that exploit account functionalities for fraudulent gains.
  • Policy violations: Users engaging in activities that violate organizational policies, such as excessive data downloads or unauthorized transactions.

Effective detection of account abuse is crucial for maintaining the integrity of financial services, protecting sensitive information, and ensuring compliance with regulatory standards. Detecting account abuse can be a significant challenge for fraud teams, as threat indicators and attacker tactics constantly evolve.

This article shows you how to use searches in the Splunk platform to create basic detection methods. For advanced techniques that leverage user behavioral analytics to stay ahead of emerging threats, see Monitoring for account abuse with the Splunk App for Behavioral Analytics.

  • Some commands, parameters, and field names in the searches below might need to be adjusted to match your environment.
  • Splunk recommends that customers look into using data models, report acceleration, or summary indexing when searching across hundreds of GBs of events in a single search. The searches provided here are a good starting point, but depending on your data, search time range, and other factors, more can be done to ensure that they scale appropriately.
  • Some of the searches below include lookup commands that enrich event data by matching and adding fields from external data sources, such as CSV files or databases. For more information, see Search reference: lookup.

Data required

  • Application data for consumer financial applications
  • Depending on the search you're looking to run, you might also need a CSV or KV lookup of suspicious countries, suspicious IPs, high-risk accounts, and/or high-risk payees.

How to use the Splunk platform for this use case

There are many searches you can run with Splunk software to detect account takeovers. You can detect these attempts using these searches:

► High volume of transactions

This search helps uncover accounts with an unusually high number of transactions in the last hour. An abnormally high transaction volume can indicate attempts to quickly move funds out of the account, especially if linked to fraud or unauthorized actions. Detecting these accounts early helps mitigate potential financial losses and enhances security for both the institution and the account holder.

Procedure

  1. Ensure that the correct source types are available for analyzing data related to transaction logs. The table below outlines recommended source types, associated fields, and typical data sources for transactions within financial applications.

    Suggested sourcetype Fields Data sources

    transaction_logs

    transaction_id, account_number, transaction_type, amount, currency, timestamp, account_type, channel, device_info, status, src_ip, source_city, source_country, dest_ip, dest_city, dest_country, old_balance_source, new_balance_source, old_balance_dest, new_balance_dest, payee, transaction_class

    • Payment gateways
      • Stripe, PayPal, Clover
    • Banking systems
      • Core banking platforms
    • E-commerce platforms
      • Shopify, Magento
    • Point of Sale (POS) systems
      • Retail transaction systems
    • Internal Financial Systems
      • Enterprise Resource Planning (ERP) systems
  2. Run the following search.

    sourcetype=<consumer financial app transaction logs> earliest=-7d@d latest=now()
    | eval period=if(_time >= relative_time(now(), "-1h@h"), "current", "historical")
    | bin _time span=1h
    | stats count AS txn_count BY usernames period _time
    | eventstats 
        avg(eval(if(period=="historical", txn_count, null()))) as avg_txn_count,
        stdev(eval(if(period=="historical", txn_count, null()))) as stdev_txn_count
        by account_id
    | where period="current" AND txn_count > (avg_txn_count + 3 * stdev_txn_count)
    | sort -txn_count
    | table account_id, txn_count, avg_txn_count, stdev_txn_count
    

Search explanation

The table provides an explanation of what each part of this search achieves. You can adjust this query based on the specifics of your environment.

Splunk Search Explanation

sourcetype=<consumer financial app transaction logs>

Search consumer financial app transaction logs.

earliest=-7d@d latest=now()

Set the search range to the last 7 days.

| eval period=if(_time >= relative_time(now(), "-1h@h"), "current", "historical")

Differentiate between current (last hour) and historical (past 7 days excluding the last hour) transactions.

| bin _time span=1h

Groups events into 1 hour intervals.

| stats count as txn_count by account_id period _time

Aggregate transaction counts per account_id for each hourly window by period.

| eventstats avg(eval(if(period=="historical", txn_count, null()))) as avg_txn_count

Calculate the average transaction count from the historical data for each account_id.

stdev(eval(if(period=="historical", txn_count, null()))) as stdev_txn_count by account_id

Calculate the standard deviation of transaction counts from the historical data for each account_id.

| where period="current" AND txn_count > (avg_txn_count + 3 * stdev_txn_count)

Filter for current transactions where the count exceeds the historical average by three standard deviations, indicating a significant anomaly.

| sort -txn_count

Sort by transaction count.

| table account_id, txn_count, avg_txn_count, stdev_txn_count

Output the results by highest anomalies first and present the key fields for analysis.

► Multiple accounts interfacing frequently

This search is designed to help you detect accounts transferring funds to each other frequently, which might indicate "mule networks" where funds are transferred to obscure a money trail. This search can highlight accounts with unusually frequent interactions, helping fraud teams quickly assess and halt suspicious activity, particularly for financial services targeted by organized networks.

Procedure

  1. Ensure that the correct source types are available for analyzing data related to account interfacing activities.The table below outlines recommended source types, associated fields, and typical data sources for monitoring account interfacing activity across financial applications.

    Suggested Sourcetype

    Fields

    Sources

    transaction_logs

    transaction_id, account_number, transaction_type, amount, currency, timestamp, account_type, channel, device_info, status, src_ip, source_city, source_country, dest_ip, dest_city, dest_country, old_balance_source, new_balance_source, old_balance_dest, new_balance_dest, payee, transaction_class
    • Payment gateways
      • Stripe, PayPal, Clover
    • Banking systems
      • Core banking platforms
    • E-commerce platforms
      • Shopify, Magento
    • Point of Sale (POS) systems
      • Retail transaction systems
    • Internal Financial Systems
      • Enterprise Resource Planning (ERP) systems

  2. Run the following search.
    index=payment_transactions "action=authorized"  
    | stats 
        count AS daily_txn_count 
        BY customer, vendor, _time
    | eventstats 
        avg(daily_txn_count) AS avg_txn_count, 
        stdev(daily_txn_count) AS stdev_txn_count 
        BY customer, vendor
    | where daily_txn_count > (avg_txn_count + 3 * stdev_txn_count)
    | sort -daily_txn_count
    | table customer, vendor, daily_txn_count, avg_txn_count, stdev_txn_count
    

Search explanation

The table provides an explanation of what each part of this search achieves. You can adjust this query based on the specifics of your environment.

Splunk Search Explanation

sourcetype=<consumer financial app auth logs>

Search consumer financial app auth logs.

| stats

count AS daily_txn_count

by customer, vendor, _time

Count the number of transactions and label it as txn_count. Group the count by customer, vendor, and _time (daily).

| eventstats

avg(daily_txn_count) AS avg_txn_count,

stdev(daily_txn_count) AS stdev_txn_count

BY customer, vendor

Compute the average daily transaction count for each customer-vendor.

Compute the standard deviation of daily transaction counts for each customer-vendor, indicating variability.

| where daily_txn_count > (avg_txn_count + 3 * stdev_txn_count)

Filter by transactions where the daily count exceeds the average by more than three standard deviations, indicating an anomaly.

| sort -daily_txn_count

Organize the results in descending order of transaction counts.

| table customer, vendor, daily_txn_count, avg_txn_count, stdev_txn_count

Output a table displaying the key metrics shown for each customer-vendor pair.

► Transactions involving high-risk countries

This search is designed to help you identify transactions involving countries known for high-risk activities. Identifying transactions involving high-risk regions is essential for compliance and risk management, as certain countries are associated with higher levels of financial crime. This search allows financial institutions to pinpoint transactions with specific countries or IPs, helping prevent illicit activity and ensuring regulatory adherence.

Procedure

  1. Ensure that the correct source types are available for identifying transaction activity. The table below outlines recommended source types, associated fields, and typical data sources for monitoring transactions across financial applications.

    Suggested sourcetype Fields Data sources

    transaction_logs

    transaction_id, account_number, transaction_type, amount, currency,timestamp, account_type, channel, device_info, status,src_ip, source_city, source_country, dest_ip, dest_city, dest_country, old_balance_source, new_balance_source, old_balance_dest, new_balance_dest, payee, transaction_class Payment gateways
    • Stripe, PayPal, Clover
    Banking systems
    • Core banking platforms
    E-commerce platforms
    • Shopify, Magento
    Point of Sale (POS) systems
    • Retail transaction systems
    Internal Financial Systems
    • Enterprise Resource Planning (ERP) systems
  2. Run the following search.

    sourcetype=<consumer financial app transaction logs> 
    status="completed" earliest=-24h@h 
    | lookup high_risk_countries country AS source_country OUTPUT country AS source_high_risk 
    | lookup high_risk_countries country AS destination_country OUTPUT country AS destination_high_risk 
    | lookup high_risk_ips ip_address OUTPUT ip_address AS high_risk_ip
    | eval high_risk_indicator isnotnull(source_high_risk), 
    "Source Country" isnotnull(destination_high_risk), 
    "Destination Country", isnotnull(high_risk_ip), "High-Risk IP"
    | where isnotnull(source_high_risk) OR isnotnull(destination_high_risk) OR isnotnull(high_risk_ip)
    | eval multi_factor_flag = if(transaction_amount > 10000, 1, 0)
    | where multi_factor_flag=1
    | sort -transaction_amount
    | table _time, account_id, transaction_id, transaction_amount, transaction_type, payee, source_country, destination_country, high_risk_indicator, ip_address, device_info
    

Search explanation

The table provides an explanation of what each part of this search achieves. You can adjust this query based on the specifics of your environment.

Splunk Search Explanation

sourcetype=<consumer financial app transaction logs>

Search consumer financial app transaction logs.

status="completed" earliest=-24h@h

Retrieve all completed transactions from the past 24 hours.

| lookup high_risk_countries country AS source_country OUTPUT country AS source_high_risk

Use the high_risk_countries lookup to identify transactions involving high-risk source countries.

| lookup high_risk_countries country AS destination_country OUTPUT country AS destination_high_risk

Use the high_risk_countries lookup to identify transactions involving high-risk destination countries.

| lookup high_risk_ips ip_address OUTPUT ip_address AS high_risk_ip

Use the high_risk_ip lookup to identify transactions involving high-risk IPs.

| eval high_risk_indicator

Evaluate whether any of the cases below are true.

isnotnull(source_high_risk), "Source Country"

Check whether the source country is high risk.

isnotnull(destination_high_risk), "Destination Country",

Check whether the destination country is high risk.

isnotnull(high_risk_ip), "High-Risk IP"

Check whether the IP is high risk.

| where isnotnull(source_high_risk) OR isnotnull(destination_high_risk) OR isnotnull(high_risk_ip)

Retain only the transactions where either the source_country, destination_country, or ip_address is identified as high-risk.

| eval multi_factor_flag = if(transaction_amount > 10000, 1, 0)

Check whether the transaction amount is over a 10,000 monetary threshold.

| where multi_factor_flag=1

Set flag if the transaction amount is over the threshold limit of 10,000.

| sort -transaction_amount

Sort the results in descending order of transaction amounts.

| table _time, account_id, transaction_id, transaction_amount, transaction_type, payee, source_country, destination_country, high_risk_indicator, ip_address, device_info

Select and format the specified fields for display for further review.

► Suspicious transaction patterns

This search allows you to detect specific patterns, like round-dollar transactions, or transactions just under reporting thresholds, which might indicate structuring attempts to bypass reporting thresholds. This search enables detection of these subtle indicators, providing early warning signs of potential financial misuse or fraud, and supporting proactive account monitoring and investigation.

Procedure

  1. Ensure that the correct source types are available for identifying unusual transaction patterns. The table below outlines recommended source types, associated fields, and typical data sources for monitoring transaction patterns across financial applications.

    Suggested source type

    Fields

    Sources

    transaction_logs

    user, transaction_id, transaction_amount, transaction_type, payee, location, device_info, _time, ip_address, status (completed, pending, failed)

    • Payment gateways
      • Stripe, PayPal, Clover
    • Banking systems
      • Core banking platforms
    • E-commerce platforms
      • Shopify, Magento
    • Point of Sale (POS) systems
      • Retail transaction systems
    • Internal Financial Systems
      • Enterprise Resource Planning (ERP) systems

  2. Run the following search.
    sourcetype=<consumer financial app transaction logs> status="completed" earliest=-7d@d
    | eval hour_of_day = strftime(_time, "%H")
    | lookup high_risk_usernames usernames OUTPUT usernames AS high_risk_usernames
    | lookup high_risk_countries country AS destination_country OUTPUT country AS high_risk_destination_country
    | lookup known_payees payee OUTPUT payee AS known_payee
    | lookup known_accounts account_id OUTPUT account_id AS known_account
    | stats 
        count AS txn_count,
        sum(transaction_amount) AS total_amount,
        avg(transaction_amount) AS avg_txn_amount,
        stdev(transaction_amount) AS stdev_txn_amount,
        dc(payee) AS unique_payees,
        dc(ip_address) AS unique_ips
        by account_id
    | eval txn_amount_threshold = avg_txn_amount + 3 * stdev_txn_amount
    | join account_id [
        search sourcetype=<consumer financial app transaction logs> status="completed" earliest=-1h@h
        | stats count AS recent_txn_count, sum(transaction_amount) AS recent_total_amount by account_id
    ]
    | eval structuring_flag = if(total_amount > 10000 AND avg_txn_amount < 500, 1, 0)
    | eval rapid_succession_flag = if(recent_txn_count > 20, 1, 0)
    | eval high_value_flag = if(recent_total_amount > txn_amount_threshold, 1, 0)
    | eval new_payee_flag = if(unique_payees > 10, 1, 0)
    | eval high_risk_payee_flag = if(isnotnull(high_risk_payee), 1, 0)
    | eval high_risk_country_flag = if(isnotnull(high_risk_destination_country), 1, 0)
    | eval suspicious_score = structuring_flag + rapid_succession_flag + high_value_flag + new_payee_flag + high_risk_payee_flag + high_risk_country_flag
    | where suspicious_score >= 2
    | sort -suspicious_score, -recent_total_amount
    | table account_id, txn_count, total_amount, recent_txn_count, recent_total_amount, suspicious_score, structuring_flag, rapid_succession_flag, high_value_flag, new_payee_flag, high_risk_payee_flag, high_risk_country_flag
    

    Search explanation

    The table provides an explanation of what each part of this search achieves. You can adjust this query based on the specifics of your environment.

    Splunk Search Explanation

    sourcetype=<consumer financial app transaction logs>

    Search consumer financial app auth logs.

    earliest=-7d@d

    Set a search range for 7 days.

    | eval hour_of_day = date_hour(_time)

    Extract the hour (0-23) from the _time field to analyze transaction patterns based on time of day.

    | lookup high_risk_payees payee OUTPUT payee AS high_risk_payee

    Use the high_risk_payees lookup to identify transactions involving high-risk payees.

    | lookup high_risk_countries country AS destination_country OUTPUT country AS high_risk_destination_country

    Use the high_risk_countries lookup to identify transactions involving high-risk destination countries.

    | lookup known_payees payee OUTPUT payee AS known_payee

    Use the known_payees lookup to identify transactions involving high-risk known payees.

    | lookup known_accounts account_id OUTPUT account_id AS known_account

    Use the known_accounts lookup to identify transactions involving high-risk known accounts.

    | stats count AS txn_count

    Count the total number of transactions per account.

    sum(transaction_amount) AS total_amount

    Total the number of transactions per account.

    avg(transaction_amount) AS avg_txn_amount

    Create an average for transactions amount per account.

    stdev(transaction_amount) AS stdev_txn_amount

    Set standard deviation for transaction amount per account.

    dc(payee) AS unique_payees

    Count the number of distinct payees per account.

    dc(ip_address) AS unique_ips

    BY account_id

    Count the number of distinct IP addresses per account.

    | eval txn_amount_threshold = avg_txn_amount + 3 * stdev_txn_amount

    Calculate the threshold as three standard deviations above the average transaction amount.

    | join account_id

    Join the main search results with a subsearch that aggregates recent transactions by account_id.

    search index=finance sourcetype="transaction_logs" status="completed" earliest=-1h@h

    Retrieve completed transactions from the last hour.

    | stats count AS recent_txn_count, sum(transaction_amount) AS recent_total_amount by account_id

    Calculate the count and sum of recent transactions per account.

    | eval structuring_flag = if(total_amount > 10000 AND avg_txn_amount < 500, 1, 0)

    Indicate potential structuring if total transactions exceed $10,000 but the average transaction is below $500.

    | eval rapid_succession_flag = if(recent_txn_count > 20, 1, 0)

    Indicate rapid succession of transactions if more than 20 transactions occurred in the last hour.

    | eval high_value_flag = if(recent_total_amount > txn_amount_threshold, 1, 0)

    Indicate high-value transactions if the recent total exceeds the dynamic threshold.

    | eval new_payee_flag = if(unique_payees > 10, 1, 0)

    Indicate transactions to a large number of unique payees, suggesting possible diversification to avoid detection.

    | eval high_risk_payee_flag = if(isnotnull(high_risk_payee), 1, 0)

    Indicate transactions involving high-risk payees.

    | eval high_risk_country_flag = if(isnotnull(high_risk_destination_country), 1, 0)

    Indicate transactions directed to high-risk countries.

    | eval suspicious_score = structuring_flag + rapid_succession_flag + high_value_flag + new_payee_flag + high_risk_payee_flag + high_risk_country_flag

    Aggregate individual flags into a composite score to quantify the level of suspicion for each account.

    | where suspicious_score >= 2

    Retain only those accounts exhibiting multiple suspicious indicators, reducing false positives.

    | sort -suspicious_score, -recent_total_amount

    Sort primarily by suspicious_score (descending) and secondarily by recent_total_amount (descending).

    | table account_id, txn_count, total_amount, recent_txn_count, recent_total_amount, suspicious_score, structuring_flag, rapid_succession_flag, high_value_flag, new_payee_flag, high_risk_payee_flag, high_risk_country_flag

    Display the specified fields in a structured table format


  3.  

Next steps

Use the results of these searches to make recommendations to the rest of the security team about which accounts should be investigated for potential account abuse. Create reports based on these searches and schedule them to run at a regular cadence as needed. Be sure to follow any industry policies and regulations that are required for compliance.

For advanced techniques leveraging user behavioral analytics to stay ahead of emerging threats, see Monitoring for account abuse with the Splunk App for Behavioral Analytics.

To further advance your use cases, the Splunk Essentials for the Financial Services Industry app helps you automate the searches to detect financial crime. The app also provides more insight on how searches can be applied in your environment, how they work, the difficulty level, and what data can be valuable to run them successfully.

The Splunk App for Fraud Analytics provides Splunk Enterprise Security users a number of other fraud detection solutions for financial services such as account takeover and new account abuse.

The Splunk App for Behavioral Profiling is a collection of workflows which enable you to operationalize machine learning driven detection and scoring of behavioral anomalies at scale in complex environments, correlated to profile and highlight the entities which require investigation.

If you have questions about monitoring for account takeover in your environment, you can reach out to your Splunk account team or representative for comprehensive advice and assistance. You can contact your account team through the Contact Us page. For more in-depth support, consult Splunk On-Demand Services to access credit-based services for direct access to Splunk technical consultants with a variety of technical services from a pre-defined catalog. Most customers have OnDemand Services per their license support plan. Engage the ODS team at ondemand@splunk.com if you would like assistance.

In addition, these resources might help you understand and implement this guidance: