sherlock-audit / 2024-06-makerdao-endgame-judging

5 stars 3 forks source link

0xaliyah - h-01 reentrant with stolen of funds 0xaliyah #14

Closed sherlock-admin3 closed 3 months ago

sherlock-admin3 commented 3 months ago

0xaliyah

High

h-01 reentrant with stolen of funds 0xaliyah

Summary

  1. while the temp. var; balance L222 is the misinformation toward the effect at L237
  2. while the temp. var; balance L222 is the lagging indication toward the effect at L237 if the from address was made any withdrawal or any transferFrom in the way that induced that reentry
  3. L222 is the lagging indication
  4. the from address made a withdrawal when the transferFrom function gave up control to the attacker at L222
  5. since withdraw made and L222 now stale then L237 give the now empty-balance from address free increment

Vulnerability Detail

  1. recipients for free balance increment may be found

Impact

  1. high impact + high likeliness owasp

Code Snippet

poc

Tool used

Manual Review

Recommendation

checks effects interactions Will Shahda

telome commented 3 months ago

Spam/bot submission?

sabatha7 commented 3 months ago

@telome If you're asking whether the attacker might spam or brute force the contract, I don't think that would be their most elegant approach. It's more likely they would carefully plan everything off-chain first to maximize their advantage. However, using a brute force bot isn't out of the question, especially if they have a large balance to work with. They could potentially (execute a series of micro-transfer, hand in hand with the malicious removal of the all available balance prior to receipt the free additional credit), each just in time (JIT), to exploit the vulnerability. So, while brute force is less sophisticated, it's still a plausible method for them to pull off the attack.

sabatha7 commented 3 months ago

@telome @sunbreak1211 There might even be multiple less plausible attack paths that we mustn't afford to miss as well, such as running the transferFrom function in quick succession. Consider this: If the maximum available balance is the original balance, then:

  1. Run transferFrom with the maximum balance as an argument.
  2. How many transferFrom calls can we successfully execute in quick succession to capture that maximum balance (Line 222) before the from address's balance is deducted to zero, causing a revert due to insufficient funds?

Essentially, the excess balance that could be exploited can be approximated by balance[to].latest - balance[to].original - non-relatable transactions - maximum or (max(1, ((balance[to].latest - balance[to].original - non-relatable transactions) / maximum))-1)*maximum for those who wish to visualise or capture the most information. sherlock discord @0xaliyah . the attacker may evern attempt to run some weird combination of attack paths #15 or see in combination

sunbreak1211 commented 3 months ago

Means that the submission looks as a spam one as it is not clear at all what it is reporting. If there is an attack vector should have attached a concrete PoC. We are having a hard time understanding anything said here.

sabatha7 commented 3 months ago

@sunbreak1211 @telome ok thank you at sherlock we do not allow. ok here you go;

# Tn = 0: Initial state before the attack
OriginalBalance = 100000000
FraudBalance = 0

def transferFrom(addressFrom, addressTo, value):
    # Tn = 1: Capture balance before reentrant call
    ReentrantBalance = reentrantBalance(addressFrom)  # @Tn = 1

    # Tn = 3: Deduct the manipulated balance
    BalanceOf[addressFrom] = ReentrantBalance - value  # @Tn = 3 
    BalanceOf[addressTo] += value  # @Tn = 3

def reentrantBalance(addressFrom):
    # Tn = 2: Manipulate balances within reentrant call
    global FraudBalance
    FraudBalance = BalanceOf[addressFrom]
    BalanceOf[addressFrom] = 0  # @Tn = 2
    return FraudBalance  # @Tn = 1

# Tn = 4: Final state check
AddressFrom = 5
AddressTo = 6
BalanceOf = {AddressFrom: OriginalBalance, AddressTo: 0}

transferFrom(AddressFrom, AddressTo, 0.1)
assert(FraudBalance == OriginalBalance and BalanceOf[AddressFrom] == OriginalBalance - .1 and BalanceOf[AddressTo] == 0.1)