Wie wurde die Rekursion erstellt, die zum DAO-Hack führte?

Ich verstehe, dass, wenn der DAO-Vertrag eine Auszahlungsfunktion hat, die Geld an Vertrag X sendet, Vertrag X böswillig sein und die Fallback-Funktion verwenden kann, um die Auszahlungsfunktion erneut aufzurufen. Im Fall des DAO-Vertrags X war jedoch eine weitere Kopie des DAO, sodass dieses böswillige Verhalten nicht auftrat.

Wie genau war das rekursive Senden möglich?

Es war die splitFunktion, die ausgenutzt wurde.
Dieser Artikel enthält eine Erklärung, wie der Reentry-Hack funktioniert vessenes.com/…

Antworten (2)

Dies ist die problematische Codezeile in der withdrawRewardForFunktion:

    if (!rewardAccount.payOut(_account, reward)) <-- reentrant exploit
         throw;
    paidOut[_account] += reward;

Die Auszahlung ruft die Empfängerfunktion auf payout:

function payOut(address _recipient, uint _amount) returns (bool) {
    ..
    if (_recipient.call.value(_amount)()) {
    ..
}

Wenn _recipientes sich um einen Vertrag handelt, wird die Fallback-Funktion des Vertrags aufgerufen . Dieser Empfänger wiederum kann den TheDao-Vertrag erneut aufrufen. Da withdrawRewardFores nicht gegen Wiedereintritt geschützt war, wurde es wieder erlaubt. paidOut[_account] += reward;Dies bedeutete eine kontinuierliche Auszahlung, bevor der Code mit und darüber hinaus fortgesetzt werden durfte .

Der Artikel More Ethereum Attacks: Race-To-Empty is the Real Deal , der eine Woche vor dem Angriff geschrieben wurde, enthält eine detailliertere Analyse dieser Art von Hacks und Lösungsvorschlägen.

Wenn es dann passiert ist, wie hat sich diese Rekursion vor dem vollständigen Abzug des Guthabens aufgelöst?
@AK Die maximal zulässige Gasmenge begrenzt, wie oft der Vertrag aufgerufen werden kann. Weitere Informationen finden Sie unter vessenes.com/deconstructing-thedao-attack-a-brief-code-tour

Um Ihre Frage zu beantworten, müssen Sie zwischen Verträgen und Angeboten unterscheiden.

Das DAO ist ein Vertrag , der Regeln kodifiziert, um Mittel über Vorschläge verfügbar zu machen .

Ein Vorschlag kann ein Antrag auf Investition oder ein Antrag auf Abhebung Ihrer eigenen Mittel sein (dies wird als Split -Vorschlag bezeichnet). Wenn ein geteiltes Angebot genehmigt wird, ruft es die splitDAO-API auf, um ein untergeordnetes DAO (untergeordneten Vertrag) zu erstellen. Der Code dieses untergeordneten Vertrags ist tatsächlich identisch mit dem ursprünglichen DAO.

Die SplitDAO-Funktion überträgt die angeforderten Geldmittel an die untergeordnete DAO. Aber es ruft auch eine vom Vorschlag bereitgestellte Standardfunktion auf , angeblich um die übertragenen Gelder zu handhaben. Und diese Funktion wird direkt nach der Geldtransferoperation aufgerufen, aber bevor die Gelder vom Gesamtguthaben von DAO abgezogen werden und bevor das Benutzerguthaben auf Null gesetzt wird .

Der rekursive Exploit wurde in diese Standardfunktion eingebettet. Es rief einfach wieder splitDAO auf.

In Wirklichkeit hätte die Überweisung von Geldern, die Reduzierung des Gesamtguthabens und das Setzen des Benutzerguthabens auf Null eine atomare Operation sein sollen. Andere Methoden (Sperren, Mutexe) hätten auch implementiert werden können, um sicherzustellen, dass der gesamte Aufteilungsvorgang abgeschlossen ist, bevor ein externer, vom Benutzer bereitgestellter Code ausgeführt wird.