今回はオークションを攻撃するスマートコントラクトを実行していきます。
アカウントごとの役割
アカウントの役割は次の通りです。
- MAIN ACCOUNT (eth.accounts[0]) “0xec3b01f36b44182746ca109230567c4915512e35”
オークションの オーナー。 - ACCOUNT1 (eth.accounts[1]) “0x63f25b9bbd974fdfa07477cb99c60d2073cfe560”
Bidder1(入札者1)。アカウント1。⇒悪意のあるコンストラクトから攻撃を行う。 - ACCOUNT2 (eth.accounts[2]) “0xd5adf1e9fbc1ed869ed4c7372961238fddc760a5”
Bidder2(入札者2)。アカウント2。 - ACCOUNT3 (eth.accounts[3])
マイナー。
デプロイ
まずはデプロイを行います。デプロイアカウントはアカウント1です。
[デプロイ時のイメージ]
悪意のあるコントラクトから入札(30 ether)
入札を行う前にアカウント1の残高を確認します。
アカウント1から、悪意のあるコンストラクト(EvilBidder)を使って入札(bid関数)を行います。
入札額は30 etherです。
to - addressには、オークション用コントラクトのアドレスを設定しています。
アカウント1の残高を確認します。
30 ether減っていることが確認できます。
攻撃された後のオークション用コントラクト
オークション用コントラクトの状態を確認します。
最高提示額が30 etherになっていることが確認できます。
また最高額提示者がEvilBidderのアドレスになっていることも確認できます。
通常の入札(40 ether)
アカウント2から再び入札を行います。
入札額は40 etherです。
オークションコントラクトの状態を確認します。
最高入札額が30 etherで、最高額提示者がEvilBidderのアドレスになっていることから、40 etherの入札が失敗していることを確認できます。
入札が失敗した理由
入札失敗の流れは次の通りです。
- オークション用コントラクトのbid関数がコールされる。
- 最高提示額が更新されたため、オークションコントラクトから悪意のあるコントラクトへ返金処理が実行される。
- 悪意のあるコントラクトのFallback関数がコールされ、意図的なエラーが発生する。(エクセプションがスローされる)
- オークションコントラクトでエラーが発生し、bid関数のロールバック処理が行われる。
つまり、今後だれがオークションコン用トラクトへbid(入札)しても最高提示額の更新は行うことができない状態になってしまっています。
この手法を使うと、1回だけ最高提示額を提示すればそのオークションで落札することが可能になります。
次回は、このような攻撃を避けるためのオークション用コントラクトを作成していきます。