Kuidas pääseda nutikate lepingute eest tagasituleku rünnakute eest? PlatoBlockchaini andmete luure. Vertikaalne otsing. Ai.

Kuidas pääseda nutikate lepingute eest tagasituleku rünnakute eest?

Lugemise aeg: 6 protokoll

Kui vaatleme lähemalt suurimaid krüptohäkke ja neile kaotatud silmi veetvaid kujusid, oleks need kodeerimisvigadest sügavalt juurdunud.

Üks selline levinud turvaaukude juhtum on Reentrancy rünnak. Valesti käsitletud naasmisest põhjustatud hävitav mõju ei pruugi aga kõlada nii lihtsalt kui rünnaku käivitamine ise.

Hoolimata sellest, et see on tuttav ja palju avalikustatud probleem, on Reentrancy vea ilmumine nutikatesse lepingutesse alati vältimatu. 

Kui sageli on häkkerid viimastel aastatel Reentrancy haavatavust ära kasutanud? Kuidas see töötab? Kuidas piirata nutikate lepingute raha kaotamist Reentrancy vigade tõttu? Leia vastused nendele küsimustele sellest blogist.

Nii et enne pika aja möödumist käsitleme kõige suuremaid taassisenemise rünnakuid mälus. 

Mõned kõige kurikuulsamad reaalajas sissetungimise häkid 

Taasastumise rünnakud, mis põhjustasid projektidele kõige laastavama mõju, lõppesid ühega neist kahest või isegi mõlemast. 

  • Tühjendage eeter nutikatest lepingutest täielikult
  • Häkkerid hiilivad nutika lepingu koodi juurde

Nüüd saame jälgida mõningaid Reentrancy rünnakute juhtumeid ja nende mõju. 

Juuni 2016: DAO rünnak – 3.54 miljonit või 150 miljonit dollarit eetrit

aprill 2020: Uniswap/Lendf.Me häkkimine – 25 miljonit dollarit

May 2021: BurgerSwapi häkkimine – 7.2 miljonit dollarit

2021. august: CREAM FINANCE häkkimine – 18.8 miljonit dollarit

Märts 2022: Ola Finance – 3.6 miljonit dollarit

Juuli 2022: OMNI protokoll – 1.43 miljonit dollarit

On täiesti selge, et Reentrancy rünnakud pole kunagi stiilist väljas läinud. Saame sellest järgmistest lõikudest sügava ülevaate. 

Reentrancy rünnaku ülevaade

Nagu nimest "Reentrancy", mis tähendab "taassisenemist ikka ja jälle". Reentancy rünnak hõlmab kahte lepingut: ohvri leping ja ründaja leping. 

Ründaja leping kasutab ära ohvrilepingus sisalduvat taassisenemise haavatavust. Selle saavutamiseks kasutab see tagasivõtmise funktsiooni. 

Ründaja leping kutsub väljamaksefunktsiooni, et tühjendada ohvrilepingust raha, tehes korduvaid kõnesid enne, kui ohvrilepingu saldot värskendatakse. Ohvrileping kontrollib saldot, saadab raha ja värskendab saldot. 

Kuid raha saatmise ja lepingu saldo värskendamise aja jooksul kutsub ründaja leping pidevalt üles raha välja võtma. Selle tulemusena ei uuendata ohvrilepingu saldot enne, kui ründaja leping on kõik rahalised vahendid ära kasutanud.

Taassisenemise ärakasutamise tõsidus ja hind hoiatavad esinemisvajaduse pärast arukad lepinguauditid et välistada võimalus sellistest vigadest mööda vaadata. 

Illustreeriv vaade Reentrancy Attackile

Mõelgem uuesti sisenemise rünnaku kontseptsioonile allolevalt lihtsustatud illustratsioonilt. 

Siin on kaks lepingut: haavatav leping ja häkkerite leping

Häkkerileping kutsub üles haavatavast lepingust taganema. Kõne saamisel kontrollib haavatav leping häkkerilepingus olevaid rahalisi vahendeid ja kannab seejärel raha häkkerile üle. 

Häkker saab raha ja rakendab varufunktsiooni, mis kutsub uuesti haavatavasse lepingusse isegi enne, kui haavatava lepingu saldot värskendatakse. Seega, korrates sama toimingut, võtab häkker haavatavast lepingust raha täielikult välja. 

Kuidas pääseda nutikate lepingute eest tagasituleku rünnakute eest?

Ründaja poolt kasutatava varufunktsiooni omadused 

  • Need on väliselt kutsutavad. St neile ei saa helistada lepingu seest, mis nad on kirjutatud
  • Nimetu funktsioon
  • Varufunktsioon ei sisalda selle sees suvalist loogikat
  • Tagatiskäivitub, kui ETH saadetakse seda ümbritsevale nutikale lepingule ja vastuvõtufunktsiooni () ei deklareerita.

Taassisenemise rünnaku analüüsimine tehnilisest vaatest 

Võtame näidislepingu ja mõistame, kuidas taastumisrünnak toimub.

Pahatahtlik leping

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();
    }


}

See on ründaja leping, mille kohaselt ründaja deponeerib 2ETH. Ründaja kutsub haavatava lepingu tagasivõtmise funktsiooni. Kui haavatavast lepingust on raha laekunud, käivitub varufunktsioon. 

Seejärel täidab varuosa tagasivõtmise funktsiooni ja tühjendab fondi haavatavast lepingust. See tsükkel kestab seni, kuni haavatava lepingu rahalised vahendid on täielikult ammendatud.

Haavatav leping

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;
    }


}

Haavataval lepingul on 30 ETH. Siin saadab funktsioon tagasi () ründajale nõutud summa. Kuna saldot ei uuendata, kantakse märgid ründajale korduvalt. 

Taassisenemise rünnakute tüübid

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

Funktsioon msg.sender.call.value(amount)() kannab raha üle, pärast mida ründaja lepingu varufunktsioon kutsub uuesti tagasi () enne saldode[msg.sender] = 0 värskendamist.

  • Funktsioonidevaheline taassisenemine
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;
}

Funktsioonidevahelist taassisenemist on palju keerulisem tuvastada. Erinevus seisneb selles, et varufunktsioon kutsub esile ülekande, erinevalt ühefunktsioonilise taassisenemise korral, kus see kutsub välja tagasivõtmise.

Reentrancy rünnakute ennetamine

Kontrollide-efektide-interaktsioonide muster: Kontrollide-mõjude-interaktsioonide muster aitab funktsioone struktureerida. 

Programm peaks olema kodeeritud viisil, mis kontrollib kõigepealt tingimusi. Pärast kontrolli läbimist peaks olema lahendatud mõju lepingute olekule, misjärel saab välja kutsuda välised funktsioonid. 

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

Siin ümberkirjutatud kood järgib kontrollide-mõjude-interaktsioonide mustrit. Siin nullitakse saldo enne väliskõne tegemist. 

Modifikaatori kasutamine

Funktsioonile rakendatud modifikaator noReentrant tagab, et reentrant-kõnesid ei esine. 

contract ReEntrancyGuard {
    bool internal locked;

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

Lõpus

Kõige tõhusam samm on alustada nutikaid lepinguauditeid juhtivalt turvafirmalt, nagu QuillAudits, mille käigus audiitorid jälgivad hoolikalt koodi ülesehitust ja kontrollivad, kuidas varufunktsioon toimib. Uuritud mustrite põhjal antakse soovitusi koodi ümberstruktureerimiseks, kui see tundub olevat haavatavad käitumised

Vahendite turvalisus on tagatud vahetult enne kahjude ohvriks langemist. 

KKK

Mis on taastumisrünnak?

Uuesti sisenemise rünnak juhtub siis, kui haavatava lepingu funktsioon kutsub esile ebausaldusväärse lepingu. Ebausaldusväärne leping on ründaja leping, mis teeb haavatavale lepingule rekursiivseid kõnesid, kuni raha on täielikult ära kasutatud. 

Mis on reentrant?

Taassisenemine tähendab koodi täitmise katkestamist ja protsessi uuesti alustamist, mida nimetatakse ka uuesti sisestamiseks.

Mis on sissepääsuvalvur?

Reentancy valve kasutab modifikaatorit, mis takistab funktsiooni korduvat kutsumist. Lugege ülaltoodud ajaveebi, et leida näide taassisenemise valve kohta.

Millised on nutikate lepingute rünnakud?

Nutikad lepingud puutuvad kokku paljude haavatavustega, nagu taassisenemine, ajatempli sõltuvus, aritmeetilised ületäitmised, DoS-rünnakud jne. Seetõttu on auditeerimine kohustuslik tagamaks, et puuduvad vead, mis rikuksid lepingu loogika.

69 views

Ajatempel:

Veel alates Quillhash