Diving into the intricate world of blockchain vulnerabilities, we encounter a notorious pair of bugs: overflow and underflow. These bugs have haunted developers for years, enabling malicious actors to exploit vulnerabilities and wreak havoc on decentralized systems.
Yet, just when it seemed like these threats were subdued with the advent of Solidity 0.8 and the implementation of SafeMath, a recent wave of attacks has unveiled a chilling reality. Outdated contracts, compiled with older Solidity versions, have become unsuspecting targets for cunning adversaries.
In a series of calculated maneuvers, attackers have exploited these neglected vulnerabilities, resulting in staggering losses totaling nearly $80,000. The implications of these attacks extend far beyond mere financial losses, highlighting the critical importance of ongoing vigilance and the necessity of constantly updating and securing smart contracts.
Join us as we unravel the intricacies of these recent assaults, dissecting the mechanisms behind the exploits and exploring strategies to fortify our decentralized ecosystems against future threats.
Basic Information
Affected Contract Address: 0x70ab487ec48B4b9571d346348da0F10737d48A54
(*Other contracts have also been attacked; however, they are unverified. So, let’s take the above verified contract to dive into the bug)
Vulnerability Category: Overflow/Underflow
Network: Ethereum
Total Lost: $~80,000
Difficulties: 5/10
Vulnerability Analysis
As we can see in the above image, the attacker has made a series of calls to different functions as below:
-
Call
_createMarket (0x186704b4)
-
Call
init (0x4394f6f3)
-
Call
shake (0xdecea642)
-
Call
report (0xda676f20)
-
Call
collect (0xf3692c3e)
Basically, first, the attacker created a game for his own, and then he/she played with himself/herself by calling init
and shake
. After that, the attacker set the result of the game for his own and claimed the reward that was manipulated by overflow bug happened during the shake
invocation.
In the shake
invocation, the attacker set
takerOdds
= 115792089237316195423570985008687907853269984665640564039457584007913129639935
and makerOdds
= 900000000000000000000
.
Let’s take a look at function _shake()
to see how the attacker profited from this.
In the _shake()
function, the payout amount to the makerSide would equal (makerStake * makerOdds) / ODDS_1;
Here, makerStake
was set to be 1 wei in the previous init()
invocation of the attacker. As such, with ODDS_1
= 100, makerPayout would then be:
(1 * 900000000000000000000)/100 = 9 * 1e18
On the other hand, takerPayout would equal to
(1*115792089237316195423570985008687907853269984665640564039457584007913129639935)/100 = 1157920892373161954235709850086879078532699846656405640394575840079131296399
Based on the logic in the code, as takerPayout
is greater than makerPayout
, takerPayout
, takerPayout
would then be equal to makerPayout
which is 9 ether.
In normal logic, the condition provided in the above image; however, interestingly, overflow has helped the attacker bypass this condition. As we all know, all compilers’ versions prior to Solidity 0.8.0 will NOT result in reverts if there are overflow or underflow. The exploited contract unfortunately was compiled with Solidity version 0.4.24; as such, overflow was there.
On the left hand side of the above condition,
takerOdds * ODDS_1 = 1157920892373161954235709850086879078532699846656405640394575840079131296399 * 100 = 115792089237316195423570985008687907853269984665640564039457584007913129639900
Whereas, the right hand side would be
makerOdds * (takerOdds - ODDS_1)) = 900000000000000000000*(1157920892373161954235709850086879078532699846656405640394575840079131296399 - 100) = 115792089237316195423570985008687907853269984665640563949133584007913129639936
Therefore, the condition is met and the payout amount to the winner is then manipulated to be 9 ether. At the end, all the attacker had to do is to set himself/herself as the winner and collect the manipulated reward.
Mediation
This attack has sounded the alarm for long-abandoned contracts. These contracts are often compiled with very low Solidity versions, making them susceptible to underflow and overflow vulnerabilities. This ultimately can lead to significant financial losses. Therefore, developers need to thoroughly inspect their assets and old contracts. If there are any assets remaining within them, it's advisable for them to withdraw funds from those contracts, or at least find a way to hack themselves before any bad actors come across.
评论 (0)