
Phân tích nguyên nhân vụ Nomad bị đánh cắp 190 triệu USD: Một vụ huyết án do nâng cấp gây ra
Tuyển chọn TechFlowTuyển chọn TechFlow

Phân tích nguyên nhân vụ Nomad bị đánh cắp 190 triệu USD: Một vụ huyết án do nâng cấp gây ra
Trong một lần nâng cấp, hợp đồng đã đánh dấu 0x00 là gốc hợp lệ, điều này dẫn đến hệ thống Nomad tràn ngập thông tin giả mạo. Kẻ tấn công đã lợi dụng điểm này để sao chép/dán các địa chỉ giao dịch hợp lệ, và trong sự hỗn loạn đó, tài sản trên cầu nối liên chuỗi đã nhanh chóng bị rút cạn.
Viết bởi: Samczsun
Dịch bởi: TechFlow intern
TL;DR
Trong một lần nâng cấp, hợp đồng đã đánh dấu 0x00 là gốc hợp lệ, điều này dẫn đến việc Nomad tràn ngập thông tin giả mạo. Kẻ tấn công đã lợi dụng điểm yếu này để sao chép/dán lại địa chỉ giao dịch hợp lệ và trong sự hỗn loạn đó, tài sản trên cầu nối liên chuỗi đã nhanh chóng bị rút cạn.
Sự cố vừa xảy ra với Nomad là một trong những vụ tấn công hỗn loạn nhất mà tôi từng thấy trong Web3, khiến hơn 150 triệu USD bị rút sạch. Điều này thực sự đã xảy ra như thế nào? Nguyên nhân cốt lõi là gì? Hãy để tôi đưa bạn đi tìm hiểu chuyện gì đã diễn ra đằng sau hậu trường.

Tất cả bắt đầu khi CIA Officer chia sẻ bài đăng của Spreek trên kênh Telegram ETHSecurity, dù lúc đó tôi chưa biết chuyện gì đang xảy ra, nhưng lượng lớn tài sản rời khỏi cầu nối rõ ràng là một dấu hiệu không lành.

Ý nghĩ đầu tiên của tôi là có lỗi cấu hình về số thập phân của token. Dù sao thì, theo góc nhìn của tôi, dường như cây cầu đang chạy chương trình khuyến mãi kiểu "gửi 0,01 WBTC, nhận lại 100 WBTC".

Ban đầu tôi không tin, nhưng sau khi tự tay kiểm tra một vài giao dịch trên mạng Moonbeam, tôi xác nhận được đúng là như vậy: chỉ có 0,01 WBTC được gửi từ Moonbeam, nhưng vì lý do nào đó lại nhận được 100 WBTC trên Ethereum.

Hơn nữa, giao dịch cầu nối WBTC này thực tế không trải qua bước Chứng minh (Prove), mà chỉ trực tiếp gọi hàm `Process`. Có thể nói, việc xử lý một thông điệp mà không cần bằng chứng là cực kỳ nghiêm trọng.

Trong tình huống này có hai khả năng: hoặc bước chứng minh được gửi riêng ở khối trước đó, hoặc hợp đồng Replica có vấn đề cực lớn. Tuy nhiên, hoàn toàn không có dấu hiệu nào cho thấy gần đây có thông điệp nào được chứng minh riêng biệt.

Vì vậy, chỉ còn lại một khả năng duy nhất —— hợp đồng Replica có lỗi nghiêm trọng, nhưng tại sao lại như vậy? Qua việc quét nhanh mã nguồn, tôi phát hiện thông điệp được gửi phải thuộc về gốc được chấp nhận, nếu không, phép kiểm tra ở dòng 185 sẽ thất bại.

May mắn thay, có một cách đơn giản để kiểm tra giả thiết này. Tôi biết rằng gốc của thông điệp chưa được chứng minh là 0x00, vì messages[_messageHash] cho thấy trạng thái chưa khởi tạo, việc tôi cần làm là kiểm tra xem hợp đồng có chấp nhận gốc này hay không.

Hợp đồng đã chấp nhận....

Hóa ra, trong quá trình nâng cấp, đội ngũ Nomad đã khởi tạo gốc đáng tin cậy là 0x00. Nói thẳng ra, việc dùng giá trị 0 làm giá trị khởi tạo là một thói quen phổ biến. Tiếc thay, trong trường hợp này, nó gây ra một tác động phụ nhỏ nhưng nghiêm trọng: tự động xác thực mọi thông điệp.


Đây chính là lý do sự việc trở nên hỗn loạn đến vậy —— bạn không cần biết Solidity hay Merkle Trees hay bất cứ thứ gì tương tự. Việc bạn cần làm chỉ là tìm một giao dịch hợp lệ, tìm/thay thế địa chỉ người gửi bằng địa chỉ của bạn, rồi phát lại giao dịch đó.
Chào mừng tham gia cộng đồng chính thức TechFlow
Nhóm Telegram:https://t.me/TechFlowDaily
Tài khoản Twitter chính thức:https://x.com/TechFlowPost
Tài khoản Twitter tiếng Anh:https://x.com/BlockFlow_News














