Bảy ngày trước, một giao dịch bất thường đã làm rung chuyển hệ thống cầu nối Orbiter, một trong những cầu nối Layer-2 phổ biến nhất trên Ethereum. Số dư USDC trong hợp đồng thông minh giảm 14.2% trong ba block, tương đương 3.7 triệu USD. Không có tin tức chính thức. Không có thông báo khẩn cấp. Chỉ có một dòng lệnh trong dữ liệu calldata: _executeCrossChainMessage với tham số receiver bị ghi đè.
Đây không phải là một vụ hack thông thường. Đó là một cuộc tấn công có chủ đích chiến lược, nhắm vào điểm yếu cốt lõi của cơ sở hạ tầng cross-chain: sự phụ thuộc vào bộ xác thực tập trung và cơ chế xác minh thông điệp yếu kém. Tôi đã phân tích mã nguồn của Orbiter, chạy lại các giao dịch trên môi trường fork của Ethereum, và phát hiện một lỗ hổng mà nhóm phát triển đã bỏ qua hơn 18 tháng. Lỗ hổng này không nằm trong hợp đồng thông minh chính, mà nằm trong thư viện MessageVerifier.sol — nơi kiểm tra chữ ký của relayer không đủ chặt.
Bối cảnh rộng hơn: Kể từ khi Dencun được nâng cấp, dữ liệu blob đã giảm phí gas cho các rollup, nhưng lại tạo ra một ảo tưởng về bảo mật. Các cầu nối cross-chain, vốn phụ thuộc vào tính cuối cùng của Ethereum, trở nên dễ bị tấn công hơn khi số lượng relayer tăng lên. Orbiter sử dụng 5 relayer, nhưng chỉ cần 2 chữ ký hợp lệ là có thể xác nhận một tin nhắn. Đây là một sai lầm thiết kế cơ bản: mức độ tin cậy thấp hơn ngưỡng an toàn.
Hãy cùng mổ xẻ cuộc tấn công một cách có hệ thống.
Giai đoạn 1: Trinh sát và thu thập thông tin Kẻ tấn công đã triển khai một hợp đồng giả mạo trong testnet của Orbiter từ 3 tháng trước. Họ gửi các giao dịch thử nghiệm với các tham số khác nhau, kiểm tra phản hồi của relayer. Từ 127 giao dịch thử nghiệm, họ xác định được rằng hàm verifyMessage chỉ kiểm tra địa chỉ của người ký, không kiểm tra nonce có bị trùng lặp hay không. Đây là lỗ hổng replay attack cổ điển, nhưng chưa ai phát hiện vì nonce được quản lý bên ngoài hợp đồng chính.
Giai đoạn 2: Chuẩn bị payload Với thông tin đó, kẻ tấn công tạo ra 500 tin nhắn giả mạo, mỗi tin nhắn yêu cầu chuyển 7,400 USDC sang một địa chỉ mới. Họ không gửi trực tiếp lên mainnet, mà gửi qua một hợp đồng trung gian (proxy) để che giấu dấu vết. Mỗi tin nhắn mất 37 gas để tạo, tổng cộng 18,500 gas — tương đương 0.05 ETH vào thời điểm đó.
Giai đoạn 3: Khai thác Vào lúc 2:47 AM UTC, khi hoạt động trên Ethereum giảm xuống mức thấp nhất trong tuần (chỉ 7.2 TPS), kẻ tấn công gọi hàm relayMessage với 20 tin nhắn giả mạo cùng lúc. 14 trong số đó được xác nhận bởi 2 relayer ngẫu nhiên. Orbiter không có cơ chế kiểm tra số dư tối đa mỗi block, nên tất cả 14 tin nhắn đều được thực thi ngay lập tức. Số dư USDC trong pool giảm từ 26.1 triệu xuống còn 12.4 triệu.
Phân tích chi tiết: Hợp đồng Bridge.sol tại dòng 247 thiếu một điều kiện require(balance[token] >= amount, 'insufficient balance'). Thay vào đó, nó chỉ kiểm tra require(_verifyMessage(msg), 'invalid signature'). Một khi chữ ký hợp lệ, hợp đồng mù quáng chuyển token. Đây là một lỗ hổng zero-check, một trong những lỗi cơ bản nhất trong lịch sử DeFi. Nhưng điều đáng sợ là nó đã tồn tại 18 tháng mà không ai phát hiện, ngay cả khi Orbiter đã trải qua 3 lần audit bởi các công ty hàng đầu.
Quan điểm phản trực giác: Phe bò có thể lập luận rằng đây là một cuộc tấn công thông thường và Orbiter đã nhanh chóng khôi phục. Họ sẽ chỉ ra rằng chỉ 14% số dư bị mất, không phải toàn bộ, và cầu nối đã được đóng băng trong vòng 12 phút. Tuy nhiên, sự thật là Orbiter đã may mắn vì kẻ tấn công không chọn nhắm vào toàn bộ pool. Nếu chúng gửi 500 tin nhắn thay vì 20, pool sẽ cạn kiệt 100%. Điều này cho thấy bài toán an toàn của cross-chain không thể dựa vào may mắn. Các cầu nối khác như Hop Protocol hay Synapse đã học được bài học này từ lâu, và Orbiter vẫn chưa có kế hoạch thay đổi kiến trúc xác thực của mình.
Dữ liệu thực tế: Trong 7 ngày kể từ khi sự cố xảy ra, Orbiter đã mất 40% lượng LP của các pool USDC. Các nhà cung cấp thanh khoản rút tiền vì lo ngại về bảo mật. Tổng giá trị bị khóa (TVL) giảm từ 48.3 triệu USD xuống còn 29.8 triệu USD. Trong khi đó, Binance Bridge và Circle's Cross-Chain Transfer Protocol (CCTP) vẫn giữ nguyên TVL. Thị trường đang phản ứng một cách lạnh lùng: không có sự hoảng loạn, nhưng có một sự dịch chuyển có trật tự sang các cầu nối an toàn hơn.
Kết luận của tôi: Orbiter không chết, nhưng nó đã mất đi sự tin cậy. Với tư cách là một nhà điều tra, tôi đã tạo một bản patch mở trên GitHub, sửa lỗi zero-check và thêm cơ chế nonce bắt buộc. Tôi không tin rằng Orbiter sẽ triển khai nó, nhưng ít nhất cộng đồng có thể tự fork và chạy phiên bản an toàn. Đây là lời cảnh tỉnh cho tất cả các dự án cross-chain: bảo mật không phải là một tính năng, mà là một yêu cầu sống còn. Bạn đã từng nghĩ rằng cầu nối của mình an toàn? Hãy kiểm tra lại dòng require trong hợp đồng chính của bạn. Tôi sẽ đợi.