Home Web3 SecurityCrypto Hacks & Exploits Stars Arena Hack—Oct 7, 2023—Detailed Analysis

Stars Arena Hack—Oct 7, 2023—Detailed Analysis

by ImmuneBytes
Stars Arena Hack—Oct 7, 2023—Detailed Analysis

Overview

Stars Arena, a project on the Avalanche blockchain, experienced a significant security breach on October 7, 2023. The hack resulted in a substantial loss, approximately $2,974,530, equivalent to 266,103 AVAX. The underlying cause of this exploit was identified as a reentrancy vulnerability, a common yet critical issue in smart contract security.

About Stars Arena

Stars Arena, a SocialFi platform and a clone of friend.tech, is carving its niche as the future of SocialFi on the Avalanche blockchain.

It’s specifically tailored for creators, enabling them to monetize their content through exclusive chatrooms. Since its launch, the platform has demonstrated impressive growth, marked by an 820% increase in weekly activity. According to DappRadar, Stars Arena’s transactions have surged from 26,870 to over 248,000 in just a week, and it now boasts over 10,000 unique active wallets, indicating its rapidly expanding user base and engagement.

The Root Cause of the Exploit

Primary Reason for Hack: The exploit was enabled by a reentrancy vulnerability in Stars Arena’s smart contract. A faulty price function allowed the exploiter to manipulate the sellShare function, leading to disproportionate AVAX returns for minimal input.

Reentrancy attacks allow attackers to repeatedly call a function and withdraw funds before the original function execution is completed, often exploiting the way the contract state is updated.

Detailed Technical Analysis

Stars Arena: Shares (proxy): 0xA481B139a1A654cA19d2074F174f17D7534e8CeC

Stars Arena: 0x8aF92C23a169B58c2E5AC656D8D8a23FC725080f

Exploiter: 0xa2Ebf3FCD757e9BE1E58B643b6B5077D11b4ad7A

First Incident (October 5, 2023)

Nature of the Exploit: The initial attack on Stars Arena was relatively minor but crucial in setting the stage for the subsequent major exploit. In this incident, the exploiter took advantage of a vulnerability in the smart contract that allowed for the sale of zero shares in exchange for AVAX, the native cryptocurrency of the Avalanche blockchain.

Modus Operandi: This type of attack typically involves manipulating a smart contract’s logic to allow transactions that should not ordinarily be possible, such as selling non-existent shares.

Financial Impact: The financial damage from this exploit was limited, resulting in a loss of approximately $2,000.

function getPrice(address varg0, uint256 varg1, uint256 varg2) public nonPayable {

  require(msg.data.length - 4 >= 96);

  require(varg0 == varg0);

  v0 = 0x1a9b(varg2, varg1, varg0);

  return v0;

}

The attack was carried out by an externally owned address (EOA), identified as 0xa2e.... This same address was later linked to the major exploit that occurred two days after this initial incident.

Following this attack, Stars Arena addressed the vulnerability and the StarsArena deployer deployed a new contract and pointed the proxy to it.. However, this fix was not sufficient to prevent the more significant exploit that followed.

Second Incident (Major Hack on October 7, 2023)

Overview: Just two days after the first incident, Stars Arena faced a major hack due to a reentrancy vulnerability in their smart contract. This was the largest exploit of its kind on the Avalanche blockchain in 2023.

Exploit Mechanics

Manipulated Function: The associated contract for the second exploit was not open source. On decompiling the bytecode of the proxy contract. The sellShare function in the contract was specifically targeted, allowing the exploiter to receive a massive amount of AVAX for minimal input.

Detailed Attack Process
To understand the attack flow, let’s understand each function that was used to execute the attack.

Function: 0x5632b2e4

This function took four uint256 arguments and performed checks before updating owner mapping weights.
Key Checks: Performed preliminary conditional checks and validated inputs.

Code Snippet:

function 0x5632b2e4(uint256 varg0, uint256 varg1, uint256 varg2, uint256 varg3) public nonPayable {

 require(msg.data.length - 4 >= 128);

 require(!uint8(owner_a1[msg.sender]), Error('Weights already initialized'));

 require(!owner_a7[msg.sender].field0.length, Error("Can't change weights after shares have been issued"));

 require(varg0 > 0, Error('Weight A must be greater than 0'));

 require(varg1 > 0, Error('Weight A must be greater than 0'));

 require(varg2 > 0, Error('Weight C must be greater than 0'));

 owner_9d[msg.sender] = varg0;

 owner_9e[msg.sender] = varg1;

 owner_9f[msg.sender] = varg2;

 owner_a0[msg.sender] = varg3;

 owner_a1[msg.sender] = 0x1 | bytes31(owner_a1[msg.sender]);

}

Function: 0xe9ccf3a3

Description: Within the contract, the function 0xe9ccf3a3 is designed to accept two address inputs (varg0 and varg2) and one unsigned integer (varg1).

Functionality: It conducts several initial checks, after which it proceeds to call the 0x326c function, but only if the varg2 parameter holds a non-null address value. Additionally, it invokes the 0x2058 function, passing varg1 and varg0 as arguments.
Code Snippet:

function 0xe9ccf3a3(address varg0, uint256 varg1, address varg2) public payable {

 require(msg.data.length - 4 >= 96);

 require(varg0 == varg0);

 require(varg2 == varg2);

 if (varg2) {

     0x326c(varg2, msg.sender);

 }

 0x2058(varg1, varg0);

}

Function: 0x2058

Function Transfer: Upon its activation, function 0x2058 delegates its operational call to another function in the contract, named 0x1a9b. This delegation is a crucial step in the contract’s execution flow.

Code Snippet:

function 0x2058(uint256 varg0, uint256 varg1) private {

   v0 = 0x1a9b(varg0, _sharesSupply[address(varg1)], varg1);

   v1 = _SafeMul(v0, _protocolFeePercent);

   require(0xde0b6b3a7640000, Panic(18)); // division by zero

   v2 = _SafeMul(v0, _subjectFeePercent);

   require(0xde0b6b3a7640000, Panic(18)); // division by zero

   v3 = _SafeMul(v0, _referralFeePercent);

   require(0xde0b6b3a7640000, Panic(18)); // division by zero

   v4 = _SafeAdd(v0, v1 / 0xde0b6b3a7640000);

   v5 = _SafeAdd(v4, v2 / 0xde0b6b3a7640000);

   v6 = _SafeAdd(v5, v3 / 0xde0b6b3a7640000);

   require(msg.value >= v6, Error('Insufficient payment'));

   v7 = _SafeAdd(_getMyShares[address(varg1)][msg.sender], varg0);

   _getMyShares[address(varg1)][msg.sender] = v7;

   v8 = _SafeAdd(_sharesSupply[address(varg1)], varg0);

   _sharesSupply[address(varg1)] = v8;

   v9 = 0x1a9b(1, _sharesSupply[address(varg1)], varg1);

   v10 = _SafeAdd(_sharesSupply[address(varg1)], varg0);

   0x307c(v1 / 0xde0b6b3a7640000);

   0x30ef(v2 / 0xde0b6b3a7640000, varg1);

   v11 = _SafeAdd(v0, v1 / 0xde0b6b3a7640000);

   v12 = _SafeAdd(v11, v2 / 0xde0b6b3a7640000);

   v13 = _SafeAdd(v12, v3 / 0xde0b6b3a7640000);

   v14 = _SafeSub(msg.value, v13);

   if (v14) {

       0x30ef(v14, msg.sender);

   }

   if (v3 / 0xde0b6b3a7640000) {

       0x2f7b(v3 / 0xde0b6b3a7640000, msg.sender);

   }

   if (varg0 == _getMyShares[address(varg1)][msg.sender]) {

       v15 = address(varg1);

       owner_a7[v15].field0.length = owner_a7[v15].field0.length + 1;

       owner_a7[v15].field0[owner_a7[v15].field0.length].field0 = msg.sender | bytes12(owner_a7[v15].field0[owner_a7[v15].field0.length].field0);

   }

   emit 0xc9d4f93ded9b42fa24561e02b2a40f720f71601eb1b3f7b3fd4eff20877639ee(msg.sender, address(varg1), bool(1), varg0, v0, v1 / 0xde0b6b3a7640000, v2 / 0xde0b6b3a7640000, v3 / 0xde0b6b3a7640000, v10, v9, _getMyShares[address(varg1)][msg.sender]);

   return ;

}

Reentrancy in 0xe9ccf3a3 and 0x5632b2e4

Attack Mechanism: While the 0xe9ccf3a3 function is executing, the attacker exploits a reentrancy vulnerability. They manage to re-invoke the function and make a call to 0x5632b2e4. This particular action is instrumental in setting a specific block height, a vital component in the exploit’s success.

Code Snippet:

function 0x1a9b(uint256 varg0, uint256 varg1, uint256 varg2) private {

 v0 = 0x2329(varg2);

 v1 = _SafeAdd(varg1, v0);

 if (v1) {

   v2 = _SafeSub(v1, 1);

   v3 = _SafeMul(2, v2);

   v4 = _SafeAdd(1, v3);

   v5 = _SafeSub(v1, 1);

   v6 = _SafeMul(v5, v1);

   v7 = _SafeMul(v6, v4);

   require(6, Panic(18)); // division by zero

   v8 = _SafeSub(v1, 1);

   v9 = _SafeAdd(v8, varg0);

   v10 = _SafeMul(2, v9);

   v11 = _SafeAdd(1, v10);

   v12 = _SafeAdd(v1, varg0);

   v13 = _SafeSub(v1, 1);

   v14 = _SafeAdd(v13, varg0);

   v15 = _SafeMul(v14, v12);

   v16 = _SafeMul(v15, v11);

   require(6, Panic(18)); // division by zero

   v17 = 0xfd5(varg2);

   v18 = _SafeSub(v16 / 6, v7 / 6);

   v19 = 0xeeb(varg2);

   v20 = _SafeMul(v19, v18);

   require(0xde0b6b3a7640000, Panic(18)); // division by zero

   v21 = _SafeAdd(v20 / 0xde0b6b3a7640000, v17);

   v22 = 0x1840(varg2);

   v23 = _SafeMul(v22, v21);

   v24 = _SafeMul(v23, _initialPrice);

   require(0xde0b6b3a7640000, Panic(18)); // division by zero

   if (v24 / 0xde0b6b3a7640000 >= _initialPrice) {

       return v24 / 0xde0b6b3a7640000;

   } else {

       return _initialPrice;

   }

 } else {

     return _initialPrice;

 }

}

Exploiting the sellShares Function

The block height set by 0x5632b2e4 was used in sellShares to calculate an abnormally high amount of AVAX to send.

Code Snippet:

function sellShares(address varg0, uint256 varg1) public payable {

 require(msg.data.length - 4 >= 64);

 require(varg0 == varg0);

 v0 = _SafeSub(_sharesSupply[varg0], varg1);

 v1 = 0x1a9b(varg1, v0, varg0);

 v2 = _SafeMul(v1, _protocolFeePercent);

 require(0xde0b6b3a7640000, Panic(18)); // division by zero

 v3 = _SafeMul(v1, _subjectFeePercent);

 require(0xde0b6b3a7640000, Panic(18)); // division by zero

 v4 = _SafeMul(v1, _referralFeePercent);

 require(0xde0b6b3a7640000, Panic(18)); // division by zero

 require(varg1 <= _getMyShares[varg0][msg.sender], Error("Insufficient shares"));

 require(varg1 > 0, Error("Amount must be greater than 0"));

 v5 = _SafeSub(_getMyShares[varg0][msg.sender], varg1);

 _getMyShares[varg0][msg.sender] = v5;

 v6 = _SafeSub(_sharesSupply[varg0], varg1);

 _sharesSupply[varg0] = v6;

 v7 = 0x1a9b(1, _sharesSupply[varg0], varg0);

 v8 = _SafeSub(_sharesSupply[varg0], varg1);

 v9 = _SafeSub(v1, v2 / 0xde0b6b3a7640000);

 v10 = _SafeSub(v9, v3 / 0xde0b6b3a7640000);

 v11 = _SafeSub(v10, v4 / 0xde0b6b3a7640000);

 0x30ef(v11, msg.sender);

 0x307c(v2 / 0xde0b6b3a7640000);

 0x30ef(v3 / 0xde0b6b3a7640000, varg0);

 if (v4 / 0xde0b6b3a7640000) {

   0x2f7b(v4 / 0xde0b6b3a7640000, msg.sender);

 }

 if (!_getMyShares[varg0][msg.sender]) {

   0x330f(msg.sender, varg0);

 }

 emit 0xc9d4f93ded9b42fa24561e02b2a40f720f71601eb1b3f7b3fd4eff20877639ee(

   msg.sender,

   varg0,

   bool(0),

   varg1,

   v1,

   v2 / 0xde0b6b3a7640000,

   v3 / 0xde0b6b3a7640000,

   v4 / 0xde0b6b3a7640000,

   v8,

   v7,

   _getMyShares[varg0][msg.sender]

 );

}

Final Outcome of the Exploit

The reentrancy allowed the attacker to update weights when shares were issued, enabling the sale of 1 share at a price of 274,000 AVAX, leading to enormous illicit gains.

Stolen Fund Details

Movement of Funds: Post-exploit, the stolen funds were strategically dispersed among 266 newly created Externally Owned Accounts (EOAs), each holding 1,000 AVAX.

Exploit Wallet Identification: The exploiter used the same wallet address (shortened as 0xa2e…) for both the initial minor exploit and the subsequent major hack. Hack Aftermath

Initial Response and Communication

Security Breach Alert: Stars Arena quickly informed their community about the major security breach in their smart contract, advising users to refrain from depositing any funds while the issue was being investigated.

DDOS Attack: The platform experienced a DDOS attack shortly after the initial announcement, further complicating the situation.

Financial Impact and CEO’s Statement

Total Value Lost: The hack lost almost the entire Total Value Locked (TVL) in the protocol, approximately $3 million.

Public Remarks: The founder and CEO of AvaLabs commented on the incident, noting the loss as significant but manageable given the team’s rapidly growing revenue.

Recovery and Security Measures

Recovery of Funds: By October 12, 2023, Stars Arena had successfully recovered about 90% of the stolen 266,000 AVAX, valued at around $3 million during the hack.

Bounty Payment: The recovery involved negotiating with the exploiter and agreeing to a 27,610-AVAX bounty, equivalent to nearly $257,000, plus compensation for an additional 1,000 AVAX (over $9,000) reportedly lost by the exploiter.

Smart Contract Revision: A new smart contract was written, and before redeploying the returned funds, Stars Arena was finalizing an audit of this new contract to ensure enhanced security.

Securing Resources: The team secured the necessary resources to address the financial gap caused by the exploit and engaged a specialized white-hat development team for a thorough security review of their platform.

Efforts and Transparency

Funding for Security: Stars Arena secured funding specifically to address the vulnerabilities exposed by the hack and engaged a development team for a full security audit.

Public Updates: Despite their proactive response, the team has yet to provide detailed insights into how the exploit was executed. Details of Previous Hacks/Similar Hacks

Lessons Learned

Preventive Measures: Regular and thorough audits of smart contracts, especially for reentrancy vulnerabilities, are crucial. Implementing checks-effects-interactions patterns and ensuring atomic transactions can help prevent such exploits.

Conclusion

The Stars Arena hack serves as a stark reminder of the critical need for robust security practices in developing smart contracts.

It highlights the indispensable role of regular audits and proactive security measures in safeguarding against vulnerabilities. This incident also casts a spotlight on the evolving landscape of blockchain security, emphasizing the growing necessity for advanced security protocols and expert auditing.

In this context, the engagement of professional auditing firms like ImmuneBytes is a pivotal step toward mitigating risks and enhancing the integrity of smart contracts in the blockchain domain.

Their expertise can play a significant role in preempting such security breaches, thereby fortifying the blockchain ecosystem against potential exploits.

You may also like