- vừa được xem lúc

PHÂN TÍCH KỸ THUẬT VÀ TÁI HIỆN VỤ HACK 20M $OP TRÊN OPTIMISTIC CHAIN

0 0 34

Người đăng: ChainZoom Security

Theo Viblo Asia

Vào ngày 26 tháng 5 vừa qua, 20 triệu $OP (trị giá 14 triệu USD theo giá trị tại thời điểm viết bài) đã bị hack. Vụ việc xảy ra trước cả khi token $OP được phát hành tới với người dùng 5 ngày sau đó. Bài viết sau đây cung cấp thông tin để mô phỏng lại chi tiết quá trình xảy ra vụ hack.

image.png

Về Optimism

Optimism là Layer 2 trên Ethereum cung cấp tốc độ giao dịch nhanh chóng và bảo mật tốt dựa trên cơ chế Optimistic Rollup. Là một trong những Layer 2 đứng đầu, Optimism có lượng TVL đạt ngưỡng cao nhất hơn 1 tỷ USD.

Sử dụng máy ảo EVM, Optimism cung cấp môi trường phát triển dapp giống với mạng chính Ethereum.

image.png

Cơ sở lý thuyết

Để hiểu rõ hơn về vụ hack, ta cần hiểu về quá trình deploy smart contract bởi một smart contract khác.

Khi contract A được deploy bởi contract B thì địa chỉ của contract A được tính dựa trên những tham số:

address_A = keccak256(address_B, nonce_B)

Theo công thức trên, address_A chỉ phụ thuộc vào 2 tham số address_B và nonce_B, trong đó nonce_B là số contract đã được deploy bởi B cộng thêm 1.

Nói cách khác, ta có thể xác định trước address của contract A bất kỳ được deploy bởi contract B dựa vào address của B và số thứ tự của contract A.

Ví dụ, ở đây ta có 2 contract như sau:

pragma solidity ^0.5.3; contract Instance {} contract Factory { mapping(uint256 => address) public nonceToAddress; uint256 public nonce; constructor() public { nonce = 1; } function createInstance() public { Instance newInstance = new Instance(); nonceToAddress[nonce] = address(newInstance); nonce++; }
}

trong đó, contract Instance sẽ được deploy bởi contract Factory.

Ta hoàn toàn có thể tính được trước address của Instance được deploy qua mỗi lần gọi đến hàm createInstance() của Factory:

// nonce = 1 await factory.connect(deployer).createInstance(); var nonce = 0x01; //The nonce must be a hex literal! var input_arr = [factory.address, nonce]; var rlp_encoded = rlp.encode(input_arr); var contract_address_long = keccak('keccak256').update(Buffer.from(rlp_encoded)).digest('hex'); var contract_address = '0x' + contract_address_long.substring(24); //Trim the first 24 characters. console.log('Instance contract_address with nonce 1: ' + contract_address); expect((await factory.nonceToAddress(1)).toLowerCase()).be.equal(contract_address);// The deployed instance address must be equal to the one we calculated

Chạy lệnh yarn test_create: link

Kết quả: image.png

Quá trình hack

Sự việc xảy ra do sự bất cẩn của Wintermute - một market maker partner với Optimism. Wintermute vay Optimism 20 triệu OP để tạo thanh khoản cho đồng token này.

Vụ hack bao gồm sự tham gia của 5 address chính, ta gọi ngắn gọn như sau:

  1. A(L1) và A(L2): Contract 0x4f3a120e72c76c22ae802d129f599bfdbc31cb81 trên Ethereum và Optimism Chain.
  1. B(L1) và B(L2): Contract ProxyFactory 0x76e2cfc1f5fa8f6a5b3fc4c8f4788f0116861f9b trên Ethereum và Optimism Chain.
  1. X(L2): Contract chứa logic tấn công của hacker

Để nhận token, Wintermute gửi address A cho Optimism Foundation.

Tuy nhiên, Wintermute chỉ mới sở hữu address này trên Ethereum Chain (L1) mà chưa deploy nó lên Optimisim Chain (L2). Họ nghĩ rằng nếu mình đã sở hữu địa chỉ này trên L1 thì có thể dễ dàng sở hữu nó trên L2, do cả hai cùng sử dụng máy ảo EVM.

May-26-2022 11:55:44 PM +UTC:

Optimism Foundation gửi test 1 OP đến address A(L2)

Transaction tại đây

May-27-2022 04:05:27 PM +UTC:

Optimism Foundation gửi tiếp 1,000,000 OP đến address A(L2)

Transaction tại đây

Rất có thể lúc này address A(L2) đã vào tầm ngắm của hacker

May-27-2022 04:59:21 PM +UTC:

Optimism Foundation gửi nốt 19,000,000 OP đến address A(L2)

Transaction tại đây

=> một khoản tiền trị giá 20M USD nằm trong 1 empty_address, chưa hề có logic nào được triển khai trên địa chỉ đó.

Hacker điều tra về address A(L1) trên Ethereum chain

Trên Ethereum Chain address A(L1) thực chất lại là 1 contract: image.png Hacker còn điều tra được thêm contract này lại được deploy bởi contract B(L1) tại transaction này

Tại address B(L2) trên Optimism Chain cũng là một contract ProxyFactory y hệt Ethereum Chain

Kết hợp với lý thuyết trình bày ở trên, hacker suy ra được cặp contract được tạo bởi B trên Ethereum và Optimism nếu cùng 1 nonce sẽ cho ra cùng địa chỉ.

Bước tiếp theo Hacker tìm số nonce đã tạo ra địa chỉ A(L1)

Bằng cách thay đổi giá trị nonce cho đến khi địa chỉ cho ra khớp với A, hacker tìm được nonce là 8884

const rlp = require('rlp');
const keccak = require('keccak'); const findNonce = () => { var factoryAddress = '0x76e2cfc1f5fa8f6a5b3fc4c8f4788f0116861f9b'; var target = '0x4f3a120e72c76c22ae802d129f599bfdbc31cb81'; var nonce = 1; while (true) { var input_arr = [factoryAddress, parseInt(nonce.toString(16), 16)]; var rlp_encoded = rlp.encode(input_arr); var contract_address_long = keccak('keccak256').update(Buffer.from(rlp_encoded)).digest('hex'); var contract_address = '0x' + contract_address_long.substring(24); if (contract_address == target) { console.log(nonce); console.log(contract_address); return; } nonce++; }
}; findNonce();

Kết quả: image.png

Hacker quay lại điều tra nonce của address B(L2) trên Optimism xem liệu nó đã vượt qua 8884 chưa.

image.png Thật may mắn cho hacker, nonce tại thời điểm đấy mới chỉ tầm 10, vẫn chưa vượt quá 8884

Bước tiếp theo, hacker chuẩn bị sẵn 2 logic:

  • replaying the deployment gọi liên tục đến hàm createProxy() của B(L2) để tăng nonce đến 8884
  • logic để rút OP Token khi đã deploy contract thành công lên address A(L2)

Hacker đã kết hợp 2 logic đấy trong contract X(L2)

Hacker tấn công và rút tiền:

Transaction replay deploy để chiếm quyền kiểm soát address A(L2) tại đây

Hacker khởi động tấn công tại address X(L2). Hắn gọi liên tục hàm createProxy() của B(L2) với tham số masterCopy chính bằng address X(L2)

Như vậy 20M OP trong contract A(L2) đã hoàn toàn thuộc về hacker, hắn đã rút ra khoảng 2M OP tại 2 transaction

Tái hiện trên local

Sử dụng repo này để test.

Để chạy test đỡ mất thời gian, chúng ta sẽ giả định targetAddress ứng với nonce = 15 chứ không cần đến 8884

Có 3 module:

Trong đó 2 modules ProxyFactory và OPTokenMock là có sẵn, Hacker chỉ cần code thêm Attack contract.

Phân tích code trong Attack contract, vì Hacker muốn kết hợp cả 2 logic replayDeploy và withdrawToken trong cùng 1 contract nên contract Attack sẽ hơi khó hiểu và có một số việc bị lặp lại:

  • Ở hàm constructor(), các tham số factory, target, token là cần thiết cho việc thực hiện replayDeploy
  • Ở hàm replayDeploy(), sẽ thực hiện vòng lặp createProxy cho đến khi tìm được targetAddress
  • Ở hàm initialize() cần phải khởi tạo lại token và khởi tạo thêm giá trị owner, do contract Attack sẽ chứa logic của contract Proxy vừa được deploy lên targetAddress.

Chạy lệnh yarn exploit: link

Kết quả trả về sẽ tương tự như sau: image.png``

Bình luận

Bài viết tương tự

- vừa được xem lúc

[Blockchain] Road to Bitcoin

. Chắc mọi người hẳn đã không còn xa lạ gì với anh chàng tỷ phú đã ném vỡ cửa kính ô tô nhà mình cùng với siêu năng lực điều khiển vật giá chỉ bằng lời nói, người đã đẩy định giá Bitcoin trên thị trường vượt ngưỡng 50K dolar/coin với những bài twitter để đời . .

0 0 61

- vừa được xem lúc

Khi Ethereum có chi phí giao dịch quá đắt đỏ - Tương lai cho layer2 ?

Với sự phát triển như vũ bão của Blockchain, ETH dường như đang quá tải và hệ quả là chi phí Gas đã lên đến 1000Gwei, phí để tạo những transaction phức tạp đã xấp xỉ 500$ . Và một giải pháp cứu cánh cho các sản phẩm Defi trên ETH chính là Layer2, và trong nhiệm vụ lần này Matic đang thể hiện khả năn

0 0 89

- vừa được xem lúc

Blockchain với Java - Tại sao không?

Cuộc cách mạng công nghiệp 4.0 ra đời kéo theo nhiều sự thay đổi và xu hướng mới được hình thành. Riêng đối với lĩnh vực CNTT cũng không nằm ngoài vùng ảnh hưởng mạnh mẽ. Chính làn sóng 4.

0 0 92

- vừa được xem lúc

Phân loại và tầm quan trọng của các node trong mạng blockchain

Trước khi đi vào phân loại và nêu rõ được tầm quan trọng của các node trọng mạng blockchain thì mình xin được trích dẫn khái niệm về blockchain từ Wikipedia như sau:. .

0 1 65

- vừa được xem lúc

Code Smart Contract bằng Assembly ?

Introduction. Hồi còn học trong ghế nhà trường bộ môn lập trình tốn nhiều não nhất của mình là code assembly. Nôm na thì bất cứ ngôn ngữ bậc cao nào như C , Go, Java,... được sinh ra để người dễ hiểu và dễ code , tuy nhiên chúng đều sẽ được compiled down xuống assembly một ngôn ngữ bậc thấp để máy h

0 0 58

- vừa được xem lúc

Dextool - Công cụ phân tích Decentralized Exchange tuyệt vời

. Trend Defi mặc dù đã bớt nhiệt nhưng những sản phẩm nổi bật của làn sóng này mang lại thì vẫn rất được người dùng ưa chuộng. Đặc biệt là các nền tảng Decentralized Exchange, tiêu biểu là Uniswap, SushiSwap, 1inch Exchange, FalconSwap,... Nhưng khi đã sử dụng các nền tảng DEx này mà không biết đến

0 0 106