Bitget follow-up: what SlowMist and Mandiant found, and why the security appliances were the story

Two independent investigations into the Bitget theft have now been published, and between them they answer the question our analysis of 25 September had to leave open [7]. The attacker did not break cryptography, did not take private keys and did not need to forge customer withdrawal requests. They compromised the third-party security products sitting inside Bitget’s trust boundary, used one of them to reach the production wallet job server, and then ran a purpose-built withdrawal tool that forged the exchange’s own risk-control parameters and invoked the withdrawal path directly [1][2].

The loss has also been revised upward, withdrawals have begun returning in phases, and some of the money has been frozen. This follow-up sets out what the two reports found, where they agree, what remains unanswered, and what the mechanics of this intrusion should change in your own environment.

Sources: SlowMist’s investigation progress report commissioned by Bitget, covering findings as of 29 September [1], and Mandiant’s incident response status report dated 28 September [2]. Bitget has published both, alongside its own updates on tracing, recovery and the phased restoration of withdrawals [3][4][5]. All times in the reports are UTC+8; UTC equivalents are given alongside.

What changed since the first week

ItemAs of 25 SeptemberNow
Attack pathUnknown. Bitget said it would not speculate and investigators were still determining which systems were compromisedTwo independent reports describe a chain through third-party security appliances A and B, a web shell and command-and-control on appliance B, lateral movement to the production wallet job server, and a custom withdrawal tool [1][2]
Loss figureApproximately $351.6 million, with the CEO later saying some funds had been recoveredApproximately $387.5 million confirmed to attacker-controlled addresses, a revision that adds assets on Zcash and TRON that the first estimate omitted, and does not reflect new transfers [4]
Assets and chainsETH, USDT, USDC, AVAX, BNB and gold-backed XAUt reported publiclyXRP, ETH, USDT, USDC, USDT0, XAUt, BNB, AVAX, TRX and ZEC, across Ethereum and several EVM networks, XRP Ledger, Zcash and TRON [4]
WithdrawalsSuspended platform-wideRestored in phases from 28 September: bitcoin first, then ETH networks, then USDT, then remaining tokens, fiat and P2P [5]
The vulnerabilityNot identifiedBitget states the underlying vulnerability has been identified and remediated, with withdrawal infrastructure re-validated before reopening [4][5]
AttributionThe CEO cited IP addresses matching VPN choices of a DPRK-linked group, with no published evidenceUnchanged. Neither the SlowMist nor the Mandiant report addresses attribution, so the claim remains a company statement rather than a finding [1][2]
RecoverySome funds reported recovered, amount undisclosedSome affected assets frozen through industry coordination, with a Recovery Bounty Program paying five per cent of frozen or recovered funds, channelled partly through Bybit’s LazarusBounty initiative [4]
The Bitget attack chain as reconstructed by SlowMist and Mandiant

Figure 1. The chain as the two reports describe it. The compromise began with a security product, not with the wallet system.

The chain, stage by stage

A zero-day in a security product, and a database password in an environment variable

SlowMist dates the earliest malicious activity in the available logs to 31 August. A service running on one of Product A’s nodes was affected by a zero-day vulnerability. The attacker ran a hidden script under the service process, used it to read the environment variable holding the database password, and connected to the database [1]. Similar hidden-script activity appeared on two further nodes on 23 and 25 September [1].

That finding carries two lessons that generalise well beyond this incident. The first is that a zero-day in a third-party security product is a supply-chain exposure: the victim cannot patch it, may not know it exists, and in this case the product sat inside the environment with enough privilege to be worth exploiting [1][2]. The second is the credential pattern. A database password living in an environment variable is readable by anything that can run code under that service, which turns a single foothold into database access without any further exploitation [1].

An internal identity, and a management platform that executes code by design

In the early hours of 25 September, the attacker reached Product B’s management platform using an internal employee’s identity. From 00:07 UTC+8 they made three consecutive attempts to inject system commands into the platform’s task parameters in order to write malicious files, then submitted code through the platform’s web execution endpoint, attempting to modify server configuration, write a communication relay file, and upload and assemble malicious program files in batches [1].

Mandiant’s report describes the same segment from the other end: unauthorised privileged access to third-party security appliances A and B, a web shell deployed on appliance B, and a command-and-control connection established from it [2]. Read the two together and the picture is of an appliance management plane being used as a delivery mechanism rather than as a target. A platform whose job is to run tasks across an estate is, by construction, a remote code execution engine for anyone who can reach it with sufficient rights.

The pivot to the wallet job server

From persistent access on appliance B, the attacker moved laterally to Bitget’s production wallet job server and deployed malicious packages there [2]. Mandiant summarises the shape of the intrusion as compromised network and security appliances being leveraged to distribute malicious packages and gain control of the wallet job server, and describes its own investigation as ongoing [2]. SlowMist states separately that work continues into how the attacker moved between the systems involved [1].

This is the step that should worry anyone running privileged infrastructure tooling. The wallet job server is the machine that executes the exchange’s own wallet operations. It already holds the authority to move funds. Nothing had to be escalated there; the attacker inherited the trust the system already had.

A withdrawal tool that forged the risk controls

The most specific finding in either report is the recovery of a highly customised withdrawal tool, rebuilt from files the attacker had deleted. The tool was tailored to the wallet system’s withdrawal logic: it forged risk-control parameters in its own code, constructed withdrawal requests and invoked the withdrawal process [1]. The host log shows the malicious program beginning to run and execute the theft at 01:49 UTC+8 on 25 September [1].

That is 42 minutes before the first on-chain transfer and before Bitget’s monitoring flagged anything. The tool did not need to defeat a cryptographic control, because the risk parameters it was supposed to be checked against were values it supplied itself. The control existed; the integrity of its inputs did not.

The drain, running alongside legitimate operations

On-chain verification shows the earliest transfer as 93 TRX reaching the attacker’s address at 02:31:00 UTC+8, which is 18:31 UTC on 24 September, the same moment Bitget’s security monitoring detected the incident [1][2][6]. Eleven seconds later the Ethereum receiving address took 0.84 ETH [1]. The compiled transfer records run to 05:23:11 UTC+8, a span of about two hours and 52 minutes, across multiple blockchains [1].

Mandiant adds the detail that matters most for detection design: the unauthorised transfers were executed alongside legitimate internal wallet operations on Ethereum until about 05:23 UTC+8, nearly three hours after detection [2]. A drain that hides inside normal treasury traffic cannot be caught by volume thresholds tuned to what normal looks like, because it is normal, plus an extra stream nobody reconciled.

Rewriting the record after the money left

The activity continued after the transfers began. The attacker tried to modify withdrawal records directly in the wallet database and to invoke withdrawal tasks on the local host. Logs show two fabricated BTC withdrawal orders entering processing and returning errors, and then the attacker reviewing logs, querying order status and trying again after 05:22 UTC+8 [1]. The wallet database and the withdrawal queue were part of the attack surface, not just the funds inside them.

Why the security appliances were the whole story

Where the attacker went and where the keys were

Figure 2. The apparent paradox of this incident: no key compromise, and a nine-figure loss.

The instinct on reading the first reports was to ask how $351.6 million, later $387.5 million, could leave a platform whose keys were never taken. The answer in both documents is that the keys were never the constraint. The compromised systems already had the authority to instruct the wallet environment, and the withdrawal tool simply spoke to it in its own language [1][2].

It also explains why the third-party products were targeted rather than the exchange’s own estate. Security and network appliances usually sit inside the perimeter with privileged access, remote management interfaces and an update cadence controlled by a vendor rather than by the customer. They are trusted by everything around them and monitored by fewer people than the servers they protect. This intrusion used exactly those properties.

What to instrument, and what to change

ControlHow this chain got past itWhat to do
Appliance and infrastructure tooling monitoringAppliance A and appliance B were compromised and used as the delivery platform, which means the actor was operating inside systems whose logs are often not collected at the same fidelity as servers [1][2]Collect authentication, configuration change, process execution and egress telemetry from security appliances and network tooling with the same priority as production servers, and alert on new web shells or unexpected outbound connections from them
Third-party and supply-chain riskThe entry point was a zero-day in a third-party product, and neither report names the vendors, so customers of those products cannot self-assess from the public record [1][2]Know which appliances hold privileged access and to what, demand disclosure and patch commitments in contracts, segment them so a compromise does not sit adjacent to production, and give their service accounts the least privilege that lets them function
Secret managementThe database password was read from an environment variable by a hidden script running under a service process [1]Move credentials out of process environments into a secrets manager, issue short-lived database credentials per service, and alert on database connections whose source host normally has no reason to query the wallet database
Code execution surfaces in management platformsProduct B’s web execution endpoint accepted attacker-submitted code, used after three command-injection attempts into task parameters [1]Treat any task or job parameter as untrusted input, restrict code submission to signed and reviewed artefacts, restrict who can reach these endpoints, and diff task parameter changes as a first-class alert
Withdrawal risk controlsThe custom tool forged risk-control parameters in its own code and invoked the withdrawal process, so the control ran on attacker-supplied values [1]Enforce limits and approvals outside the withdrawal service: hardware-backed signing, out-of-band confirmation for large transfers, per-address and velocity limits evaluated independently, and reconciliation of expected against on-chain movements in near real time
Wallet database integrityAfter transfers began, the actor attempted to modify withdrawal records directly in the database and push fabricated BTC orders [1]Protect withdrawal records with append-only logging, database-level change auditing and alerting, and detect order records that exist without a matching on-chain settlement
Detection timingThe tool executed from 01:49 UTC+8, the first transfer and the detection came at 02:31, and the drain continued for nearly three hours alongside legitimate operations [1][2]Reconcile continuously rather than periodically, treat custody operations as a monitored lane of their own, and rehearse the containment decision that freezes withdrawals while the money is still moving

The money, the freezing and the bounty

Bitget’s tracing update revises the confirmed figure to approximately $387.5 million transferred to attacker-controlled addresses, up from the initial $351.6 million estimate, and states plainly that the increase reflects a more complete accounting of the incident that adds affected assets on Zcash and TRON rather than further transfers [4]. It confirms affected assets across XRP, ETH, USDT, USDC, USDT0, XAUt, BNB, AVAX, TRX and ZEC on Ethereum and several EVM networks, XRP Ledger, Zcash and TRON [4]. Four primary receiving addresses have been published: an EVM address, an XRP Ledger address, a Zcash address and a TRON address [4].

Some affected assets have been frozen through coordination with exchanges, blockchain projects and security firms, and Bitget has launched a Recovery Bounty Program paying five per cent of successfully frozen funds and five per cent of successfully recovered funds to the person or entity whose voluntary action achieved it, with legal-process actions excluded, and with Bybit’s LazarusBounty initiative used as a core channel [4]. Live tracing data is published for security teams through a fund-tracing dashboard and an attacker-address API [4].

That bounty channel is worth noting precisely because it is an operational choice rather than a finding. Neither the SlowMist nor the Mandiant report mentions attribution at all [1][2]. Bitget’s decision to route recovery through an initiative built for Lazarus-linked theft is consistent with the chief executive’s earlier statement about IP addresses matching a DPRK group’s VPN choices, and it is not the same thing as evidence in the public record.

Withdrawals came back in phases

Date and time (UTC)AssetsNetworks
28 September, 08:00Bitcoin (BTC)Bitcoin
29 September, 08:00Ether (ETH)Ethereum, BSC, Arbitrum, Base, Optimism
30 September, 08:00Tether (USDT)Ethereum, BSC, Solana, Tron
2 October, 08:00Remaining tokens, fiat and P2PAll supported networks

Bitget states that the pause was a security measure and not a reflection of asset availability, that user balances were unaffected, that the Protection Fund covers the financial impact, and that the underlying vulnerability had been identified and remediated before the rollout began [5]. The same notice says the incident remained contained and that no further unauthorised transfers were possible [5].

What is still open

  • How the attacker moved between the systems involved, which SlowMist explicitly lists as continuing work [1].
  • The remaining scope questions in Mandiant’s engagement, which the report describes as ongoing [2].
  • The identity of the two third-party products, which neither public report names, leaving other customers of those products unable to assess their own exposure from these documents [1][2].
  • Any technical evidence behind the DPRK attribution, which these two reports do not address at all [1][2].
  • A recovered total, since freezing has begun but no aggregate figure has been published [4].

Sources

  1. SlowMist, “Bitget Security Incident Investigation Progress Update”, commissioned by Bitget, covering findings as of 29 September 2026. Primary source for the zero-day on security product A, the environment-variable database password, the internal identity and command injection on product B, the customised withdrawal tool and the on-chain transfer window. All times in the report are UTC+8. · https://github.com/slowmist/Knowledge-Base/blob/master/open-report-V2%2Fincident-response%2FSlowMist%20Investigation%20Progress%20Report%20-%20Bitget_en-us.pdf
  2. Mandiant, part of Google Cloud, “Bitget Incident Response Status Report” dated 28 September 2026, published via Bitget. Primary source for the privileged access to third-party security appliances A and B, the web shell and command-and-control on appliance B, the lateral movement to the production wallet job server, the loss range and the observation that transfers ran alongside legitimate wallet operations. · https://img.bgstatic.com/multiLang/events/MFR26-1029_Status_Update_Bitget_0930.pdf
  3. Bitget Support, “Update On Slowmist and Mandiant Report” (30 September 2026), confirming that both investigations identified the compromise of third-party security products as what enabled access to the wallet environment. · https://www.bitget.com/support/articles/12560603896305
  4. Bitget Support, “Bitget Security Latest Incident Update: Fund Tracing and Recovery Bounty Program” (25 September 2026), the revised $387.5 million figure, the confirmed assets and chains, the published attacker addresses, the freezing progress, the live tracing dashboard and the 5 per cent bounty terms. · https://www.bitget.com/support/articles/12560603896108
  5. Bitget Support, “Bitget to Resume Withdrawals in Phases” (26 September 2026), with the resumption schedule and the statement that the vulnerability was identified and remediated. · https://www.bitget.com/support/articles/12560603896110
  6. Bitget Support, “[SECURITY NOTICE] Bitget exchange hot wallets Incident, September 24, 2026”, the original notice recording detection at 18:31 UTC on 24 September 2026. · https://www.bitget.com/support/articles/12560603896024
  7. InfoSec Builder, “Bitget’s $351.6 million breach: the confirmed facts, the unproven claims, and what it means for exchange custody risk” (25 September 2026), our first analysis of the incident. · https://infosec-builder.com/bitgets-351-6-million-breach-the-confirmed-facts-the-unproven-claims-and-what-it-means-for-exchange-custody-risk/

The lesson that outlives the incident

Most exchange security commentary focuses on keys, and this incident is a useful corrective. The keys held. The cold wallets held. The signatures were legitimate. What failed was the integrity of the inputs to a control, and the privilege of the systems sitting inside the perimeter that were trusted to operate the wallet environment in the first place.

For anyone with privileged infrastructure in their estate, the practical test is uncomfortable but simple. Take the appliances, management planes and job runners that hold authority over your most sensitive systems, and ask three questions: do we collect their telemetry with the same fidelity as our production servers, do we know what each one is permitted to reach, and could a task submitted through their own interfaces move money or data if the submitter were hostile. In this incident the answer to the third question was yes, and it cost $387.5 million to find out.