📑

スマーコントラクト脆弱性記事まとめリンク(随時更新)

2023/05/03に公開

前置き

スマートコントラクトを対象としたバグバウンティプログラムの学習用まとめリンク
読んだ分析レポートからキーワードを抽出し、頻出・傾向をつかむことを目的としています
ネストの子要素は概要と自分が読んだメモや感想。★は個人的に読んでよかったと思ったもの。
自習用途なので間違いはあしからず。指摘は歓迎

リソースはImmunefiDiscordMediumと、ここから拾ってきたものが主です
機械学習で脆弱性を検知させるだとか、高度すぎそうなものは避けています。(読んだけど得るものが何もなかったものも)

なお、自分はSolana住みのRust育ちでEVMの仕様だとかSolidityもほとんどナニモワカナイ状態から読んでいます。ホントならRustとかSolanaの記事読みたいのですが、ほぼお目にかかれないです

走り書きスペース

語句の定義など他忘れちゃいけなさそうなのをとりあえず放り込んでおく場所

- 再入可能(リエントラシー)攻撃。コントラクトが別のコントラクトを呼び出し、元のコントラクトの状態が適切に更新される前に、呼び出されたコントラクトが元のコントラクトをコールバックするたびに再入可能性が発生します
- require() は、実行時にのみチェックできる条件を検証するために使用されます。条件が満たされない場合、例外がスローされ、未使用のガスが送信者に払い戻されます。 assert() は、不変条件と内部エラー チェックにのみ使用されます。エラーが発生すると、トランザクションは失敗し、送信者にガスを返金せずに状態の変更が元に戻されます。 revert() は require に似ていますが、ビジネス ロジック エラーの処理に使用されます。内部エラーチェックには require() と revert() を使用すべきではなく、外部入力のチェックには assert() を使用すべきではありません
- 現在、Ethereum Dappsのための最も人気のあるテストフレームワークの中には、Truffle,Embark,Etherlimeがあります
- OpenZeppelin:スマートコントラクト開発、デプロイ、アップグレードを容易に行うことができる開発者向けのツールキット。また、ローカル開発環境をセットアップし、スマートコントラクトのテストやデバッグを支援する機能も提供している

追加用テンプレート

キーワード//hoge

概要:
メモや感想


脆弱性の分類

スマートコントラクトの脆弱性を理解してBugハンターになろう

日本語//包括的//脆弱性の分類//ベストプラクティス★★★

概要:頻出する脆弱性を、種別毎にひとつずつ丁寧に解説している
神によって書かれし聖典。脆弱性やDefiといったテーマに限らず、他の技術系ブログや記事と比較しても突出して分かりやすい。個人的には、どういった解説記事を書くと分かりやすいかといったことまでお手本を示してくれているので、もはや神である。必読。

Ethereum Smart Contract Security Best Practices

包括的//脆弱性の分類//ベストプラクティス//アンチパターン★★

概要:脆弱性種別毎のベストプラクティスとアンチパターン
分類ごとに簡単なコードが挙げられており、GoodパターンとBadパターンが併記されているので理解しやすい。上述の「Bugハンターになろう」シリーズと共通する部分も多いので併せて読むことをおすすめする。

Coinbugs: Enumerating Common Blockchain Implementation-Level Vulnerabilities

ブロックチェーン//包括的//脆弱性の分類★

概要:BTCで過去にあった事例や理論上考えられる脆弱性を分類毎に解説したもの
良記事。マークルツリーや整数オーバーフローなどスマコンにも共通するものから、ネットスプリットやコンセンサスに関わるものまで網羅している。チェーンに焦点を当てているのでより高度だが、例えば大型アップデート時にチェーンが止まる事案(solana 2023/Febなど)の根本的原因を知れたのは良かった

Security checklists for Ethereum smart contract development: patterns and best practices

セキュリティパターン//プロキシコントラクト//脆弱性の分類★

概要:デザインパターン的な脆弱性の分類とチェックリスト
これもなかなか良記事。EVM(全部かは知らない)は一度デプロイしたらスマコンをアップデートできないので、プロキシを挟んで変更するらしいというのがここでも出てくる。バグが発生しやすそうなパターンを表にしてくれて、ちゃんと定義まで書かれているので体系的でわかりやすい。が、哀しいかな。PDFだと手元に置いといて参照するのが面倒なんすよ...。

CryptoFin's Solidity Auditing Checklist

チェックリスト//ハイリスクエリア//脆弱性の分類

概要:脆弱性のチェックリスト
2分で読める。参照用で手元に置いとくとたぶん幸せになれるやつ。

DeFi Developer RoadMap

包括的//まとめリンク ☆☆☆

概要:EVM系学習リソースをすべて網羅していると言えるリンク集
包括的という意味でこちらに分類。前書きにもリンクを貼ったがあまりに凄まじいのでここでも言及しておく。
EVMで開発を志すすべての人を、その圧倒的物量で絶望の底へ叩き落してくれること間違いなし。活字中毒なところがある自分は、豊富なリソースなどを見ると普通なら骨っこを与えられた犬のように尻尾を振るのだが、こいつを見たときはさすがにちょっと引いた。活字中毒じゃない人だとおそらく失神してしまうと思われるので、リンク先を見る際は注意が必要。底のない沼へと引きずり込まれてしまう恐ろしいリンク集。※個人の感想です。

テストツール/フレームワーク

Ethereum Developer Tools List

ツールまとめリンク//包括的//日本語★★

概要:あらゆるツールやフレームワークのまとめリンク
ツールに限らず、FaucetにRPCにIDEにと幅開く揃っているので、EVMで何か必要になったらここ見ればよさそう。ひと言概要も付いており探しやすい上、日本語ページも用意されているという心の配りよう。上の化け物リンク集が予備校教師なら、こちらは優しい家庭教師のお姉さん。これくらいならワクワクできるのでちょうどいい。

Library Driven Development in Solidity

ライブラリ//モジュール開発//コンポーネント//Zeppelin

概要:モジュールで再利用可能なシステム開発をしようぜという提唱
他を読んでいてもしょっちゅうZeppelinというワードが出てくる。似たコントラクトを何個もあげるんじゃなく、オンチェーン上にライブラリをデプロイしてそれをモジュールみたいに使えばいいじゃん、ということをやりだしたのがZepplinなのである。それをおそらく5年前に書かれた記事で私は知ったのであった。
確かにこれができればガス代節約できるし、チェーンのスケーリング向上にもひと役買うし、セキュリティセーフだしと良いこと尽くめである。で、5年経った今現在そのへんがどうなっているのかということを私はまだ何も知らないのであった(ズコーッ)

Profiling Gas Leaks in Solidity Smart Contracts

ツール//GasMet//ガス消費削減

概要:コントラクトのガス消費を削減するためのTIPSと最適化ツールGasMetの紹介
脆弱性とは関係ないが、Botter目線ではおもしろなので読んだ。後半はアンケート調査とツール紹介なので目を通したのは前半部分だけ。
とはいえ、ガス削減効果のあるコードの書き方(e.g. 抽象化、ループで高価な計算は避ける、パブリック変数はコスト高い)など表にしてまとめてくれてるので、そこだけでも目を通しておくといいことあるかも

SuMo: A Mutation Testing Strategy for Solidity Smart Contracts

ツール//SuMo//ミューテーションテスト

概要:ミューテーションテストのためのツールSuMoの紹介
Solidityのスマートコントラクト内のプログラムを、条件文の演算子や算術子を入れ替えたりして改変(変異)させて、その違いを検出してテストするためのツールらしい。SuMoの解説については正直何言ってるのかさっぱりだったが、最初の方はETH全般の基礎知識みたいなものも解説してくれてるので読んで損はない。

The Eye of Horus: Spotting and Analyzing Attacks on Ethereum Smart Contracts

ツール//Horus//トランザクショントラッカー

概要:トランザクショントレース用フレームワークHorusの紹介
Horusについては未リサーチ。他の記事でも出てくるようなら調べてみるか

詐欺/ハニーポット

Targeting the Weakest Link: Social Engineering Attacks in Ethereum Smart Contracts

ソーシャルエンジニアリング攻撃//ハニーポット//詐欺

概要:人間の視覚バイアスを利用した詐欺や悪意のあるコントラクトで資金を盗む手法の分析
コントラクトそのものが悪意のある人物によって作られているといった前提なので、脆弱性ではなく詐欺案件かと。だがやっていることはなかなか高度で、類似したEOAアドレスを提示しそこへ被害者からの送金を促すわけだが、当然そこへ送られてきても秘密鍵がわからないと回収できない。そこでスマコンを間に挟んで、自己破壊命令時に攻撃者の元へ送られてくるようにするみたいなことらしい。
他にも無害なこと(ロギング等)をやっているように見せかけて、その関数内で悪いことやっているなどあるようだが、大まかな流れは把握できても、個々の細かな"仕掛け"についてまでは理解が及ばない。

分類保留

再入可能性(リエントランシー)

Reentrancy Attacks and The DAO Hack

事後レポート(失敗)//再入可能性//DAO//ETHハードフォーク事案★

概要:悪名高いDAOハックの解説記事
イーサリアムクラシック誕生の契機となったハックだが、使用された再入可能攻撃は今日ではもはや教科書に載るレベルの基本と言っていいくらいには単純なもので、自分でも理解できた。かるでねさんのこちらの記事を読むことでより理解が深まるので必読

XSURGE on the BSC Chain was Attacked by Lightning Loans — A Full Analysis

事後レポート(失敗)//再入可能性//フラッシュローン//造幣//XSURGE事案

概要:XSURGEが13111BNBハックされた事案の解説

ずっとスワッププールだと思って読んでたので???だったが、途中でMint&Burnの担保型トークンであることに気付いてやっと理解できた。参照した方はコードが小さすぎて読めないので、こちらも併せて読むことを推奨。
Sellされた時に、発行している総SURGEから売却された枚数を差し引く(Burn)わけだが、その更新をする前にBNBを送ってしまっているので、fallback(再帰)で買われてしまう。その時の発行レートが総発行量*(入力BnB/金庫BnB)という計算式。
つまり買って売って買うと、1回目に買った時より多いSURGEが手に入る。これをループさせて膨れ上がらせ最後にまとめて売って、BNBローン返却

オラクル攻撃/価格操作

Understanding Liquidity Pools, AMMs, Vaults, and the yDAI Exploit

流動性プール//ステーブル//フラッシュローン//Curveプロトコル

概要:流動性プールの基本的な概要と、ステーブルプールを用いた攻撃プランの説明
ステーブルプールは基本マルチトークン型だが、トークンがどちらかに偏った時にペナルティとしてスリッページが発生する仕様らしい。それをフラッシュローンを使ってExploitするみたいだが、脆弱性というよりはそもそもの仕様に欠陥があったような気はする。一時的に引き出し手数料が無料になったのがきっかけだったようで、個人的にはこれは合法だろうと思う。マルチ型のステーブルプール自体は多いので、読んでおく価値はある

So you want to use a price oracle

オラクル//包括的//概略//事例紹介

概要:オラクルの概要と価格操作による事案、ソリューションの紹介
オラクルとは何ぞやといった説明。ここで取り上げられた事案の詳細は、下記記事へ。最初にこれを読んで大まかに雰囲気を掴んでおくと理解しやすい

The bZx attacks explained

事後レポート(失敗)//オラクル//フラッシュローン//bZxハック事案

概要:bZxで起こったオラクル攻撃事案の解説($100万規模)
上記記事で取り上げられた事案の分析。関連してエクスプロイトが2つ起こっている。1回目がbZx(たぶんPerpプロトコル)でETHを担保に5倍のBTCショートを打つ → プロトコルが内部でUniでスワップしてヘッジ用のWBTCを用意する→極大スリッページをプロトロコル側が負担 → フラッシュ&レンディングで借りておいたWBTCを売って得たETHを返却といった流れ。複雑そうに見えるが、やっていることはセルフフロントランニングの裁定取引みたいなもの。スリッページが大きいときの論理チェックにバグがあったよう。ETHを返却したあとも、借りたWBTCを返済できたらETHを回収できるというレンディング(Compound)のborrowが残るので、その回収のために2発目のオラクル攻撃へと繋がる。1つ目と2つ目が同一人物かは定かでないらしいが、まぁ一緒だろうと思う

Accidentally stepping on a DeFi lego

事後レポート(成功)//オラクル//論理エラー//流動性トークン//yEarn事案

概要:yEarnの価格設定アルゴリズムに欠陥のあったバグの解説
リリース直後に開発者自らバグに気付いた、であってるのかわからないが実際に被害があったわけではないよう。Balancerが発行する利回り用流動性トークン(BPT)に基づいて、yUSDCのレートが変動する。BPTを直接どうこうするわけではないのがミソ。以下流れ。
先にyUSDC買っておく → バランサーでUSDCをMUSDに大量交換する → 損失が出るが交換したMUSDをそっくりUSDCにまた戻せば多少の額で済む → だがMUSDへ交換した直後はBPTの価値が上がっており、yUSDCは良いレートでUSDCに戻せる → MUSDを買って売った時に出る損失よりもyUSDCを買って売った利益の方が大きいのでループさせれば錬金術ができるというバグ。自分で鞘を作って自分で埋めるんだけど、その間に違うところで影響が出るので利益が取れるというカラクリ。yUSDCとMUSDがそれぞれ違うものを参照して価格決定していることによる構造的な問題かな。

Yield Skimming: Forcing Bad Swaps on Yield Farming

事後レポート(成功)//価格操作//流動性プール//リバランス型//Vesper事案

概要:リバランス型流動性プールの価格操作によって利鞘をとる分析レポート
流動性プールのharvest()を誰でも呼び出せたようで、これはリバランスで偏った方のトークンをスワップする処理が走るもの。呼び出す前に売っておいて、これを呼び出しさらに下がったところを余分に買い戻すというもの。難しいことは特にないかと

Fei Protocol Flashloan Vulnerability Bugfix Review

事後レポート(成功)//フラッシュローン//アルゴリズムステーブル//ボンディングカーブ//Feiプロトコル

概要:バグハントに成功($80,000)した事案の分析レポート
allocate()関数が呼び出されることで、FEI/ETH価格が自動調整されるアルゴリズムだったらしいが、この価格調整のチェックをバイパスして価格操作できたよう。偽のコントラクトを用意し、借りたETHをUniswapプールに投入→FEI高騰→プロトコルの方でFEI買う→ダミーでallocate()を呼び出すとUniswapに基づいてプロトコルがFEIの値段を上げる(Burn)→買ってたのを売る→UniからETH回収、というのが大まかな流れっぽいが、最初にETH入れたプールとは異なるPCV(ETH)/FEIプールとかボンディングカーブ(参考)とか、シグモイド関数とか出てきて、ちゃんと理解するにはその辺りの実装とか見る必要がある雰囲気。またダミーコントラクトがどんな役割したのか不明。つまりナニモワカランムツカシイ

A Guide to Reproducing Ethereum Exploits: Fei Protocol

ローカルフォーク//HardHat//再現手法//Feiプロトコル

概要:上述のFei事案を再現するためのガイド
ETHのローカルフォーク作ってPoCコードを動かして実際にエクスプロイトできるかテストしてみよう!といった手順の解説。Githubにコントラクトのコードがなかったりした場合の代替手段。HardHatはEVMを触るときにちょいちょいテストで見るので、いずれEVMやるなら必読か。なお自分はしばらくRustで挑戦してみようと思っているので後回し

Hack Analysis: BonqDAO, February 2023

事後レポート(失敗)//オラクル//価格操作//BonqDao事案

概要:オラクル価格フィードで好きな価格に操作されてしまった事案の分析レポート
オラクルを「最後に報告のあった価格」を基にフィードしていたため、勝手に価格を上げられて大量にトークンをborrowされたり、逆に価格を下げられてユーザーの清算を誘発されて清算狩りで担保を盗られたりした事案。他のレポートにも言えることだが、価格フィードのアップデートを行う部分のコード(脆弱性のあったところ)はあまりフォーカスされず、PoCの解説が成分として多めになっている。そのへんをもっと見たい。そこまであからさまに欠陥のあるコードではないだろうとは思うのだが、実際他のExploitでもお粗末なものはよく目にするのでこの事案はどうなのかというのは気になる点(シラベナイ)

ブリッジ

Trustless, privacy-preserving blockchain bridges

ブリッジ//ゼロ知識証明//マークルツリー

概要:ブリッジの設計と実装
クロスチェーンブリッジする際の大まかな流れと、ゼロ知識証明について触れられているが、概要程度しか読み解けなかった。コード読んだ方が早そうだなというのが正直な感想。

Hack Analysis: Binance Bridge, October 2022

事後レポート(失敗)//ブリッジ//マークルツリー//IAVL検証//Binanceブリッジ事案

概要:BNPとBSCのクロスチェーンブリッジへのハック
天下のBinance絡みの事案であり、ブリッジがそもそも他の実装よりも複雑なのもあって今の自分の段階では雰囲気しかつかめない。リレイヤーとかも使うらしく、まずはそのへんのブリッジについて造詣を深めないと正しく理解できなさそう。通常はマークルツリーを使うと思うのだが、こちらはIAVL検証という認証を用いていたようでここにバグがあった模様。マークルツリーもよく目にするので、いつか自分で実装して勉強する必要が出てくるだろう

算術/オーバーフロー/丸め誤差

Armor Bugfix Review

事後レポート(成功)//算術//Armor事案

概要:バグハント成功で$100万ドルの報酬が発生した事案の解説
weiをETHの桁に合わせる10の18乗をする時に、すでに引数でETHになってるのをさらに10の18乗しようとしたもんだからそりゃやばいよねって話。バグバウンティプログラム開始からわずか24時間で報告された。そりゃそうだろ。というかこんなんで$100万ドルもらえるんだから、報酬とハント難易度は必ずしも比例しないという良い例。あとCTO喜んでる場合やないだろ。タトゥーいれるとかツッコミどころありすぎる

論理エラー/ロジック

PancakeSwap Lottery Vulnerability Bugfix Review And Bug Bounty

事後レポート(成功)//論理チェック//Lottery(宝くじ)//Pancake事案

概要:Pancakeの宝くじを当選番号を確認してから購入可能なバグ
抽選後はrequire()でちゃんと弾かれるけど、抽選中は弾かれないから宝くじを買えちゃうというものらしい。宝くじの仕様が定かでないので不確かなところはあるが、複数枚購入の関数と単独購入の関数とがあって、単独購入の方はチェックされてて複数枚のにはそれがないのだから、見比べたら簡単に見つけられそうなもの。なおImmunefiと提携してなかったらしく、間にエージェントとして入ってもらって報告したらしい。報酬は非公開

88mph Function Initialization Bugfix Review

事後レポート(成功)//権限//NFTコントラクト//88mph事案

概要:NFTコントラクトの持つ初期化関数を誰でも呼び出せたバグ
コードは見当たらなかったが、initialize()のownerなりのチェックが抜けていたのだろうと思う。初期化して自分をそのコントラクトのオーナーしてしまえば、そのコントラクトをおもいのままにできてしまう。

Zapper Arbitrary Call Data Bugfix Review

事後レポート(成功)//LPトークン//approve//Zappper事案

概要:ウォレットに入っているLPトークンを勝手にトランスファーできるバグ
これもコントラクトのコードは確認していないが、transferFrom()というLPトークンのトランスファー機能を誰でも呼び出せたもよう。被害者はプロトコルからのLPトークンをApproveしているので、LPを持っているだけで被害に会う可能性があった。これも所有者のチェックが抜けていたのだと思われる。PoCのコードが読める。HardHat使えると便利そうだなと思った

SharedStake Insider Exploit Postmortem

事後レポート(成功?)//インサイダー//トークンロック//SharedStake事案

概要:開発チーム用のロックトークンが期間を無視していつでも引き出せたバグ
誰でも引き出せるわけでなく、トークンをロックしている人間、つまり開発チーム関係者だけがこの脆弱性を利用できたよう。4回悪用された形跡があった点といい、修正が2か月近く保留された点といい、いやいや確信犯やろと勘ぐってしまうのは私だけでしょうか

PancakeSwap Logic Error Bugfix Review

事後レポート(成功)//論理チェック//Lottery(宝くじ)//Pancake事案

概要:当選くじ1枚で255回当選金を受け取れるバグ
驚くことなかれ。上述のPancake宝くじ当選番号カンニングバグとは別件である。リンクは張ってないがWebサイトのインジェクションの脆弱性も報告されているので、Pancakeは既にImmunefiのお得意様である。バグ自体は当選くじで当選金を請求しても、請求済みにマークされてないので何回でも受け取れるという単純なもの。Pancakeのコードは自分も目にしたことがあり、あまり良い印象を受けなかったのでその感性は間違っていなかったということなのかもしれん

Beanstalk Logic Error Bugfix Review

事後レポート(成功)//論理チェック//Approve//Beanstalk事案

概要:勝手に他の人がApproveしたトークンをトランスファーできちゃうバグ
内部トラスファーモード(コントラクト内の残高を操作)と、外部トランスファーモード(Approveされているトークン)があり、後者を使用した際にトークンの送信者とTxの送信者が一致しない時のチェックと処理が抜けている、とコードを見るとそんな感じだった。Approveの仕様とかもよく分かってないし、なんならSolidityを1行も書いたことない(オイ)ので、EVMに進出するときにもっと勉強しようと思いましたまる

Balancer Logic Error Bugfix Review

事後レポート(成功)//マークルツリー//論理チェック//Balancer事案

概要:LPのリワード請求時に重複請求のチェックが抜けていてリワードを水増しできたバグ
マークルツリーを使って請求権のプルーフをチェック、Bitmapに請求済みを記録という流れだが、複数の請求を処理する際にloopで配列を処理する。配列の処理が終わるまで請求済みの処理をバイパスできるので、同じ配列に同じ請求を入れたら多重受理できちゃうよねといった感じ。
マークルツリーのデータ構造はこの記事に出てくる図が、これまで見た中では最も分かりやすかった。ひとつひとつの処理までは追って読んでないが、まぁこーゆーのは必要になった時にまたじっくり時間をかけて読めばいいと思って流し読んだ

プロキシコントラクト

Teller Bugfix Review and Bug Bounty Launch

事後レポート(成功)//プロキシコントラクト//自己破壊//Teller事案

概要:ビーコンプロキシに偽コントラクトのアドレスを伝えて破壊するバグ
アップグレードなどでプロキシコントラクトを使うわけだが、このビーコンコントラクトが初期化されておらず、誰でも呼び出せたよう。新しいコントラクトと装ってそのアドレスを渡し、自己破壊命令を出して中のDAI等をGOXさせることができたようだ。プロキシコントラクトが絡んだハックはよく出てくるので(Nomad事案など)、仕様などまで深く掘り下げた記事を読みたい。現時点では理解が浅いので、今後の課題

Discussion