今回は、Reentrancy問題を改善したスマートコントラクトに対して攻撃を行います。
アカウントごとの役割
アカウントの役割は次の通りです。
- MAIN ACCOUNT (eth.accounts[0])
攻撃される側のコンストラクト(Victim Balance)生成者。 - ACCOUNT1 (eth.accounts[1])
攻撃される側のコントラクトに送金を行う通常のユーザ。 - ACCOUNT2 (eth.accounts[2])
攻撃する側のコンストラクト(Evil Receiverコ)生成者。 - ACCOUNT3 (eth.accounts[3])
マイナー。
攻撃される側のコントラクト(改善版)をデプロイ
まずはデプロイを行います。デプロイアカウントはMAIN ACCOUNTです。
デプロイするのは、前回改善したVictim Balanceコントラクトになります。
[Victim Balanceコントラクトのデプロイ]
デプロイ後のコントラクトの状態を確認します。
[攻撃される側のコントラクト状態]
デプロイ直後なので、コントラクトの残高が0 ehterであることが確認できます。
攻撃する側のコントラクトをデプロイ
次は攻撃する側のコントラクトのデプロイを行います。デプロイアカウントはACCOUNT2です。
デプロイするのは、Evil Receiverコントラクトになります。
targetには、攻撃される側のコントラクト(改善したVictim Balance)のアドレスを設定します。
[Evil Receiverコントラクトのデプロイ]
デプロイ後のコントラクトの状態を確認します。
[攻撃する側のコントラクト状態]
ターゲットのコントラクトがVictim Balanceとなっていることが確認できます。
通常のユーザから送金
ACCOUNT1から、攻撃される側のコントラクト(Victim Balance)に20 ether送金します。
Add To Balance関数を使用します。
[送金]
送金後のコントラクトの状態を確認します。
[攻撃される側のコントラクト状態]
残高が20 etherになっていることが確認できます。
攻撃する側のコントラクトに送金
ACCOUNT2から、攻撃する側のコントラクト(Evil Receiver)に10 etherを送金します。
Add Balance関数を使用します。
[送金]
送金後のコントラクトの状態を確認します。
[攻撃する側のコントラクト状態]
残高が10 etherになっていることが確認できます。
攻撃する側のコントラクトから送金
攻撃する側のコントラクト(Evil Receiver)から攻撃される側のコントラクト(Victim Balance)に10 etherを送金します。
Send Eth To Target関数を使用します。
[送金]
攻撃される側のコントラクトの状態を確認します。
[攻撃される側のコントラクト状態]
10 ether追加されて、残高が30 etherになりました。
攻撃する側のコントラクトの状態を確認します。
[攻撃する側のコントラクト状態]
10 ether送金したので、残高が0 etherになりました
攻撃する側のコントラクトから返金要求
攻撃する側のコントラクト(Evil Receiver)から攻撃される側のコントラクト(Victim Balance)に返金要求を行います。Withdraw関数を使用します。
10 ether送金したので、返金額は10 etherとなるはずです。
[返金]
攻撃された側のコントラクト状態を確認します。
[攻撃される側のコントラクト状態]
改善前は、20 ether送金されてしまい10 etherしか残っていませんでしたが、今回は問題なく10 etherが返金され残高が20 etherとなっています。
攻撃した側のコントラクト状態も確認します。
[攻撃する側のコントラクト状態]
前回は攻撃の結果20 ether引き出せましたが、今回は本来の10 ehterの返金となり攻撃に失敗しています。
以上で、Reentrancy問題のあったらスマートコントラクトの改善を確認することができました。