Phân tích tấn công từ chối dịch vụ trong hợp đồng thông minh
tấn công từ chối dịch vụ(DoS)có thể dẫn đế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:
Các khiếm khuyết trong logic hợp đồng, chẳng hạn như độ phức tạp tính toán của một số hàm công khai quá cao, dẫn đến việc tiêu tốn Gas vượt quá giới hạn.
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 hợp đồng chéo, việc thực thi hợp đồng bên ngoài không đáng tin cậy có thể chặn hoạt động bình thường của hợp đồng này.
Yếu tố con người, như việc chủ hợp đồng mất khóa riêng dẫn đến một số chức năng đặc quyền không thể gọi.
Dưới đây là phân tích lỗ hổng tấn công từ chối dịch vụ trong hợp đồng thông minh thông qua ví dụ cụ thể.
1. Duyệt qua cấu trúc dữ liệu lớn có thể được chỉnh sửa từ bên ngoài
Dưới đây là một hợp đồng đơn giản để "chia lợi nhuận" cho người dùng đã đăng ký:
gỉ
#[near_bindgen]
#[derive(BorshDeserialize, BorshSerialize)]
pub struct Hợp đồng {
pub registered: Vec\u003caccountid\u003e,
pub accounts: UnorderedMap\u003caccountid, balance=""\u003e,
}
pub fn distribute_token(&mut self, amount: u128) {
assert_eq!(env::predecessor_account_id(),DISTRIBUTOR,'ERR_NOT_ALLOWED');
for cur_account in self.registered.iter(){
let balance = self.accounts.get(&cur_account).expect('ERR_GET');
self.accounts.insert(&cur_account,&balance.checked_add(amount).expect('ERR_ADD'));
log!('Tìm cách 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
);
}
}
Vấn đề của hợp đồng này là kích thước của mảng self.registered không có giới hạn, có thể bị người dùng ác ý thao túng để trở nên quá lớn, dẫn đến việc hàm distribute_token thực thi tiêu tốn Gas vượt quá giới hạn.
Giải pháp đề xuất:
giới hạn độ dài tối đa của mảng self.registered
Áp dụng chế độ rút tiền, không chủ động duyệt phân phát thưởng, mà để người dùng tự gọi hàm rút tiền.
2. Sự phụ thuộc trạng thái giữa các hợp đồng dẫn đến việc hợp đồng bị chặn
Vấn đề của hợp đồng này là nếu tài khoản của người dùng có giá thầu cao nhất hiện tại bị hủy trong hợp đồng mã thông báo bên ngoài, giá thầu mới cao hơn sẽ không thể hoàn lại mã thông báo của người trước đó, dẫn đến quá trình đấu giá bị tắc nghẽn.
Giải pháp:
Xem xét khả năng gọi hợp đồng bên ngoài có thể thất bại, thực hiện xử lý lỗi hợp lý. Ví dụ, tạm giữ token không thể hoàn lại trong hợp đồng, sau đó cho phép người dùng tự mình rút.
3. Mất khóa riêng của chủ hợp đồng
Trong hợp đồng thông minh thường có những hàm đặc quyền chỉ có chủ sở hữu mới có thể thực thi. Nếu chìa khóa riêng của chủ sở hữu bị mất, những hàm này sẽ không thể được gọi, có thể dẫn đến việc hợp đồng không thể hoạt động bình thường.
Giải pháp:
Thiết lập nhiều chủ hợp đồng để cùng quản lý
Sử dụng cơ chế đa chữ ký thay thế cho quyền kiểm soát của chủ sở hữu đơn lẻ
Thực hiện giải pháp quản trị hợp đồng phi tập trung
</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.
15 thích
Phần thưởng
15
7
Chia sẻ
Bình luận
0/400
consensus_whisperer
· 07-31 14:18
Hợp đồng vừa tệ vừa thích chơi, bạn nói ai vậy?
Xem bản gốcTrả lời0
RumbleValidator
· 07-30 19:13
Lại thấy lỗ hổng vòng lặp chết đơn giản, trước khi hợp đồng dump, cần phải kiểm tra độ chịu tải của Nút đến mức tối đa.
Xem bản gốcTrả lời0
GasGuzzler
· 07-30 19:12
GAS phí khuyên rút lui! Nổ trực tiếp
Xem bản gốcTrả lời0
BtcDailyResearcher
· 07-30 19:10
Lại có người bị DoS lừa rồi, cười chết mất.
Xem bản gốcTrả lời0
SignatureDenied
· 07-30 19:05
Lại bị tấn công à? Ai còn dám lưu trữ khóa riêng một cách bừa bãi chứ?
Xem bản gốcTrả lời0
DefiOldTrickster
· 07-30 19:02
Lão Bạch Thị trường Bear chơi bời nên bị một cái khóa hợp đồng do mất Khóa riêng.
Xem bản gốcTrả lời0
RuntimeError
· 07-30 18:53
Ừ? Hợp đồng vẫn có thể bị hỏng vì mất khóa riêng à? Thật sự gấp gáp quá.
Độ sâu phân tích lỗ hổng tấn công DoS trong hợp đồng thông minh và các chiến lược phòng ngừa
Phân tích tấn công từ chối dịch vụ trong hợp đồng thông minh
tấn công từ chối dịch vụ(DoS)có thể dẫn đế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:
Các khiếm khuyết trong logic hợp đồng, chẳng hạn như độ phức tạp tính toán của một số hàm công khai quá cao, dẫn đến việc tiêu tốn Gas vượt quá giới hạn.
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 hợp đồng chéo, việc thực thi hợp đồng bên ngoài không đáng tin cậy có thể chặn hoạt động bình thường của hợp đồng này.
Yếu tố con người, như việc chủ hợp đồng mất khóa riêng dẫn đến một số chức năng đặc quyền không thể gọi.
Dưới đây là phân tích lỗ hổng tấn công từ chối dịch vụ trong hợp đồng thông minh thông qua ví dụ cụ thể.
1. Duyệt qua cấu trúc dữ liệu lớn có thể được chỉnh sửa từ bên ngoài
Dưới đây là một hợp đồng đơn giản để "chia lợi nhuận" cho người dùng đã đăng ký:
gỉ #[near_bindgen] #[derive(BorshDeserialize, BorshSerialize)] pub struct Hợp đồng { 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!('Đã đăng ký tài khoản{}',env::predecessor_account_id()); }
pub fn distribute_token(&mut self, amount: u128) { assert_eq!(env::predecessor_account_id(),DISTRIBUTOR,'ERR_NOT_ALLOWED'); for cur_account in self.registered.iter(){ let balance = self.accounts.get(&cur_account).expect('ERR_GET'); self.accounts.insert(&cur_account,&balance.checked_add(amount).expect('ERR_ADD')); log!('Tìm cách 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 ); } }
Vấn đề của hợp đồng này là kích thước của mảng self.registered không có giới hạn, có thể bị người dùng ác ý thao túng để trở nên quá lớn, dẫn đến việc hàm distribute_token thực thi tiêu tốn Gas vượt quá giới hạn.
Giải pháp đề xuất:
2. Sự phụ thuộc trạng thái giữa các hợp đồng dẫn đến việc hợp đồng bị chặn
Xem xét một hợp đồng "đấu giá":
gỉ #[near_bindgen] #[derive(BorshDeserialize, BorshSerialize)] pub struct Hợp đồng { pub registered: Vec\u003caccountid\u003e, 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) }
#( pub fn account_resolve)&mut self,sender_id: AccountId,amount: u128[private] { match env::promise_result(0) { PromiseResult::NotReady => unreachable!(), PromiseResult::Successful(_) => { ext_ft_token::ft_transfer( self.current_leader.clone)(, self.highest_bid, &FTTOKEN, 0, GAS_FOR_SINGLE_CALL * 2, (; self.current_leader = sender_id; self.highest_bid = amount; } PromiseResult::Failed => { ext_ft_token::ft_transfer) sender_id.clone)(, số lượng, &FTTOKEN, 0, GAS_FOR_SINGLE_CALL * 2, (; log!)'Tro về ngay bây giờ'); } }; }
Vấn đề của hợp đồng này là nếu tài khoản của người dùng có giá thầu cao nhất hiện tại bị hủy trong hợp đồng mã thông báo bên ngoài, giá thầu mới cao hơn sẽ không thể hoàn lại mã thông báo của người trước đó, dẫn đến quá trình đấu giá bị tắc nghẽn.
Giải pháp:
Xem xét khả năng gọi hợp đồng bên ngoài có thể thất bại, thực hiện xử lý lỗi hợp lý. Ví dụ, tạm giữ token không thể hoàn lại trong hợp đồng, sau đó cho phép người dùng tự mình rút.
3. Mất khóa riêng của chủ hợp đồng
Trong hợp đồng thông minh thường có những hàm đặc quyền chỉ có chủ sở hữu mới có thể thực thi. Nếu chìa khóa riêng của chủ sở hữu bị mất, những hàm này sẽ không thể được gọi, có thể dẫn đến việc hợp đồng không thể hoạt động bình thường.
Giải pháp: