Contracts
Name | Address |
Bybit Cold Wallet (Safe Multisig) | |
Malicious Implementation | |
Malicious Contract used to update implementation |
Tx
Name | Tx Hash |
Attacker: Deploy malicious contract which is used to update safe’s proxy implementation contract | |
Attacker: Execute tx to modify safe’s proxy implementation | |
Attacker: Transfer assets from Bybit cold wallet | 0x25800d105db4f21908d646a7a3db849343737c5fba0bc5701f782bf0e75217c9
0xb61413c495fdad6114a7aa863a00b2e3c28945979a10885b12b30316ea9f072c
0xbcf316f5835362b7f1586215173cc8b294f5499c60c029a3de6318bf25ca7b20
0xa284a1bc4c7e0379c924c73fcea1067068635507254b03ebbbd3f4e222c1fae0
0x847b8403e8a4816a4de1e63db321705cdb6f998fb01ab58f653b863fda988647 |
Safe Multisig Architecture
One Safe wallet consists of two contracts:
- Proxy
- Proxy contract stores the implementation contract’s address in slot 0.
- Proxy contract delegates all tx to implementation contract
- This design can reuse implementation contract during Safe wallet deployment which can save gas.
- Implementation
- Handle tx sent by Safe proxy contract
- Checks signatures are correct according to multisig setting
- Execute tx
- call
- delegatecall
Attack
Attacker constructs a transaction and gets signatures of the Bybit safe wallet’s owners. Then attacker executes the tx.
In this tx:
- it instructs the safe wallet to call
0x96221423681A6d52E184D440a8eFCEbB105C7242
, which has the logic to update slot 0.
- The
operation
is set as1
, which means the logic contract usesdelegatecall
opcode to call0x96221423681A6d52E184D440a8eFCEbB105C7242
so that0x96221423681A6d52E184D440a8eFCEbB105C7242
has the ability to modify proxy contract’s storage
ㅤ | Name | Type | Data |
0 | to | address | |
1 | value | uint256 | 0 |
2 | data | bytes | 0xa9059cbb000000000000000000000000bdd077f651ebe7f7b3ce16fe5f2b025be29695160000000000000000000000000000000000000000000000000000000000000000 |
3 | operation | uint8 | 1 |
4 | safeTxGas | uint256 | 45746 |
5 | baseGas | uint256 | 0 |
6 | gasPrice | uint256 | 0 |
7 | gasToken | address | |
8 | refundReceiver | address | |
9 | signatures | bytes | 0xd0afef78a52fd504479dc2af3dc401334762cbd05609c7ac18db9ec5abf4a07a5cc09fc86efd3489707b89b0c729faed616459189cb50084f208d03b201b001f1f0f62ad358d6b319d3c1221d44456080068fe02ae5b1a39b4afb1e6721ca7f9903ac523a801533f265231cd35fc2dfddc3bd9a9563b51315cf9d5ff23dc6d2c221fdf9e4b878877a8dbeee951a4a31ddbf1d3b71e127d5eda44b4730030114baba52e06dd23da37cd2a07a6e84f9950db867374a0f77558f42adf4409bfd569673c1f |
Executor.sol
safe-global
Code of malicious contract 0x96221423681A6d52E184D440a8eFCEbB105C7242
It defins a
transfer
function with same interface as that of standard ERC20. This may cause Safe’s UI to display the tx as a normal erc20 transfer tx.But in fact it update the slot 0 to parameter
to
which is 0xbdd077f651ebe7f7b3ce16fe5f2b025be2969516
.After this tx has been executed, the safe wallet’s implementation become
0xbdd077f651ebe7f7b3ce16fe5f2b025be2969516
, which allows hacker to transfer ether and erc20 from the contract.Question
- How did the attacker make the owners of the Bybit safe contract see the malicious multi-sig transaction that needed to be signed on the Safe UI?
Advice
- When sending tx using safe, it's better to check the content of the tx.
- Be very cautious with tx using operation
1
which has ability to upgrade the safe wallet to other malicious contract.