Análisis del ataque de denegación de servicio en contratos inteligentes
ataque de denegación de servicio(DoS)puede provocar que los contratos inteligentes no estén disponibles de manera normal durante un período de tiempo o incluso de forma permanente. Las principales razones incluyen:
Defectos en la lógica del contrato, como la complejidad computacional excesiva de ciertas funciones públicas, que provocan que el consumo de Gas supere el límite.
La dependencia del estado de ejecución de contratos externos al realizar llamadas entre contratos puede bloquear el funcionamiento normal de este contrato debido a la posible falta de fiabilidad en la ejecución del contrato externo.
Factores humanos, como la pérdida de la clave privada por parte del propietario del contrato que impide la llamada a ciertas funciones privilegiadas.
A continuación, se analizarán las vulnerabilidades de ataque de denegación de servicio en los contratos inteligentes a través de ejemplos específicos.
1. Recorrido cíclico de estructuras de datos grandes que pueden ser modificadas externamente
A continuación se muestra un contrato simple para "repartir dividendos" a los usuarios registrados:
pub fn register_account(&mut self) {
if self.accounts.insert(\u0026env::predecessor_account_id(), \u00260).is_some() {
env::panic('La cuenta ya está registrada'.to_string().as_bytes());
}else{
self.registered.push(env::predecessor_account_id());
}
log!('Cuenta registrada{}',env::predecessor_account_id());
}
pub fn distribute_token(&mut self, amount: u128) {
assert_eq!(env::predecessor_account_id(),DISTRIBUTOR,'ERR_NOT_ALLOWED');
para cur_account en 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!('Intentar distribuir a la cuenta{}',&cur_account);
ext_ft_token::ft_transfer(
cur_account.clone(),
cantidad,
&FTTOKEN,
0,
GAS_FOR_SINGLE_CALL
);
}
}
El problema del contrato es que el tamaño del array self.registered no tiene límites, lo que puede ser manipulado por usuarios maliciosos para que sea demasiado grande, lo que provoca que el consumo de Gas durante la ejecución de la función distribute_token supere el límite.
Recomendación de soluciones:
Limitar la longitud máxima del arreglo self.registered
Adoptar el modo de retiro, no distribuir recompensas de forma proactiva, sino permitir que los usuarios llamen a la función de retiro por sí mismos.
2. La dependencia del estado entre contratos provoca el bloqueo del contrato
El problema del contrato es que, si la cuenta del usuario con la oferta más alta actual es cancelada en el contrato de tokens externos, una nueva oferta más alta no podrá devolver los tokens del anterior, lo que llevará a un bloqueo en el proceso de subasta.
Solución:
Considerar la posibilidad de que las llamadas a contratos externos puedan fallar e implementar un manejo de errores razonable. Por ejemplo, almacenar temporalmente los tokens no reembolsables en el contrato y permitir que los usuarios los extraigan posteriormente.
3. Pérdida de la clave privada del propietario del contrato
En los contratos inteligentes a menudo existen funciones privilegiadas que solo pueden ser ejecutadas por el propietario. Si se pierde la clave privada del propietario, estas funciones no podrán ser llamadas, lo que puede llevar a que el contrato no funcione correctamente.
Método de solución:
Configurar múltiples propietarios de contratos para la gobernanza conjunta
Adoptar un mecanismo de múltiples firmas en lugar del control de permisos de un único propietario
Implementar un plan de gobernanza de contratos descentralizados
</accountid,balance><accountid,>
Ver originales
Esta página puede contener contenido de terceros, que se proporciona únicamente con fines informativos (sin garantías ni declaraciones) y no debe considerarse como un respaldo por parte de Gate a las opiniones expresadas ni como asesoramiento financiero o profesional. Consulte el Descargo de responsabilidad para obtener más detalles.
15 me gusta
Recompensa
15
7
Compartir
Comentar
0/400
consensus_whisperer
· hace23h
¿A quién te refieres con un contrato que es tanto inexperto como amante del juego?
Ver originalesResponder0
RumbleValidator
· 07-30 19:13
Una vez más, se observa una vulnerabilidad de bucle infinito simple; la prueba de estrés de los nodos debe llegar al límite antes de que se realice el dump del contrato.
Ver originalesResponder0
GasGuzzler
· 07-30 19:12
¡Experto en disuadir tarifas de GAS! ¡Explosión directa!
Ver originalesResponder0
BtcDailyResearcher
· 07-30 19:10
Otro más ha sido estafado por DoS, me muero de risa.
Ver originalesResponder0
SignatureDenied
· 07-30 19:05
¿Otra vez atacado? ¿Quién se atreve a guardar la Llave privada a la ligera?
Ver originalesResponder0
DefiOldTrickster
· 07-30 19:02
El viejo blanco jugó en el mercado bajista y se convirtió en el maestro, pero fue bloqueado por un contrato debido a una llave privada perdida. ¡Qué fragilidad!
Ver originalesResponder0
RuntimeError
· 07-30 18:53
¿Hmm? ¿El contrato puede morir porque se pierde la Llave privada? Realmente es urgente.
Profundidad del análisis de las vulnerabilidades de ataque DoS en contratos inteligentes y estrategias de prevención
Análisis del ataque de denegación de servicio en contratos inteligentes
ataque de denegación de servicio(DoS)puede provocar que los contratos inteligentes no estén disponibles de manera normal durante un período de tiempo o incluso de forma permanente. Las principales razones incluyen:
Defectos en la lógica del contrato, como la complejidad computacional excesiva de ciertas funciones públicas, que provocan que el consumo de Gas supere el límite.
La dependencia del estado de ejecución de contratos externos al realizar llamadas entre contratos puede bloquear el funcionamiento normal de este contrato debido a la posible falta de fiabilidad en la ejecución del contrato externo.
Factores humanos, como la pérdida de la clave privada por parte del propietario del contrato que impide la llamada a ciertas funciones privilegiadas.
A continuación, se analizarán las vulnerabilidades de ataque de denegación de servicio en los contratos inteligentes a través de ejemplos específicos.
1. Recorrido cíclico de estructuras de datos grandes que pueden ser modificadas externamente
A continuación se muestra un contrato simple para "repartir dividendos" a los usuarios registrados:
óxido #[near_bindgen] #[derive(BorshDeserialize, BorshSerialize)] pub struct Contract { pub registered: Vec, pub accounts: UnorderedMap\u003caccountid, balance=""\u003e, }
pub fn register_account(&mut self) { if self.accounts.insert(\u0026env::predecessor_account_id(), \u00260).is_some() { env::panic('La cuenta ya está registrada'.to_string().as_bytes()); }else{ self.registered.push(env::predecessor_account_id()); } log!('Cuenta registrada{}',env::predecessor_account_id()); }
pub fn distribute_token(&mut self, amount: u128) { assert_eq!(env::predecessor_account_id(),DISTRIBUTOR,'ERR_NOT_ALLOWED'); para cur_account en 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!('Intentar distribuir a la cuenta{}',&cur_account); ext_ft_token::ft_transfer( cur_account.clone(), cantidad, &FTTOKEN, 0, GAS_FOR_SINGLE_CALL ); } }
El problema del contrato es que el tamaño del array self.registered no tiene límites, lo que puede ser manipulado por usuarios maliciosos para que sea demasiado grande, lo que provoca que el consumo de Gas durante la ejecución de la función distribute_token supere el límite.
Recomendación de soluciones:
2. La dependencia del estado entre contratos provoca el bloqueo del contrato
Considera un contrato de "subasta":
óxido #[near_bindgen] #[derive(BorshDeserialize, BorshSerialize)] pub struct Contract { pub registrado: Vec, pub bid_price: UnorderedMap\u003caccountid,balance\u003e, pub current_leader: AccountId, pub highest_bid: u128, pub reembolso: bool }
PromiseOrValue { assert!(cantidad > self.highest_bid); if 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::gas_prepagado() - GAS_PARA_LLAMADA_UNICA * 4, (.then)ext_self::account_resolve) sender_id, cantidad, &env::current_account_id((, 0, GAS_FOR_SINGLE_CALL * 3, (); } log!) 'líder_actual: {} oferta_más_alta: {}', self.current_leader, self.highest_bid ); PromiseOrValue::Value(0) }
#( pub fn account_resolve)\u0026mut 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)(, cantidad, &FTTOKEN, 0, GAS_FOR_SINGLE_CALL * 2, (; log!)'Volver Ahora'); } }; }
El problema del contrato es que, si la cuenta del usuario con la oferta más alta actual es cancelada en el contrato de tokens externos, una nueva oferta más alta no podrá devolver los tokens del anterior, lo que llevará a un bloqueo en el proceso de subasta.
Solución:
Considerar la posibilidad de que las llamadas a contratos externos puedan fallar e implementar un manejo de errores razonable. Por ejemplo, almacenar temporalmente los tokens no reembolsables en el contrato y permitir que los usuarios los extraigan posteriormente.
3. Pérdida de la clave privada del propietario del contrato
En los contratos inteligentes a menudo existen funciones privilegiadas que solo pueden ser ejecutadas por el propietario. Si se pierde la clave privada del propietario, estas funciones no podrán ser llamadas, lo que puede llevar a que el contrato no funcione correctamente.
Método de solución: