Beginner FriendlyFoundryGameFi
100 EXP
View results
Submission Details
Severity: high
Invalid

Eth sending to an arbitrary address

Summary

The 'buyMartenitsa' function of the 'MartenitsaMarketplace' contract sends eth to an arbitrary address. The function sends Ether to the seller address, which is obtained from the listing. If the seller address is malicious or controlled by an attacker, it could potentially execute arbitrary code when receiving Ether, leading to unexpected behavior.

Vulnerability Details

In the 'buyMartenitsa' function, after verifying that the Martenitsa token is listed for sale and the buyer has sent enough Ether to cover the price, it transfers Ether to the seller using seller.call{value: salePrice}(""). This line uses the low-level call function to send Ether to the seller's address.

This function sends Ether to the seller address, which is obtained from the listing. If the seller address is malicious or controlled by an attacker, it could potentially execute arbitrary code when receiving Ether, leading to unexpected behavior or vulnerabilities.

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
contract Attacker {
MartenitsaMarketplace public marketplace;
constructor(address _marketplace) {
marketplace = MartenitsaMarketplace(_marketplace);
}
// Function to initiate the attack
function initiateAttack(uint256 tokenId) external payable {
// Call the vulnerable function with a large amount of Ether
marketplace.buyMartenitsa{value: msg.value}(tokenId);
}
// Fallback function to receive Ether
receive() external payable {}
}
contract MartenitsaMarketplace {
mapping(uint256 => address) public tokenIdToSeller;
function buyMartenitsa(uint256 tokenId) external payable {
address seller = tokenIdToSeller[tokenId];
// Vulnerable part: Sends Ether to seller's address
(bool sent, ) = seller.call{value: msg.value}("");
require(sent, "Failed to send Ether");
}
}

Impact

  • The Attacker contract is created with the address of the 'MartenitsaMarketplace' contract.

  • The 'initiateAttack' function is called with a specified tokenId and a large amount of Ether.

  • Inside the 'buyMartenitsa' function of 'MartenitsaMarketplace', Ether is sent to the seller address using a low-level call.

  • The seller address is retrieved from the 'tokenIdToSeller' mapping, which can potentially be manipulated by an attacker.

  • By initiating the attack with a large amount of Ether and setting up an appropriate 'fallback' function to receive Ether in the Attacker contract, an attacker can potentially receive Ether sent by the 'MartenitsaMarketplace' contract to any address they control, demonstrating the vulnerability of sending Ether to an arbitrary address.

Tools Used

Foundry, VSCode, Slither, Remix.

Recommendations

It is recommended to follow the withdrawal pattern, where sellers withdraw Ether from the contract rather than having the contract send Ether to them automatically. This approach ensures that Ether transfers are controlled by the seller and reduces the attack surface for potential vulnerabilities. Additionally, using a more secure transfer method, such as 'transfer' or 'send', can provide additional safeguards against reentrancy and other vulnerabilities.

Updates

Lead Judging Commences

bube Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

Reentrancy

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.