Hur undkommer man smarta kontrakt från återinträdesattackernas koppling? PlatoBlockchain Data Intelligence. Vertikal sökning. Ai.

Hur undkommer man smarta kontrakt från återinträdesattackernas koppling?

Lästid: 6 minuter

Om vi ​​tittar närmare på de största kryptohackarna och de iögonfallande siffrorna som förlorats för dem, skulle de ha rotat sig djupt från kodningsbristerna.

En sådan vanlig förekomst av säkerhetssårbarhet är Reentrancy-attacken. Den destruktiva effekten som orsakas på grund av felaktigt återinträde kanske inte låter så enkelt som att starta själva attacken.

Trots att det är en välbekant och väl omtalad fråga är uppkomsten av Reentrancy-buggen i smarta kontrakt alltid oundviklig. 

Hur ofta hade Reentrancy-sårbarheten utnyttjats av hackare under de senaste åren? Hur fungerar det? Hur hindrar man smarta kontrakt från att förlora pengar till Reentrancy-buggar? Hitta svar på dessa frågor i den här bloggen.

Så, snart, låt oss fräscha upp de största återinträdesattackerna i minnet. 

Några av de mest ökända reentrancy-hacken i realtid 

Återinträdesattacker som orsakade de mest förödande effekterna på projekten slutade med att göra en av dessa två eller till och med båda. 

  • Töm bort Ether helt från de smarta kontrakten
  • Hackare smyger sig in i den smarta kontraktskoden

Vi kan nu observera några fall av återinträdesattacker och deras inverkan. 

Juni 2016: DAO attack – 3.54 miljoner eller $150 miljoner eter

april 2020: Uniswap/Lendf.Me-hack – $25 miljoner

Maj 2021: BurgerSwap-hacket – $7.2 miljoner

2021 augusti: CREAM FINANCE hack – $18.8 miljoner

Mars 2022: Ola Finance – 3.6 miljoner dollar

juli 2022: OMNI-protokoll – 1.43 miljoner dollar

Det är kristallklart att Reentrancy-attacker aldrig har gått ur stilen. Låt oss få djupa insikter i det i följande avsnitt. 

Översikt över Reentrancy-attack

Som från namnet "Reentrancy", vilket innebär "Återinträde igen och igen." Återinträdesattack involverar två kontrakt: offerkontraktet och attackerkontraktet. 

Angriparkontraktet utnyttjar sårbarheten för återinträde i offerkontraktet. Den använder tillbakadragningsfunktionen för att uppnå det. 

Angriparkontraktet anropar uttagsfunktionen för att tappa pengar från offerkontraktet genom att göra upprepade samtal innan saldot i offerkontraktet uppdateras. Offrets kontrakt kommer att kontrollera saldot, skicka pengar och uppdatera saldot. 

Men inom tidsramen för att skicka pengarna och uppdatera saldot i kontraktet, gör angriparkontraktet ett kontinuerligt uppmaning att ta ut pengar. Som ett resultat uppdateras inte saldot i offerkontraktet förrän angriparkontraktet tappar alla medel.

Allvarligheten och kostnaderna för att utnyttja återinträde larmar det trängande behovet av att prestera smarta kontraktsgranskningar för att utesluta möjligheten att förbise sådana fel. 

Illustrativ bild av Reentrancy Attack

Låt oss förstå konceptet med återinträdesattack från den förenklade illustrationen nedan. 

Här är två kontrakt: Det sårbara kontraktet och hackerkontraktet

Hackerkontraktet uppmanar till att dra sig ur det sårbara kontraktet. När det sårbara kontraktet tar emot samtalet söker det efter pengarna i hackerkontraktet och överför sedan pengarna till hackaren. 

Hackaren tar emot pengarna och implementerar reservfunktionen, som återigen ringer in i det sårbara kontraktet redan innan saldot uppdateras i det sårbara kontraktet. Genom att upprepa samma operation drar hackaren ut pengarna helt från det sårbara kontraktet. 

Hur undkommer man smarta kontrakt från återinträdesattackernas koppling?

Funktioner för reservfunktion som används av angripare 

  • De är externt anropsbara. Dvs de kan inte ringas in från kontraktet de är skrivna
  • Namnlös funktion
  • Reservfunktionen inkluderar inte godtycklig logik inuti den
  • Fallback utlöses när ETH skickas till sitt omslutande smarta kontrakt, och ingen receive() funktion deklareras.

Analyserar återinträdesattack från en teknisk vy 

Låt oss ta ett provkontrakt och förstå hur återinträdesattacken uppstår.

Skadligt kontrakt

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


}

Detta är angriparkontraktet där angriparen sätter in 2ETH. Angriparen anropar tillbakadragningsfunktionen i det sårbara kontraktet. När medlen har tagits emot från det sårbara kontraktet utlöses reservfunktionen. 

Fallbacken utför sedan uttagsfunktionen och dränerar fonden från det sårbara kontraktet. Denna cykel fortsätter tills medlen är helt uttömda från det sårbara kontraktet.

Sårbart kontrakt

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


}

Det sårbara kontraktet har 30ETH. Häri skickar funktionen withdraw() det begärda beloppet till angriparen. Eftersom saldot inte uppdateras överförs tokens till angriparen upprepade gånger. 

Typer av återinträdesattacker

  • Enkelfunktion återinträde 
function withdraw() external {
   uint256 amount = balances[msg.sender];
   require(msg.sender.call.value(amount)());
   balances[msg.sender] = 0;
}

Msg.sender.call.value(amount)() överför pengarna varefter angriparens kontraktsfallback-funktion anropar withdraw()igen innan saldot[msg.sender] = 0 uppdateras.

  • Tvärfunktion återinträde
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;
}

Återinträde på flera funktioner är mycket mer komplicerat att identifiera. Skillnaden här är att reservfunktionen anropar överföring, till skillnad från vid återinträde med en funktion, där den ringer tillbaka.

Förebyggande mot återinträdesattacker

Mönster för kontroller-effekter-interaktioner: Checks-effects-interactions mönster hjälper till att strukturera funktionerna. 

Programmet bör vara kodat på ett sätt som kontrollerar förutsättningarna först. Efter att ha klarat kontrollerna bör effekterna på kontraktens tillstånd lösas, varefter de externa funktionerna kan anropas. 

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

Den omskrivna koden här följer mönstret checks-effects-interactions. Här nollställs saldot innan ett externt samtal görs. 

Användning av modifierare

Modifieraren noReentrant som tillämpas på funktionen säkerställer att det inte finns några reentrant-anrop. 

contract ReEntrancyGuard {
    bool internal locked;

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

I slutet

Det mest effektiva steget är att ta upp smarta kontraktsrevisioner från ett ledande säkerhetsföretag som QuillAudits, där revisorerna håller ett öga på kodens struktur och kontrollerar hur reservfunktionen fungerar. Utifrån de studerade mönstren ges rekommendationer för att omstrukturera koden om det verkar finnas några sårbara beteenden

Medlens säkerhet säkerställs precis innan du blir offer för några förluster. 

Vanliga frågor

Vad är en återinträdesattack?

En återinträdesattack inträffar när en funktion i det sårbara kontraktet ringer till ett opålitligt kontrakt. Det opålitliga kontraktet kommer att vara angriparens kontrakt som gör rekursiva anrop till det sårbara kontraktet tills pengarna är helt tömda. 

Vad är en återkommande?

Återinträde innebär att avbryta exekveringen av koden och initiera processen på nytt, vilket också är känt som återinträde.

Vad är en återinträdesvakt?

Reentrancy guard använder en modifierare som förhindrar att funktionen anropas upprepade gånger. Läs bloggen ovan för att hitta exemplet för återinträdesvakt.

Vilka är några av attackerna mot smarta kontrakt?

Smarta kontrakt är utsatta för många sårbarheter, såsom återinträde, tidsstämpelberoende, aritmetiska översvämningar, DoS-attacker och så vidare. Därför är revision ett måste för att säkerställa att det inte finns några buggar som kollapsar kontraktets logik.

69 Visningar

Tidsstämpel:

Mer från Pilbåt