Phân tích lỗ hổng DoS hợp đồng thông minh Rust: Duyệt vòng lặp, phụ thuộc giữa các hợp đồng và thiết kế quyền hạn

robot
Đang tạo bản tóm tắt

Phân tích lỗ hổng tấn công DoS trong hợp đồng thông minh Rust

Tấn công DoS ( từ chối dịch vụ ) có thể khiến hợp đồng thông minh không thể sử dụng bình thường trong một khoảng thời gian hoặc thậm chí vĩnh viễn. Nguyên nhân chính bao gồm:

  1. Trong logic hợp đồng có tồn tại khuyết điểm. Ví dụ, một số hàm public không xem xét độ phức tạp tính toán, dẫn đến tiêu thụ Gas vượt quá giới hạn.

  2. Sự phụ thuộc vào trạng thái thực thi của hợp đồng bên ngoài khi gọi chéo hợp đồng. Việc thực thi hợp đồng bên ngoài không đáng tin cậy có thể dẫn đến việc hợp đồng này bị chặn.

  3. Yếu tố con người, như việc chủ hợp đồng mất khóa riêng, dẫn đến trạng thái hệ thống quan trọng không thể được cập nhật kịp thời.

Dưới đây là phân tích lỗ hổng tấn công DoS thông qua ví dụ cụ thể.

1. Duyệt vòng qua các cấu trúc dữ liệu lớn có thể được thay đổi từ bên ngoài

Dưới đây là một hợp đồng đơn giản để "chia thưởng" cho người dùng đã đăng ký:

gỉ #[near_bindgen] #[derive(BorshDeserialize, BorshSerialize)] pub struct Contract { pub registered: Vec\u003caccountid\u003e, pub accounts: UnorderedMap\u003caccountid, balance=""\u003e, }

pub fn register_account(&mut self) { nếu self.accounts.insert(&env::predecessor_account_id(), &0).is_some() { env::panic("Tài khoản đã được đăng ký".to_string().as_bytes()); } else { self.registered.push(env::predecessor_account_id()); } log!("Tài khoản đã đăng ký {}", env::predecessor_account_id()); }

pub fn distribute_token(&mut self, amount: u128) { assert_eq!(env::predecessor_account_id(), DISTRIBUTOR, "ERR_NOT_ALLOWED");

cho cur_account trong self.registered.iter() {
    let balance = self.accounts.get(&cur_account).expect("ERR_GET");
    self.accounts.insert(\u0026cur_account, \u0026balance.checked_add(amount).expect("ERR_ADD"));
    log!("Cố gắng phân phối cho tài khoản {}", &cur_account);
    
    ext_ft_token::ft_transfer(
        cur_account.clone(),
        số lượng,
        &FTTOKEN,
        0,
        GAS_FOR_SINGLE_CALL
    );
}

}

Dữ liệu trạng thái hợp đồng này self.registered không bị giới hạn về kích thước, có thể bị người dùng độc hại thao túng khiến nó quá lớn. Dẫn đến việc thực thi distribute_token tiêu tốn Gas vượt quá giới hạn và thất bại.

Khuyến nghị chuyển sang chế độ rút tiền: Bên hợp đồng trước tiên ghi sổ, người dùng tự rút thưởng thông qua hàm withdraw. Hợp đồng chỉ cần duy trì số tiền thưởng của một người dùng duy nhất.

2. Sự phụ thuộc trạng thái giữa các hợp đồng dẫn đến việc chặn hợp đồng

Xem xét một hợp đồng "đấu giá":

gỉ #[near_bindgen] #[derive(BorshDeserialize, BorshSerialize)] pub struct Hợp đồng { pub registered: Vec, pub bid_price: UnorderedMap\u003caccountid,balance\u003e, pub current_leader: AccountId, pub highest_bid: u128, pub refund: bool }

PromiseOrValue { assert!(amount > self.highest_bid);

nếu self.current_leader == DEFAULT_ACCOUNT {
    self.current_leader = sender_id;
    self.highest_bid = amount;
} else {
    ext_ft_token::account_exist(
        self.current_leader.clone)(,
        &FTTOKEN,
        0,
        env::prepaid_gas() - GAS_FOR_SINGLE_CALL * 4,
    (.then)ext_self::account_resolve)
        sender_id,
        số lượng,
        &env::current_account_id((,
        0,
        GAS_FOR_SINGLE_CALL * 3,
     ();
}

log!)
    "current_leader: {} highest_bid: {}", 
    self.current_leader,
    self.highest_bid
);

PromiseOrValue::Value(0)

}

Hợp đồng này phụ thuộc vào việc trả lại token của người đấu giá cao nhất trước đó để có thể cập nhật giá thầu cao nhất mới. Nếu tài khoản của người trước đó đã bị hủy, giá thầu mới sẽ bị chặn.

Giải pháp: Cân nhắc các trường hợp gọi bên ngoài có thể thất bại, tăng cường xử lý lỗi. Có thể tạm giữ các token không thể hoàn trả, sau đó người dùng tự lấy lại.

3. Chủ sở hữu mất chìa khóa riêng

Một số chức năng hợp đồng được thiết lập chỉ có owner mới có thể thực hiện, dùng để thay đổi các biến hệ thống quan trọng. Nếu owner không thể thực hiện chức năng ( như mất khóa riêng ), những chức năng này sẽ không thể sử dụng, có thể dẫn đến việc hợp đồng bị tê liệt.

Giải pháp:

  • Thiết lập nhiều chủ sở hữu để cùng quản lý
  • Áp dụng giải pháp đa ký thay thế cho quyền kiểm soát owner đơn lẻ
  • Thực hiện cơ chế quản trị phi tập trung

Thiết kế quyền hạn hợp lý và cơ chế quản trị có thể giảm thiểu hiệu quả rủi ro điểm lỗi đơn, tăng cường độ bền của hợp đồng.

</accountid,balance></accountid,>

Xem bản gốc
Trang này có thể chứa nội dung của bên thứ ba, được cung cấp chỉ nhằm mục đích thông tin (không phải là tuyên bố/bảo đảm) và không được coi là sự chứng thực cho quan điểm của Gate hoặc là lời khuyên về tài chính hoặc chuyên môn. Xem Tuyên bố từ chối trách nhiệm để biết chi tiết.
  • Phần thưởng
  • 7
  • Đăng lại
  • Chia sẻ
Bình luận
0/400
MEVHunterLuckyvip
· 07-17 08:49
Duyệt vòng lặp gọi siêu nguy hiểm, trước đây đã bị lỗ.
Xem bản gốcTrả lời0
BridgeNomadvip
· 07-15 16:21
đã thấy chính xác vector tấn công này trên bsc tháng trước... khi nào các dev mới học được smh
Xem bản gốcTrả lời0
BearMarketSurvivorvip
· 07-14 20:00
Cựu binh chiến trường mã quay trở lại, tổn thất chiến tranh nhờ có quản lý vị thế.
Xem bản gốcTrả lời0
BearMarketSurvivorvip
· 07-14 19:57
Khóa riêng bị mất thì phải làm sao đây, lo lắng không chịu nổi.
Xem bản gốcTrả lời0
FlatlineTradervip
· 07-14 19:56
Thiết kế hợp đồng kém như vậy mà vẫn phát hành.
Xem bản gốcTrả lời0
MetaverseVagrantvip
· 07-14 19:54
Lỗi này có mức độ nguy hiểm hơi cao.
Xem bản gốcTrả lời0
HodlVeteranvip
· 07-14 19:34
Một cái nhìn là biết ngay là cựu chiến binh tiền điện tử đã gặp tai nạn sau những bài học đau thương...
Xem bản gốcTrả lời0
Giao dịch tiền điện tử mọi lúc mọi nơi
qrCode
Quét để tải xuống ứng dụng Gate
Cộng đồng
Tiếng Việt
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)