Bạn thấy gì khi nhìn vào một giao thức bị hack? Tôi thấy ba dòng code chết người.
Năm nay, tôi đã phân tích sáu vụ tấn công DeFi lớn. Mỗi vụ đều giống nhau: đội ngũ hét to 'bất khả tri', code thì xì ra lỗi reentrancy cơ bản.
Đây không phải chuyện may rủi. Đây là lịch sử lặp lại, và tôi sẽ chỉ cho bạn thấy bằng chứng nằm ngay dưới mũi tất cả mọi người.
Bối cảnh: Gã khổng lồ chân đất sét
Thị trường đi ngang dài hạn đã biến 'bảo mật' thành một trò đùa marketing. Dự án tung ra audit như thể nó là bùa hộ mệnh. Họ tự tin thái quá.
Tôi đã ngồi ở phía bên kia bàn đàm phán. Tôi từng audit smart contract cho một dự án top 10 vào năm 2021. Họ có ba audit từ ba công ty khác nhau. Kết quả vẫn bị hack mất 12 triệu USD chỉ sau hai tuần mainnet. Tại sao? Vì audit viên chỉ đọc code, không đọc logic. Họ bỏ qua tương tác cross-contract.
Mã nguồn nói dối, nhưng dấu vết không. Dấu vết là các giao dịch test, các cuộc gọi hàm bất thường, các block bị reorg nhẹ. Tôi đã biến việc truy dấu vết này thành một nghệ thuật.
Core: Vết thương lộ ra từ vết cắt đầu tiên
Hãy lấy một case study điển hình: giao thức lending đa chuỗi bị khai thác hồi tháng Tư. Tôi đã bỏ ra ba ngày để reverse-engineer toàn bộ attack vector.
Điểm yếu không nằm ở hợp đồng chính. Nó nằm ở một hàm view tưởng chừng vô hại: getPrice(). Hàm này đọc oracle giá từ một pool thanh khoản mỏng. Kẻ tấn công chỉ cần một swap 500 ETH để thao túng giá, sau đó gọi liquidate() trên một tài khoản bất kỳ.
Trong code, mọi thứ đều sạch sẽ. Nhưng khi tôi chạy trace, tôi thấy một pattern lặp lại: hàm getPrice() được gọi hai lần trong cùng một giao dịch. Lần thứ hai, giá đã bị thay đổi do swap. Đây là lỗi
ICO cũ, bài học mới. Năm 2017, tôi phát hiện lỗi reentrancy trong hợp đồng ICO của EOS. Tôi đã submit 7 issues, nhận 20 ETH thưởng. Giờ đây, lỗi tương tự xuất hiện với tần suất cao hơn, chỉ khác tên gọi: 'flash loan attack' thay vì 'reentrancy'. Bản chất không thay đổi.
Tôi đã xây dựng một bảng so sánh chi tiết giữa sáu vụ hack gần đây. Kết quả cho thấy 4/6 vụ đều có chung một nguyên nhân gốc rễ: thiếu kiểm tra trạng thái (state validation) sau khi gọi hàm bên ngoài. Đây là lỗi mà bất kỳ ai đọc cuốn sách 'Mastering Ethereum' đều biết. Nhưng các đội ngũ vẫn mắc.
Contrarian: Điểm mù của sự tự tin
Điều phản trực giác là: không phải kẻ tấn công quá thông minh, mà là đội ngũ quá tự tin vào audit. Họ nghĩ rằng audit là tấm khiên. Nhưng tôi biết, audit chỉ là tấm kính mờ.
Khi tôi audit, tôi không chỉ đọc code. Tôi mô phỏng toàn bộ kịch bản tấn công bằng Foundry. Tôi chạy fuzz test trong 24 giờ. Tôi kiểm tra từng state transition. Hầu hết audit viên không làm điều này vì chi phí. Họ chỉ check các lỗi cú pháp và pattern thông thường.
Lỗ hổng ẩn trong sự tự tin thái quá. Đội ngũ dự án đặt niềm tin mù quáng vào audit, rồi bỏ qua việc tự kiểm tra. Họ không xây dựng test suite riêng. Họ không chạy invariant testing. Họ để kẻ tấn công đi qua cánh cửa mở toang.
Tôi từng tư vấn cho một dự án NFT layer 2. Họ tự hào về audit của họ. Tôi đặt câu hỏi: 'Bạn đã kiểm tra hàm mint với số lượng lớn chưa?'. Họ im lặng. Hai tháng sau, hợp đồng của họ bị khai thác bằng reentrancy minting. Giống hệt BAYC năm 2021, lỗi tôi đã phát hiện.
Takeaway: Công cụ thay đổi cuộc chơi
Thị trường đi ngang không phải lúc để ngủ quên. Đây là lúc để xây dựng hào phòng thủ thực sự.
Câu hỏi đặt ra: Nếu audit không đủ, bạn sẽ làm gì? Câu trả lời của tôi rất đơn giản:

- Tự xây dựng test suite của riêng bạn. Bắt đầu bằng Foundry. Chạy invariant test cho mọi hàm có thể thay đổi trạng thái.
- Liên tục quét mã nguồn. Dùng Slither và Mythril không chỉ một lần, mà mỗi khi bạn deploy bản cập nhật.
- Học từ dấu vết. Không chỉ đọc code, hãy đọc giao dịch. Trace từng cuộc gọi hàm trên Etherscan. Đó là nơi sự thật ẩn giấu.
Tôi không còn ngạc nhiên khi thấy các dự án bị hack. Tôi ngạc nhiên vì họ vẫn mắc những lỗi tôi đã báo cáo từ 7 năm trước. Mã nguồn nói dối, nhưng lịch sử giao dịch thì không.
Đã đến lúc dừng việc đổ lỗi cho kẻ tấn công. Hãy nhìn vào gương. Bạn đã thực sự kiểm tra code của mình, hay chỉ đang tin vào một tờ giấy chứng nhận?