账户盗用欺诈

1. 简介

账户盗用欺诈 (ATO) 是一种复杂的身份盗窃形式,网络犯罪分子通过这种方式未经授权地访问合法用户账户。这种日益增长的威胁影响着从金融服务到社交媒体平台等各种账户类型,对个人和组织都造成了重大影响。根据最近的研究,22% 的美国成年人曾是 ATO 欺诈的受害者,平均个人损失高达 12,000 美元。这种欺诈通常涉及通过网络钓鱼、数据泄露或社会工程等方式窃取凭证,然后利用账户进行未经授权的交易或进一步的欺诈活动。随着数字服务的扩展,强大的检测和预防策略对于防范这种不断演变的威胁变得越来越重要。

2. 场景

账户盗用类型

  • 金融账户欺诈:未经授权的转账、欺诈性购买和信用卡申请

  • 电子邮件账户泄露:访问个人信息、重置密码和进一步的账户盗用

  • 社交媒体劫持:身份冒充、诈骗传播和社会工程

问题范围

  • 广泛影响:22% 的美国成年人曾是账户盗用的受害者

  • 财务损失:每次事件的平均个人损失达 12,000 美元

  • 业务影响:严重的声誉损害和潜在的法律后果

  • 复杂性增加:越来越多地使用自动化工具和 AI 进行大规模攻击

挑战

  • 复杂的攻击向量:通过网络钓鱼、恶意软件和社会工程的多个入口点

  • 凭证填充:使用被盗用户名/密码组合的自动化攻击

  • 设备欺骗:欺诈者使用先进技术绕过设备指纹识别

  • 身份验证绕过:规避多因素身份验证的复杂方法

3. 解决方案

图数据库为检测和预防账户盗用欺诈提供了一种强大的方法。通过将用户行为、设备交互和账户活动的复杂网络建模为互联网络,图技术可以识别传统系统可能遗漏的可疑模式。这种方法对于 ATO 欺诈特别有效,因为它需要同时分析多个数据点和关系。

3.1. 图数据库如何提供帮助?

  1. 设备指纹识别: Neo4j 可以跟踪用户账户、设备和 IP 地址之间的关系,以识别可疑的登录模式和潜在的凭证填充攻击。

  2. 行为分析: 图数据库擅长建模正常用户行为模式并检测异常,例如

    • 异常登录时间或地点

    • 交易模式的可疑变化

    • 意外的账户设置修改

    • 应用程序内的异常导航模式

  3. 身份验证网络: 创建连接以下各项的综合身份图

    • 用户账户和相关的电子邮件地址

    • 电话号码和身份验证方法

    • 设备指纹和登录位置

    • 交易模式和受益人关系

  4. 实时检测: Neo4j 支持

    • 根据已知模式即时验证登录尝试

    • 实时分析交易序列

    • 即时识别可疑 IP 地址或设备

    • 基于图模式的动态风险评分

  5. 网络分析: 通过以下方式揭露复杂的欺诈团伙

    • 识别被盗账户之间的共享属性

    • 检测可疑活动集群

    • 追踪凭证填充攻击的蔓延

    • 映射已知欺诈实体之间的关系

4. 建模

本节提供 Cypher 查询示例,演示如何构建数据以检测账户盗用欺诈。示例图将包括用户、设备、会话、位置和身份验证事件的节点,以及显示这些实体在正常和可疑账户访问模式下如何交互的关系。

4.1. 数据模型

4.1.1 必填字段

Person 节点

  • id: 人员的唯一标识符

  • email: 主要电子邮件地址

Device 节点

  • deviceID: 设备的唯一标识符

  • deviceType: 设备类型(移动设备、桌面设备、平板电脑)

  • userAgent: 浏览器/应用用户代理字符串

IP 节点

  • ip: IP 地址

ISP 节点

  • isp: 互联网服务提供商

Location 节点

  • city: 城市名称

  • country: 国家代码

Session 节点

  • sessionID: 唯一会话标识符

  • status: 会话状态(成功、失败、可疑)

Event 节点

  • eventID: 唯一事件标识符

  • eventType: 身份验证事件类型

  • timestamp: 事件时间戳

  • status: 身份验证状态

Account 节点

  • accountNumber: 唯一账户号码

关系

  • USED_BY: 人员使用设备

  • PARTICIPATED_IN_EVENT: 人员参与事件

  • USES_IP: 事件使用 IP

  • HAS_LOCATION: 事件具有位置

  • SESSION_USES_DEVICE: 会话使用设备

  • OWNS: 人员拥有账户

  • IS_ALLOCATED_TO: IP 分配给 ISP

  • LOCATED_IN: IP 位于位置

  • HAS_EVENT: 会话具有事件

4.2. 演示数据

以下 Cypher 语句将创建一个示例图,演示典型的账户访问模式

//
// Create Person nodes
//
CREATE (p1:Person {id: "P001", email: "user1@example.com"})
CREATE (p2:Person {id: "P002", email: "user2@example.com"})
CREATE (p3:Person { id: "P003", email: "user3@example.com"})

//
// Create Device nodes
//
CREATE (d1:Device {id: "WEB001", deviceType: "desktop", userAgent: "Mozilla/5.0 Chrome/91.0"})
CREATE (d2:Device {id: "WEB002", deviceType: "mobile", userAgent: "Mozilla/5.0 Mobile Safari/537.36"})
CREATE (d3:Device {id: "SUSPICIOUS001", deviceType: "desktop", userAgent: "Mozilla/5.0 Firefox/89.0"})

//
// Create IP nodes
//
CREATE (ip1:IP {ip: "192.168.1.1"})
CREATE (ip2:IP {ip: "10.0.0.1"})
CREATE (ip3:IP {ip: "203.0.113.1"})
CREATE (ip4:IP {ip: "198.51.100.1"})
CREATE (ip5:IP {ip: "172.16.0.1"})

//
// Create ISP nodes
//
CREATE (isp1:ISP {isp: "BT"})
CREATE (isp2:ISP {isp: "Orange"})
CREATE (isp3:ISP {isp: "Verizon"})
CREATE (isp4:ISP {isp: "China Telecom"})

//
// Create Location nodes
//
CREATE (l1:Location {city: "London", country: "UK"})
CREATE (l2:Location {city: "Paris", country: "France"})
CREATE (l3:Location {city: "Beijing", country: "China"})
CREATE (l4:Location {city: "Lagos", country: "Nigeria"})
CREATE (l5:Location {city: "New York", country: "USA"})

//
// Create Session nodes
//
CREATE (s1:Session {id: "SESS001", status: "success"})
CREATE (s2:Session {id: "SESS002", status: "success"})
CREATE (s3:Session {id: "SESS003", status: "failed"})
CREATE (s4:Session {id: "SESS004", status: "failed"})
CREATE (s5:Session {id: "SESS005", status: "failed"})

//
// Create Event nodes
//
CREATE (e1:Event {created: datetime("2024-03-01T10:00:00"), id: "EVT001", sessionKey: "SESS001", status: "success"})
CREATE (e2:Event {created: datetime("2024-03-01T10:05:00"), id: "EVT002", sessionKey: "SESS002", status: "success"})
CREATE (e3:Event {created: datetime("2024-03-01T11:00:00"), id: "EVT003", sessionKey: "SESS003", status: "failed"})
CREATE (e4:Event {created: datetime("2024-03-01T11:05:00"), id: "EVT004", sessionKey: "SESS004", status: "failed"})
CREATE (e5:Event {created: datetime("2024-03-01T11:10:00"), id: "EVT005", sessionKey: "SESS005", status: "failed"})

//
// Create Account nodes
//
CREATE (a1:Account {accountNumber: "ACC001"})
CREATE (a2:Account {accountNumber: "ACC002"})
CREATE (a3:Account {accountNumber: "ACC003"})

//
// Create Relationships
//

// Pattern 1: Single device logging into multiple accounts
CREATE (d3)-[:USED_BY]->(p1)
CREATE (d3)-[:USED_BY]->(p2)
CREATE (d3)-[:USED_BY]->(p3)

// Pattern 2: Different locations logging into single account
CREATE (p1)-[:PARTICIPATED_IN_EVENT]->(e1)
CREATE (e1)-[:USES_IP]->(ip1)
CREATE (e1)-[:HAS_LOCATION]->(l1)
CREATE (p1)-[:PARTICIPATED_IN_EVENT]->(e2)
CREATE (e2)-[:USES_IP]->(ip3)
CREATE (e2)-[:HAS_LOCATION]->(l3)

// Pattern 3: Multiple failed login attempts from different IPs
CREATE (p2)-[:PARTICIPATED_IN_EVENT]->(e3)
CREATE (e3)-[:USES_IP]->(ip2)
CREATE (e3)-[:HAS_LOCATION]->(l2)
CREATE (p2)-[:PARTICIPATED_IN_EVENT]->(e4)
CREATE (e4)-[:USES_IP]->(ip4)
CREATE (e4)-[:HAS_LOCATION]->(l4)
CREATE (p2)-[:PARTICIPATED_IN_EVENT]->(e5)
CREATE (e5)-[:USES_IP]->(ip5)
CREATE (e5)-[:HAS_LOCATION]->(l5)

// Additional contextual relationships
CREATE (ip1)-[:IS_ALLOCATED_TO]->(isp1)
CREATE (ip2)-[:IS_ALLOCATED_TO]->(isp2)
CREATE (ip3)-[:IS_ALLOCATED_TO]->(isp4)
CREATE (ip4)-[:IS_ALLOCATED_TO]->(isp3)
CREATE (ip5)-[:IS_ALLOCATED_TO]->(isp3)

// Connect IP to Location
CREATE (ip1)-[:LOCATED_IN]->(l1)
CREATE (ip2)-[:LOCATED_IN]->(l2)
CREATE (ip3)-[:LOCATED_IN]->(l3)
CREATE (ip4)-[:LOCATED_IN]->(l4)
CREATE (ip5)-[:LOCATED_IN]->(l5)

// Session device relationships
CREATE (s1)-[:SESSION_USES_DEVICE]->(d1)
CREATE (s2)-[:SESSION_USES_DEVICE]->(d3)
CREATE (s3)-[:SESSION_USES_DEVICE]->(d2)
CREATE (s4)-[:SESSION_USES_DEVICE]->(d2)
CREATE (s5)-[:SESSION_USES_DEVICE]->(d2)

// Connect Session to Event
CREATE (s1)-[:HAS_EVENT]->(e1)
CREATE (s2)-[:HAS_EVENT]->(e2)
CREATE (s3)-[:HAS_EVENT]->(e3)
CREATE (s4)-[:HAS_EVENT]->(e4)
CREATE (s5)-[:HAS_EVENT]->(e5)

// Update Relationships
CREATE (p1)-[:OWNS]->(a1)
CREATE (p2)-[:OWNS]->(a2)
CREATE (p3)-[:OWNS]->(a3)

4.3. Neo4j 架构

如果您调用

// Show neo4j schema
CALL db.schema.visualization()

您将看到以下响应

fs account takeover fraud schema

5. Cypher 查询

5.1. 单个设备登录到多个不同账户

在此查询中,我们将识别用于访问多个不同用户账户的设备,这是凭证填充攻击和账户盗用尝试中的常见模式。

查看图

// Show the relationships between suspicious devices and multiple accounts
MATCH path=(d:Device)-[:USED_BY]->(p:Person)-[:OWNS]->(a:Account)
WITH d, count(p) as accountCount
WHERE accountCount > 1
MATCH path=(d)-[:USED_BY]->(p:Person)-[:OWNS]->(a:Account)
RETURN path

查看统计数据

// Get detailed statistics about devices accessing multiple accounts
MATCH (d:Device)-[:USED_BY]->(p:Person)-[:OWNS]->(a:Account)
WITH d,
     count(p) as uniqueAccounts,
     collect(p.email) as compromisedEmails,
     d.deviceType as deviceType,
     d.userAgent as userAgent
WHERE uniqueAccounts > 1
RETURN d.id as DeviceID,
       deviceType as DeviceType,
       userAgent as UserAgent,
       uniqueAccounts as NumberOfAccounts,
       compromisedEmails as CompromisedAccounts
ORDER BY uniqueAccounts DESC

作用

  • 第一个查询可视化了可疑设备及其与多个账户的连接网络

  • 第二个查询提供了每个可疑设备的详细统计信息,包括

  • 访问的唯一账户数量

  • 设备类型和用户代理信息

  • 可能被盗用的电子邮件账户列表

风险指标

  • 24 小时内访问超过 2 个不同账户的设备

  • 多个账户的登录失败尝试

  • 可疑的用户代理字符串或设备特征

  • 快速连续的登录尝试,表明自动化攻击

5.2. 可疑会话模式

在这些查询中,我们分析会话模式,通过异常会话行为、登录失败尝试和会话内可疑位置变化来识别潜在的账户盗用尝试。

查看登录失败尝试

// Show clusters of failed login attempts within a time window
MATCH (p:Person)-[:PARTICIPATED_IN_EVENT]->(e:Event)
WHERE e.status = 'failed'
WITH p, e
ORDER BY e.created
WITH p,
     collect({
         eventId: e.id,
         eventTime: e.created,
         status: e.status
     }) as attempts
WHERE size(attempts) >= 3
RETURN p.email as UserEmail,
       attempts,
       size(attempts) as FailedAttempts
ORDER BY FailedAttempts DESC

查看位置变化

// Detect rapid location changes within sessions
MATCH (p:Person)-[:PARTICIPATED_IN_EVENT]->(e:Event)-[:HAS_LOCATION]->(l:Location)
WITH p, e, l
ORDER BY e.created
WITH p,
     collect({
         location: l.city + ', ' + l.country,
         eventTime: e.created
     }) as locations
WHERE size(locations) > 1
RETURN p.email as UserEmail,
       locations,
       size(locations) as LocationChanges
ORDER BY LocationChanges DESC

查看会话时间轴

// Analyse session patterns over time
MATCH (p:Person)-[:PARTICIPATED_IN_EVENT]->(e:Event), (d:Device)<-[:SESSION_USES_DEVICE]-(s:Session)-[:HAS_EVENT]->(e:Event)
WHERE e.sessionKey = s.id
WITH p, d, e, s
RETURN p.email as UserEmail,
       d.id as DeviceID,
       d.deviceType as DeviceType,
       e.created as EventTime,
       s.status as SessionStatus,
       duration.between(
           min(e.created),
           max(e.created)
       ).minutes as SessionDurationMinutes
ORDER BY e.created

作用

  • 第一个查询识别登录失败尝试的集群

  • 按用户分组失败尝试

  • 显示失败的序列和时间

  • 有助于识别暴力破解攻击

  • 第二个查询检测可疑位置变化

  • 跟踪用户会话内的位置变化

  • 识别物理上不可能的旅行模式

  • 有助于发现位置欺骗或被盗用账户

  • 第三个查询分析会话模式

  • 显示会话事件的完整时间轴

  • 跟踪会话内的设备变化

  • 衡量会话时长和活动模式

风险指标

  • 短时间内多次登录失败尝试

  • 登录位置快速变化

  • 异常的会话时长或活动模式

  • 单个会话中使用多个设备

  • 不匹配的设备类型或用户代理

  • 超出正常用户模式的会话

5.3. 来自不同 IP 的多次登录失败尝试

在这些查询中,我们分析来自不同 IP 地址针对同一账户的登录失败尝试模式,这是暴力破解攻击的常见指标。

查看登录失败模式

// Show accounts with multiple failed login attempts from different IPs
MATCH (p:Person)-[:PARTICIPATED_IN_EVENT]->(e:Event)-[:USES_IP]->(ip:IP)
WHERE e.status = 'failed'
WITH p, count(DISTINCT ip) as uniqueIPs, collect(DISTINCT ip.ip) as ipAddresses,
     count(e) as totalFailedAttempts
WHERE uniqueIPs >= 2
RETURN p.email as TargetAccount,
       totalFailedAttempts as FailedAttempts,
       uniqueIPs as NumberOfUniqueIPs,
       ipAddresses as IPAddresses
ORDER BY totalFailedAttempts DESC

查看详细时间轴

// Show detailed timeline of failed attempts with location context
MATCH (p:Person)-[:PARTICIPATED_IN_EVENT]->(e:Event)-[:USES_IP]->(ip:IP),
      (e)-[:HAS_LOCATION]->(l:Location),
      (ip)-[:IS_ALLOCATED_TO]->(isp:ISP)
WHERE e.status = 'failed'
WITH p, count(DISTINCT ip) as uniqueIPs
WHERE uniqueIPs >= 2
MATCH (p)-[:PARTICIPATED_IN_EVENT]->(e:Event)-[:USES_IP]->(ip:IP),
      (e)-[:HAS_LOCATION]->(l:Location),
      (ip)-[:IS_ALLOCATED_TO]->(isp:ISP)
WHERE e.status = 'failed'
RETURN p.email as TargetAccount,
       e.created as AttemptTime,
       ip.ip as IPAddress,
       l.city + ', ' + l.country as Location,
       isp.isp as ISP
ORDER BY p.email, e.created

查看地理分布

// Show geographic distribution of failed attempts
MATCH (p:Person)-[:PARTICIPATED_IN_EVENT]->(e:Event)-[:HAS_LOCATION]->(l:Location)
WHERE e.status = 'failed'
WITH p, l, count(e) as attemptsFromLocation
WITH p,
     count(DISTINCT l) as uniqueLocations,
     collect(DISTINCT {
         location: l.city + ', ' + l.country,
         attempts: attemptsFromLocation
     }) as locationBreakdown
WHERE uniqueLocations >= 2
RETURN p.email as TargetAccount,
       uniqueLocations as NumberOfLocations,
       locationBreakdown as LocationBreakdown
ORDER BY uniqueLocations DESC

作用

  • 第一个查询提供了受攻击账户的概览

  • 计算每个账户的总失败尝试次数

  • 显示使用的唯一 IP 数量

  • 列出所有涉及的 IP 地址

  • 第二个查询显示详细时间轴

  • 登录失败尝试的按时间顺序序列

  • 每次尝试的地理位置

  • 每个 IP 的 ISP 信息

  • 有助于识别攻击模式和时间

  • 第三个查询分析地理分布

  • 显示唯一位置的数量

  • 提供每个位置的尝试次数明细

  • 有助于识别地理分散的攻击

风险指标

  • 短时间内来自不同 IP 的多次失败尝试

  • 尝试之间地理上不可能的位置变化

  • 来自已知高风险 ISP 或位置的失败尝试

  • 尝试时间上存在系统性模式,表明自动化

  • 大量唯一 IP 针对单个账户

© . All rights reserved.