はじめに
最近、主催している福岡ブロックチェーン勉強会で、Ethernautというサイトの問題を解いています。
お題のEthereumのスマートコントラクトのコードに対して
条件を満たすと、クリアというサイトです。
問題の内容としては、過去にEthereumで見つかった有名な脆弱性などもあります。
今回は、そんなEthernautの1問目の問題を解いてみました。
1. Fallback の問題
URLはこちらですね。
お題
|
要は
- コントラクトのオーナーシップを奪う
- コントラクトの残高を0にする
を満たすことができれば、クリアですね。
スマートコントラクト
|
Fallbackというスマートコントラクトになっています。
オーナーを奪う方法を考える
まずは、「オーナーシップを奪う」必要があります。
コードをみる限り、オーナーになる方法は二つ。
一つ目
一つ目は以下の部分で。
|
contributions[msg.sender] が contributions[owner]より多ければ、
msg.sender つまりコントラクトを実行した人がオーナーになることができます。
しかし、constructorをみると、これは現実的でないことがわかります。
|
コントラクトが作成された時点で、contributions[owner] は 1000 * (1 ether)となっていることがわかります。
require(msg.value < 0.001 ether);が存在するため、contribute()では、一度に0.001 ether未満の額しか増やすことができません。
オーナーよりcontributionsを多くすることで、オーナー権限を奪うことは難しそうです。
二つ目
二つ目に以下の部分があります。
|
こちらは比較的簡単にオーナーを奪うことができそうです。
require(msg.value > 0 && contributions[msg.sender] > 0);
ここを満たすことができれば、オーナーを奪うことができます。
実際にオーナーを奪ってみる
contribute()
まずは、contributionsを0より大きくする必要があるので、contribute()を実行します。
ボタンをクリックして、Instanceを生成。
chromeのディベロッパーツールのconsoleから、contribute()を実行します。
require(msg.value < 0.001 ether); の条件がありますので、0.001etherより小さい値を送る必要があります。
非同期処理なので、awaitをつけるのを忘れずに。
|
getContribution()で確認
現在のcontributionsの数をgetContribution()で確認できます。
|
wordsに値が入っていることが確認できました。
sendTransaction()
contributionsの値が0より大きくなったことが確認できました。
これで、sendTransaction()を実行できるはずです。
以下のように実行してみます。
|
うまく実行できたら、これでオーナー権限を奪えているはずです。
ownerを確認する
オーナーを奪えたかどうか確認します。
オーナーのアドレスとplayerのアドレスが一致していることが確認できます。
これでオーナーを奪うことができました。
withdraw()を実行する
最後に
|
を達成するために、withdraw()を実行します。
|
オーナーしか実行できないfunctionになっています。
しかしオーナー権は奪っているので、実行できるはず。
|
を実行します。
コントラクトの残高を確認
しっかり0になっているかどうか、確認します。
|
0になっていることが確認できました。
最後にSubmit Instanceをすると、
こんな画面がでてきたら、問題クリアです!
最後に
今回はEthernautの1問目Fallbackを解いてみました。
最初の問題ということもあり、難易度は低めでしたね。
次回は2問目を解いていけたらと思います。
最後まで読んでいただき、ありがとうございました!
株式会社Fusicでは一緒に働くエンジニアを募集しています!
福岡での就職・転職に少しでも興味のある方は、
ayasamind宛のDM、Fusic公式サイトのお問い合わせなど、お気軽にご相談ください。