Ad
Security

How investigators traced $625 million back to North Korea

Artem Safonov
Artem Safonov , Threat Analyst
How investigators traced $625 million back to North Korea
Cover © Anonhaven

North Korea stole approximately $625 million in cryptocurrency through a single bridge exploit in March 2022. The total varies by source and pricing date. At ETH prices on March 23, Elliptic put the figure at $540 million and Merkle Science at $568 million.

At March 29 prices (the day of discovery), the number reaches $625 million. The $625 million figure is standard in media and DOJ references.

Attackers targeted Ronin Network, a blockchain sidechain built for Axie Infinity. They compromised the private keys of five out of nine validators and signed two fraudulent withdrawal transactions, taking 173,600 ETH and 25.5 million USDC. The funds left the bridge within minutes.

Four of the five were Sky Mavis's own validator nodes. A targeted social engineering campaign compromised them. The fifth key belonged to the Axie DAO, and its compromise traced back to a November 2021 decision.

Sky Mavis asked the Axie DAO for temporary signing privileges during a period of heavy demand. The surge passed. The allowlist was never revoked. Four months later, the attacker used that forgotten permission to reach the five-of-nine threshold.

Six days passed before anyone noticed. A user reported being unable to withdraw 5,000 ETH on March 29. By then, the stolen funds were already moving through a laundering infrastructure that would take months to map.

The ledger that never forgets

Bitcoin's original design promised pseudonymity, not anonymity. Every transaction between every address is permanently recorded on a public blockchain. For investigators, this creates an evidentiary record far more detailed than anything available in traditional financial crime.

A bank fraud investigation might yield wire transfer records going back 90 days. Blockchain data covers every transaction an address has ever made, timestamped to the second, and it never expires.

Chainalysis, Elliptic, and CipherTrace built commercial products around this reality. Their core offering is a transaction graph enriched with attribution labels from years of exchange data requests, undercover purchases, and cluster analysis. When investigators opened the Ronin case, they fed the exploit address into that graph and watched it grow.

The on-chain trail

The Ronin exploit address began moving funds within hours. Analysts traced the flow in near real time as transactions hit the Ethereum network.

# EDUCATIONAL ILLUSTRATION — demonstrates the analytical methodology
# described in published blockchain forensics research.
# Transaction hashes and addresses are real, publicly visible on Etherscan.
 
# ETH withdrawal — internal transaction from bridge contract
Parent Tx:    0xc28fad5e8d5e0ce6a2eaf67b6687be5d58113e16be590824d6cfa1a94467d0b7
Block:        14442835
Value:        173,600 ETH
From:         Axie Infinity: Ronin Bridge
To:           0x098B716B8Aaf21512996dC57EB0615e2383E2f96 [Ronin Bridge Exploiter]
Note:         Visible in Etherscan "Internal Transactions" tab
 
# USDC withdrawal (8 blocks later)
Transaction:  0xed2c72ef1a552ddaec6dd1f5cddf0b59a8f37f82bdda5257d9c7c37db7bb9b08
Block:        14442843
Action:       Transfer 25,500,000 USDC
From:         Axie Infinity: Ronin Bridge
To:           0x098B716B8Aaf21512996dC57EB0615e2383E2f96 [Ronin Bridge Exploiter]

Etherscan page for the Ronin Bridge exploit address, labeled OFAC-Sanctioned and Blocked. The Internal Transactions tab shows the original 173,600 ETH withdrawal from Axie Infinity: Ronin Bridge. Source: Etherscan

All 25.5 million USDC had to be converted first. USDC is a regulated stablecoin issued by Circle, which can freeze tokens on law enforcement request. The attacker swapped the entire balance to roughly 8,563 ETH through 1inch and Uniswap within hours, before Circle could act.

Converted ETH was returned to the exploit address. From there, funds moved to approximately ten intermediate wallets in chunks of 25,000 ETH. The structuring was deliberate, designed to avoid triggering automated thresholds on receiving exchanges. The flow then split across four parallel channels.

Channel one converted ETH to Bitcoin through the renBTC cross-chain bridge. The renBTC protocol emits an on-chain event recording the corresponding Bitcoin destination address. Investigators extracted it from the event log and continued the trace on the Bitcoin blockchain.

A second channel routed funds into Tornado Cash. Smaller amounts moved directly to centralized exchange deposit addresses tied to KYC-verified accounts.

On-chain researcher BliteZero reconstructed a fourth channel. Approximately 6,249 ETH was deposited at FTX, Huobi, and Crypto.com, converted to Bitcoin, and sent to Blender.io. The US Treasury sanctioned Blender on May 6, 2022, specifically for processing Lazarus Group funds.

Most OFAC-published Blender sanction addresses were Ronin attacker deposits, BliteZero found. The total withdrawn through this route was approximately $20.5 million.

The USDC-to-ETH conversion within hours of the theft is the most time-critical step in the entire laundering chain. Circle can freeze USDC at any address with a single contract call. By converting 25.5 million USDC before Circle acted, the attacker eliminated the only asset in the haul that could have been frozen unilaterally.
RONIN BRIDGE EXPLOIT [0x098B716...]
│
├── USDC → ETH conversion (25.5M USDC → ~8,563 ETH via 1inch/Uniswap)
│
├── 0x4F47Bc49... [Intermediate 1]
│   ├── renBTC Bridge ──────────► Bitcoin: 1BvBMSE... [Lazarus BTC cluster]
│   │                                └──► Blender.io (439 BTC / $20.5M) [OFAC sanctioned May 2022]
│   └── Tornado Cash 100 ETH pool (×340 deposits)
│
├── 0xa9D1e08C... [Intermediate 2]
│   ├── Tornado Cash 100 ETH pool (×290 deposits)
│   └── Huobi deposit address ──► KYC record [flagged]
│
├── 0x7d6149ad... [Intermediate 3]
│   └── Tornado Cash 100 ETH pool (×410 deposits)
│
├── CEX withdrawals (6,249 ETH → BTC via FTX, Huobi, Crypto.com)
│   └── BTC → Blender.io (439 BTC / $20.5M)
│
└── [additional intermediate wallets]
    └── Binance deposit addresses ► KYC records [frozen, $5.8M seized]

Destination of laundered Ronin funds as of April 14, 2022. 18% of stolen funds had been laundered through exchanges and Tornado Cash. Source: Elliptic

Why Tornado Cash did not work at scale

Tornado Cash accepts ETH deposits and issues cryptographic notes redeemable from a pooled reserve. The mechanism severs the direct on-chain link between depositing and withdrawing addresses. For small, infrequent transactions, it works as designed.

The Ronin attackers needed to process 173,600 ETH. Tornado Cash's largest pool at the time accepted 100 ETH per deposit. Processing the full amount required over 1,700 separate deposit-withdraw cycles over several weeks. That volume created a statistical problem the protocol was not designed to handle.

Each deposit generates a cryptographic commitment in the contract's Merkle tree. Each withdrawal redeems a commitment using a zero-knowledge proof. The anonymity holds when many independent users deposit and withdraw simultaneously, creating a large anonymity set.

Lazarus Group was not sharing the pool with comparable traffic. Their deposit-withdrawal pattern was distinguishable at scale.

# EDUCATIONAL ILLUSTRATION — demonstrates the analytical methodology
# described in published blockchain forensics research.
# Event topic hashes are truncated placeholders.
# This is not production tooling.
 
import requests
from datetime import datetime
 
TORNADO_100ETH = "0xA160cdAB225685dA1d56aa342Ad8841c3b53f291"
 
def fetch_pool_events(contract, from_block, to_block, api_key):
    """Fetch Deposit and Withdrawal events from Tornado Cash pool.
    All event logs are public on Ethereum."""
    url = "https://api.etherscan.io/api"
    results = {}
    for event_type, topic in [
        ("deposits",    "0xa945e51eec50ab..."),
        ("withdrawals", "0xe9e508bad6d4c3...")
    ]:
        r = requests.get(url, params={
            "module": "logs", "action": "getLogs",
            "address": contract, "topic0": topic,
            "fromBlock": from_block, "toBlock": to_block,
            "apikey": api_key
        }).json()
        results[event_type] = r["result"]
    return results
 
def timing_correlation(events, window_hours=72):
    """
    For each withdrawal, find deposits within the preceding window.
    Scoring: shorter gap = higher suspicion.
    """
    deposits    = events["deposits"]
    withdrawals = events["withdrawals"]
    matches = []
 
    for w in withdrawals:
        w_time = datetime.utcfromtimestamp(int(w["timeStamp"], 16))
        w_addr = "0x" + w["topics"][1][-40:]
        candidates = []
 
        for d in deposits:
            d_time = datetime.utcfromtimestamp(int(d["timeStamp"], 16))
            d_addr = "0x" + d["topics"][1][-40:]
            delta_h = (w_time - d_time).total_seconds() / 3600
 
            if 0 < delta_h < window_hours:
                score = 100 / (delta_h + 0.5)
                candidates.append({
                    "depositor": d_addr,
                    "gap_hours": round(delta_h, 2),
                    "score":     round(score, 3)
                })
 
        if candidates:
            best = max(candidates, key=lambda x: x["score"])
            matches.append({
                "withdrawal_addr":  w_addr,
                "withdrawal_time":  w_time.isoformat(),
                "likely_depositor": best["depositor"],
                "gap_hours":        best["gap_hours"],
                "confidence_score": best["score"]
            })
    return matches

Researchers applied this analysis across all 1,700-plus cycles. The majority of withdrawals linked back to intermediate wallets connected to the exploit address. No single match was definitive. The aggregate pattern across hundreds of cycles produced attribution confidence that multiple independent teams confirmed.

OFAC sanctioned Tornado Cash in August 2022. The designation cited Lazarus Group's use of the mixer to launder over $455 million across multiple operations.

The exchange as a forensic trap

Major cryptocurrency exchanges verify user identity before allowing withdrawals. Binance, Kraken, and Coinbase maintain government-issued ID documents, selfies, proof of address, and login IP records for every verified account.

Those records are available through standard legal process. The FBI and IRS Criminal Investigation obtain exchange records through subpoena. International requests move through MLATs (Mutual Legal Assistance Treaties). Major exchanges typically respond within 30 to 90 days.

Approximately $5.8 million of the Ronin funds reached Binance accounts verified with real identity documents. Chainalysis reconstructed the transaction path connecting those accounts to the exploit address. The full laundering operation used over 12,000 distinct cryptocurrency addresses. Binance froze the accounts and provided records.

The documents belonged to stolen or purchased identities, not Lazarus operatives. The misdirection added complexity but did not break the attribution chain.

Pattern matching across a seven-year history

Blockchain intelligence firms have maintained Lazarus Group address clusters since at least 2016. Each confirmed operation extended the database with new addresses, routing patterns, and infrastructure choices matchable against future activity.

Address clustering is the foundational technique. The Common Input Ownership Heuristic (CIOH) treats all input addresses in a multi-input transaction as belonging to the same wallet. The change address heuristic identifies which output returns funds to the sender.

# EDUCATIONAL ILLUSTRATION — simplified implementation of the
# Common Input Ownership Heuristic (Meiklejohn et al., 2013).
# Production clustering tools handle edge cases not shown here.
 
def common_input_ownership(transactions):
    """
    If a transaction spends outputs from multiple addresses,
    all those addresses share a single controller.
    Foundation: Meiklejohn et al. (2013), "A Fistful of Bitcoins."
    """
    clusters = {}
    cluster_id = 0
 
    for tx in transactions:
        if len(tx["inputs"]) < 2:
            continue
 
        input_addrs = [inp["address"] for inp in tx["inputs"]]
        existing = set(clusters[a] for a in input_addrs if a in clusters)
 
        if not existing:
            for addr in input_addrs:
                clusters[addr] = cluster_id
            cluster_id += 1
        else:
            target = min(existing)
            for addr in input_addrs:
                clusters[addr] = target
            for addr in clusters:
                if clusters[addr] in existing:
                    clusters[addr] = target
 
    return clusters

Ronin transaction patterns matched existing Lazarus clusters across multiple dimensions. Transaction timing clustered within UTC+9 business hours, the time zone of Pyongyang.

The following distribution is reconstructed from patterns described in published Chainalysis and Elliptic analyses. The specific counts illustrate the documented UTC+9 clustering pattern, not exact figures from a single dataset.

# Transaction hour distribution (UTC) for Lazarus-attributed addresses
# Ronin operation, March-June 2022
 
Hour (UTC)  |  Tx Count  |  Activity
-----------   ----------   --------
00           |     3      |  .
01           |     2      |  .
02           |     1      |  .
03-07        |     0      |                  # UTC+9 midnight-dawn: silent
08           |    47      |  ████████████████  # UTC+9 09:00 work starts
09           |    61      |  ████████████████████
10           |    73      |  ████████████████████████
11           |    68      |  ██████████████████████
12           |    12      |  ████                    # UTC+9 lunch dip
13           |    64      |  █████████████████████
14           |    71      |  ████████████████████████
15           |    59      |  ███████████████████
16           |    48      |  ████████████████        # UTC+9 end of day
17           |     9      |  ███
18-19        |   2-4      |  .

Three prior Lazarus operations showed the same fingerprint. Bithumb ($30 million, June 2018), Liquid Global (2021), and Harmony Horizon Bridge (June 2022) all displayed identical UTC+9 clustering. The algorithm splitting large amounts into smaller pre-exchange tranches followed identical proportions across all four operations. The renBTC bridge appeared in both Liquid Global and Ronin.

Seventeen behavioral indicators matched across the Ronin operation. Cross-referenced against seven years of Lazarus history, they produced the FBI's attribution confidence.

Malware forensics provided independent confirmation. The spear-phishing campaign deploying Lazarus-attributed backdoors was analyzed by a separate team using separate methods. Both reached the same conclusion.

The indictment as an investigative tool

In February 2021, the US DOJ unsealed a 33-page indictment charging three North Korean nationals. Jon Chang Hyok, Kim Il, and Park Jin Hyok are officers of North Korea's Reconnaissance General Bureau, the intelligence directorate overseeing Lazarus Group.

None will be arrested. North Korea does not extradite. The indictment was not written for a courtroom but for publication.

The indictment details Lazarus infrastructure, cryptocurrency addresses, and fund movement patterns from seven years of investigation. Publication authorizes OFAC sanctions on associated addresses and signals to foreign governments what to block. It creates a public record future prosecutors can cite without reopening classified sources.

On April 14, 2022, the FBI attributed the theft to Lazarus Group. That was 22 days after the exploit and 16 days after public disclosure. OFAC simultaneously added the exploit address to its sanctions list. Speed like that was possible because investigators matched a new operation against thirteen years of accumulated documentation.

Attribution in 22 days for a $625 million theft across 12,000 addresses is the return on thirteen years of accumulated Lazarus Group documentation. Each prior operation (Bangladesh Bank 2016, Bithumb June 2018, Liquid Global 2021) expanded the cluster database that the next investigation inherited. The speed is not a breakthrough but compound interest on institutional memory.

The structural problem that state resources cannot solve

North Korea's cryptocurrency operations are technically competent. Layered mixers, cross-chain bridges, structured amounts, and multi-jurisdiction routing are all designed to slow attribution.

The problem is economic, not technical. North Korea steals cryptocurrency to fund weapons programs. Cryptocurrency in a cold wallet does not fund anything. Converting it to usable revenue requires selling through a point connected to the global financial system.

Every such point is a regulated entity. North Korea has tried OTC brokers in China, front companies in multiple jurisdictions, and P2P platforms avoiding KYC. The UN Panel of Experts documented each channel across annual reports.

In April 2022, the exploit wallet still held 138,433 ETH. That was roughly $402 million, according to Merkle Science. By mid-2023, after months of gradual laundering, a large portion remained in addresses known to investigators. Any exchange accepting those funds would face OFAC sanctions.

The remaining funds moved slowly. Each OTC conversion yielded less than market rate. Each transaction risked identification.

Execution was precise. But the conversion pipeline could not process $625 million without generating the footprint that blockchain tools were built to detect.

What the record shows

Lazarus Group stole an estimated $3 billion in cryptocurrency between 2017 and 2023. The UN Panel of Experts assessed that stolen cryptocurrency directly funded North Korea's WMD and ballistic missile programs.

DPRK-attributed cryptocurrency theft by year. Cumulative total reached $6.75 billion by end of 2025. Source: Chainalysis 2026 Crypto Crime Report

Chainalysis claims over $10 billion in seizure assistance since 2015. No independent verification of that figure is available. The company's tools are now standard across FBI, IRS-CI, Europol, and agencies in over 40 countries.

Lazarus Group continues to operate. Blockchain analysts attributed the Radiant Capital bridge hack (October 2024) within weeks, following the same methodology. The investigation is not a sprint against a single theft. It is an ongoing mapping exercise against an adversary whose every financial move is recorded in a public database.

Table of Contents
  1. Оглавление генерируется автоматически при просмотре

Have a story? Become a contributor.

We work with independent researchers and cybersecurity professionals. Send us a tip or submit your article for editorial review.

Questions on the topic

How did investigators trace the Ronin bridge hack to North Korea?
Blockchain forensics firms traced the $625 million Ronin exploit to Lazarus Group using on-chain graph analysis, exchange KYC records, timing correlation against UTC+9 business hours, and seven years of attributed address clusters.