Cum să scapi de contractele inteligente de atacurile de reintrare? PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Cum să scapi de contractele inteligente de atacurile de reintrare?

Timp de citit: 6 minute

Dacă ne uităm mai atent la cele mai mari hack-uri criptografice și la cifrele uimitoare pierdute pentru ei, acestea s-ar fi înrădăcinat adânc din defectele de codare.

O astfel de apariție comună a vulnerabilității de securitate este atacul Reintrency. Cu toate acestea, efectul distructiv cauzat din cauza reintrării greșite poate să nu sune la fel de simplu ca lansarea atacului în sine.

În ciuda faptului că este o problemă familiară și bine mediatizată, apariția bug-ului Reintrancy în contractele inteligente este întotdeauna inevitabilă. 

Cât de des a fost exploatată vulnerabilitatea Reentrancy de către hackeri în ultimii ani? Cum functioneazã? Cum să împiedicați contractele inteligente să nu piardă fonduri din cauza erorilor de reintrare? Găsiți răspunsuri la aceste întrebări în acest blog.

Așa că, în scurt timp, să trecem la curent cu cele mai mari atacuri de reintrare din memorie. 

Unele dintre cele mai infame hack-uri de reintrare în timp real 

Atacurile de reintrare care au provocat cele mai devastatoare efecte asupra proiectelor au ajuns să facă unul dintre aceste două sau chiar ambele. 

  • Scurgeți complet eterul din contractele inteligente
  • Hackerii se strecoară în codul contractului inteligent

Putem observa acum câteva cazuri de atacuri de reintrare și impactul lor. 

Iunie 2016: Atacul DAO – 3.54 milioane sau 150 milioane USD Ether

aprilie 2020: Hack Uniswap/Lendf.Me – 25 milioane USD

May 2021: Hackul BurgerSwap – 7.2 milioane de dolari

2021 august: Hack CREAM FINANCE – 18.8 milioane USD

martie 2022: Ola Finance – 3.6 milioane USD

2022 iulie: Protocolul OMNI – 1.43 milioane USD

Este clar că atacurile de reintrare nu s-au demodat niciodată. Să obținem informații profunde despre el în pasajele următoare. 

Prezentare generală asupra atacului de reintrare

De la numele „Reintrare”, care implică „Reintrare din nou și din nou”. Atacul de reintrare implică două contracte: contractul cu victimă și contractul atacatorului. 

Contractul atacatorului exploatează vulnerabilitatea de reintrare din contractul cu victimă. Folosește funcția de retragere pentru a o realiza. 

Contractul atacatorului apelează la funcția de retragere pentru a scurge fondurile din contractul cu victimă, efectuând apeluri repetate înainte ca soldul din contractul cu victimă să fie actualizat. Contractul cu victima va verifica soldul, va trimite fonduri și va actualiza soldul. 

Dar în intervalul de timp de trimitere a fondurilor și de actualizare a soldului din contract, contractul atacatorului face apelul continuu pentru retragerea fondurilor. În consecință, soldul nu este actualizat în contractul cu victimă până când contractul atacatorului epuizează toate fondurile.

Severitatea și costul exploatării reintrării alarmează nevoia extremă de performanță audituri de contracte inteligente pentru a exclude posibilitatea de a trece cu vederea astfel de erori. 

Vedere ilustrativă a atacului de reintrare

Să înțelegem conceptul de atac de reintrare din ilustrația simplificată de mai jos. 

Iată două contracte: Contractul vulnerabil și contractul Hacker

Contractul de hacker face apel la retragerea din contractul vulnerabil. La primirea apelului, contractul vulnerabil verifică fondurile din contractul hackerului și apoi transferă fondurile hackerului. 

Hackerul primește fondurile și implementează funcția de rezervă, care apelează din nou în contractul vulnerabil chiar înainte ca soldul să fie actualizat în contractul vulnerabil. Repetând astfel aceeași operațiune, hackerul retrage complet fondurile din contractul vulnerabil. 

Cum să scapi de contractele inteligente de atacurile de reintrare?

Caracteristici ale funcției de rezervă utilizate de atacator 

  • Sunt apelabile din exterior. Adică nu pot fi chemați din contractul în care sunt scrise
  • Funcție fără nume
  • Funcția de rezervă nu include logica arbitrară în ea
  • Fallback-ul este declanșat atunci când ETH este trimis la contractul inteligent care îl include și nu este declarată nicio funcție receive().

Analizarea atacului de reintrare din punct de vedere tehnic 

Să luăm un exemplu de contract și să înțelegem cum are loc atacul de reintrare.

Contract rău intenționat

contract Attack {
    DepositFunds public depositFunds;

    constructor(address _depositFundsAddress) {
        depositFunds = DepositFunds(_depositFundsAddress);
    }

    // Fallback is called when DepositFunds sends Ether to this contract.
    fallback() external payable {
        if (address(depositFunds).balance >= 1 ether) {
            depositFunds.withdraw();
        }
    }

    function attack() external payable {
        require(msg.value >= 1 ether);
        depositFunds.deposit{value: 1 ether}();
        depositFunds.withdraw();
    }


}

Acesta este contractul atacatorului în care atacatorul depune 2ETH. Atacatorul apelează funcția de retragere din contractul vulnerabil. Odată ce fondurile sunt primite din contractul vulnerabil, se declanșează funcția de rezervă. 

Fallback-ul execută apoi funcția de retragere și drenează fondul din contractul vulnerabil. Acest ciclu continuă până când fondurile sunt complet epuizate din contractul vulnerabil.

Contract Vulnerabil

contract DepositFunds {
    mapping(address => uint) public balances;

    function deposit() public payable {
        balances[msg.sender] += msg.value;
    }

    function withdraw() public {
        uint bal = balances[msg.sender];
        require(bal > 0);

        (bool sent, ) = msg.sender.call{value: bal}("");
        require(sent, "Failed to send Ether");

        balances[msg.sender] = 0;
    }


}

Contractul vulnerabil are 30ETH. Aici, funcția withdraw() trimite atacatorului suma solicitată. Deoarece soldul nu este actualizat, jetoanele sunt transferate atacatorului în mod repetat. 

Tipuri de atacuri de reintrare

  • Reintrare cu o singură funcție 
function withdraw() external {
   uint256 amount = balances[msg.sender];
   require(msg.sender.call.value(amount)());
   balances[msg.sender] = 0;
}

msg.sender.call.value(amount)() transferă fondurile după care funcția de rezervă a contractului atacatorului apelează din nou la retragere() înainte ca soldurile[msg.sender] = 0 să fie actualizate.

  • Reintrare cu funcții încrucișate
function transfer(address to, uint amount) external {
   if (balances[msg.sender] >= amount) {
       balances[to] += amount;
       balances[msg.sender] -= amount;
   }
}
function withdraw() external {
   uint256 amount = balances[msg.sender];
   require(msg.sender.call.value(amount)());
   balances[msg.sender] = 0;
}

Reintrarea cu funcții încrucișate este mult mai complex de identificat. Diferența aici este că funcția de rezervă apelează transferul, spre deosebire de reintrarea cu o singură funcție, unde apelează retragere.

Prevenirea atacurilor de reintrare

Verificări-Efecte-Model de interacțiuni: Modelul verificări-efecte-interacțiuni ajută la structurarea funcțiilor. 

Programul ar trebui să fie codificat într-un mod care să verifice mai întâi condițiile. Odată trecute verificările, efectele asupra stării contractelor ar trebui rezolvate, după care pot fi apelate funcțiile externe. 

function withdraw() external {
   uint256 amount = balances[msg.sender];
   balances[msg.sender] = 0;
   require(msg.sender.call.value(amount)());
}

Codul rescris aici urmează modelul verificări-efecte-interacțiuni. Aici soldul este adus la zero înainte de a efectua un apel extern. 

Utilizarea modificatorului

Modificatorul noReentrant aplicat funcției asigură că nu există apeluri reintrante. 

contract ReEntrancyGuard {
    bool internal locked;

    modifier noReentrant() {
        require(!locked, "No re-entrancy");
        locked = true;
        _;
        locked = false;
    }
}

La sfarsit

Cel mai eficient pas este de a face audituri de contracte inteligente de la o firmă de securitate lider precum QuillAudits, în care auditorii urmăresc îndeaproape structura codului și verifică modul în care funcționează funcția de rezervă. Pe baza tiparelor studiate, se dau recomandări de restructurare a codului dacă pare să existe comportamente vulnerabile

Siguranța fondurilor este asigurată chiar înainte de a deveni victima oricăror pierderi. 

Întrebări frecvente

Ce este un atac de reintrare?

Un atac de reintrare are loc atunci când o funcție din contractul vulnerabil apelează la un contract care nu are încredere. Contractul care nu are încredere va fi contractul atacatorului care efectuează apeluri recursive către contractul vulnerabil până când fondurile vor fi scurse complet. 

Ce este un reintrat?

Actul de a reintroduce înseamnă întreruperea execuției codului și inițierea din nou a procesului, care este cunoscut și sub numele de reintrare.

Ce este un gardian de reintrare?

Garda de reintrare folosește un modificator care împiedică apelarea în mod repetat a funcției. Citiți blogul de mai sus pentru a găsi exemplul pentru paza de reintrare.

Care sunt unele dintre atacurile asupra contractelor inteligente?

Contractele inteligente sunt expuse la numeroase vulnerabilități, cum ar fi reintrarea, dependența de marcaj temporal, depășirile aritmetice, atacurile DoS și așa mai departe. Prin urmare, auditarea este o necesitate pentru a se asigura că nu există erori care să prăbușească logica contractului.

69 Vizualizări

Timestamp-ul:

Mai mult de la Quillhash