(19)【発行国】日本国特許庁(JP)
(12)【公報種別】特許公報(B2)
(11)【特許番号】
(24)【登録日】2023-03-23
(45)【発行日】2023-03-31
(54)【発明の名称】ブロックチェーンネットワークにおけるスマートコントラクトをサポートするための方法及びコントラクト書き換えフレームワークシステム
(51)【国際特許分類】
G06F 21/57 20130101AFI20230324BHJP
【FI】
G06F21/57 370
(21)【出願番号】P 2021571359
(86)(22)【出願日】2020-06-09
(86)【国際出願番号】 EP2020065993
(87)【国際公開番号】W WO2020249572
(87)【国際公開日】2020-12-17
【審査請求日】2022-01-20
(32)【優先日】2019-06-12
(33)【優先権主張国・地域又は機関】US
(73)【特許権者】
【識別番号】517451940
【氏名又は名称】エヌイーシー ラボラトリーズ ヨーロッパ ゲーエムベーハー
(74)【代理人】
【識別番号】100124811
【氏名又は名称】馬場 資博
(74)【代理人】
【識別番号】100088959
【氏名又は名称】境 廣巳
(74)【代理人】
【識別番号】100097157
【氏名又は名称】桂木 雄二
(74)【代理人】
【識別番号】100187724
【氏名又は名称】唐鎌 睦
(72)【発明者】
【氏名】オドラー ミヒャエル
(72)【発明者】
【氏名】ダヴィ ルカ
(72)【発明者】
【氏名】カラメ ガッサン
(72)【発明者】
【氏名】リ ウェンティン
【審査官】中里 裕正
(56)【参考文献】
【文献】特開2005-38428(JP,A)
【文献】特開2013-134573(JP,A)
【文献】特開2019-053729(JP,A)
【文献】特開2016-167262(JP,A)
【文献】国際公開第2018/172439(WO,A1)
【文献】中国特許出願公開第108536445(CN,A)
【文献】TSANKOV, P. et al.,SECURIFY: Practical Security Analysis of Smart Contracts,arXiv,1806.01143v2,2018年08月24日,pp.1-16,<URL:https://arxiv.org/abs/1806.01143v2>
【文献】PEREZ, D. and LIVSHITS, B.,Smart Contract Vulnerabilities: Does Anyone Care?,arXiv,1902.06710v3,2019年05月17日,pp.1-15,<URL:https://arXiv.org/abs/1902.06710v3>
【文献】PERKINS, J. H. et al.,Automatically Patching Errors in Deployed Software,Proc. of the 22nd ACM SIGOPS Symposium on Operating Systems Principles,2009年10月11日,pp.87-102
【文献】MONPERRUS, M.,Automatic Software Repair: A Survey,IEEE Transactions on Software Engineering,2019年01月01日,Vol.45 No.1,pp.34-67
(58)【調査した分野】(Int.Cl.,DB名)
G06F 21/57
JSTPlus/JMEDPlus/JST7580(JDreamIII)
IEEE Xplore
THE ACM DIGITAL LIBRARY
(57)【特許請求の範囲】
【請求項1】
トランザクションを検証する各ノードがスマートコントラクトを実行するための仮想マシンを実行するよう構成されており、前記ノードを有する分散型のブロックチェーンネットワークにおけるスマートコントラクトをサポートするための方法であって、
脆弱性検出ツール、リライタツール、および、デプロイコンポーネントを含むコントラクト書き換えフレームワークシステムが提供されており、
前記デプロイコンポーネントが、スマートコントラクトの作成フェーズ中に、当該スマートコントラクトの作成者及び/又は所有者によって与えられる当該スマートコントラクトをアップグレードする許可を取得し、
前記コントラクト書き換えフレームワークシステムが、前記ブロックチェーンネットワークから前記スマートコントラクトを取得して、当該スマートコントラクトを前記脆弱性検出ツールに渡し、
前記脆弱性検出ツールが、前記スマートコントラクトの脆弱性を検出して、当該脆弱性のタイプと当該脆弱性の命令位置を検出し、
前記リライタツールが、前記脆弱性を修正するためのパッチを含むよう前記スマートコントラクトを書き換えて、前記脆弱性のタイプと前記脆弱性の命令位置に基づいてパッチ適用スマートコントラクトを生成し、
前記デプロイコンポーネントが、前記パッチ適用スマートコントラクトが前記ブロックチェーンネットワークにデプロイされるよう、前記パッチ適用スマートコントラクトを含むアップグレードトランザクションを前記ブロックチェーンネットワークに発行する、
方法。
【請求項2】
請求項1に記載の方法であって、
前記コントラクト書き換えフレームワークシステムが取得する前記スマートコントラクトは、バイナリ形式であり、特にバイトコードのスマートコントラクトコードである、
方法。
【請求項3】
請求項1又は2に記載の方法であって、
前記リライタツールが生成する前記パッチ適用スマートコントラクトは、バイナリ形式、特にバイトコードの新規な、及び/又は、変更されたスマートコントラクトコードである、
方法。
【請求項4】
請求項1乃至3のいずれかに記載の方法であって、
前記パッチ適用スマートコントラクトは、オリジナルのスマートコントラクトコードの脆弱ブロックを置き換えるためのバイナリ形式、特にバイトコードのパッチ適用コードが準備されることによって生成される、
方法。
【請求項5】
請求項1乃至4のいずれかに記載の方法であって、
前記脆弱性の命令位置がプログラムカウンタを含む、
方法。
【請求項6】
請求項1乃至5のいずれかに記載の方法であって、
前記ブロックチェーンネットワークから前記コントラクト書き換えフレームワークシステムによって取得された前記スマートコントラクトが前記リライタツールに渡され、
前記リライタツールが前記脆弱性のタイプと前記脆弱性の命令位置とに基づいて前記スマートコントラクトにパッチを適用して、前記パッチ適用スマートコントラクトを生成する、
方法。
【請求項7】
請求項1乃至6のいずれかに記載の方法であって、
前記脆弱性の命令位置が解読されている間に、前記リライタツールが前記スマートコントラクトを中間表現にリフトされ、
前記中間表現にパッチコード片を含めた後に、当該中間表現がバイナリ形式にコンパイルされることで、前記パッチ適用スマートコントラクトが生成される、
方法。
【請求項8】
請求項1乃至7のいずれかに記載の方法であって、
前記リライタツールが、前記スマートコントラクトの末尾の未使用アドレス領域にパッチコード片を追加し、
前記リライタツールが、前記スマートコントラクト内の脆弱コードを、命令ポインタが前記パッチコード片にジャンプするよう構成されたトランポリンジャンプに置き換え、
前記パッチコード片の実行が終了すると、前記命令ポインタは前記スマートコントラクトの元の後続コードにジャンプして戻り、前記スマートコントラクトの残り部分の実行を続行する、
方法。
【請求項9】
請求項1乃至8のいずれかに記載の方法であって、
前記コントラクト書き換えフレームワークシステムの前記デプロイコンポーネントは、前記ブロックチェーンネットワークの前記スマートコントラクトをアップグレードするために使用される予め設定されたアカウントを務め、アップグレードトランザクションが前記予め設定されたアカウントによって署名された場合に、取得された前記スマートコントラクトから前記アップグレードトランザクションが前記ブロックチェーンネットワークのノードによって受け入れられる、
方法。
【請求項10】
請求項1乃至9のいずれかに記載の方法であって、
スマートコントラクトをデプロイするための予め設定されたアドレスが定義されており、前記予め設定されたアドレスに送信されたトランザクションが、前記スマートコントラクトをアップグレードするための前記アップグレードトランザクションとされる、
方法。
【請求項11】
請求項1乃至10のいずれかに記載の方法であって、
アップグレードトランザクションが、前記パッチ適用スマートコントラクト及びアドレスAddrを含むペイロードを有する、
方法。
【請求項12】
請求項11に記載の方法であって、
前記アップグレードトランザクションを受信した前記ブロックチェーンネットワークの前記ノードが、前記アップグレードトランザクションに基づいてアドレスAddrで元の前記スマートコントラクトを確認して、前記デプロイコンポーネントによって示された前記予め設定されたアカウントを取得する、
方法。
【請求項13】
請求項11又は12に記載の方法であって、
前記ブロックチェーンネットワークの前記ノードが、前記アップグレードトランザクションの署名を検証し、前記アップグレードトランザクションが有効である場合に、前記ブロックチェーンネットワークの前記ノードが、アドレスAddrの前記スマートコントラクトを前記パッチ適用スマートコントラクトに置き換える、
方法。
【請求項14】
請求項1乃至13のいずれかに記載の方法であって、
前記コントラクト書き換えフレームワークシステムは、さらにパッチ検証者を含み、前記リライタツールが、前記パッチ適用スマートコントラクトを前記パッチ検証者に渡し、前記パッチ検証者が、元の前記スマートコントラクトに送信されたトランザクションを抽出して再実行し、元の前記スマートコントラクトと前記パッチ適用スマートコントラクトから収集された実行トレースを比較し、それらが異なる状態の更新とならないことを検証し、前記パッチ適用スマートコントラクトによって元に戻される悪意のあるトランザクションを除き、前記パッチ検証者が前記パッチ適用スマートコントラクトのロジックの一貫性を確認する、
方法。
【請求項15】
請求項1乃至14のいずれかに記載の方法を実行する、ブロックチェーンネットワークにおけるスマートコントラクトをサポートするためのコントラクト書き換えフレームワークシステムであって、
前記ブロックチェーンネットワークは、ノードを有する分散型ブロックチェーンネットワークであり、
トランザクションを検証する前記各ノードは、スマートコントラクトを実行するための仮想マシンを実行するよう構成され、
さらに、脆弱性検出ツールと、リライタツールと、デプロイコンポーネントと、を備えており、
前記デプロイコンポーネントが、スマートコントラクトの作成フェーズ中に、当該スマートコントラクトの作成者及び/又は所有者によって与えられる当該スマートコントラクトをアップグレードする許可を取得し、
前記コントラクト書き換えフレームワークシステムが、前記ブロックチェーンネットワークから前記スマートコントラクトを取得して、当該スマートコントラクトを前記脆弱性検出ツールに渡し、
前記脆弱性検出ツールが、前記スマートコントラクトの脆弱性を検出して、当該脆弱性のタイプと当該脆弱性の命令位置を検出し、
前記リライタツールが、前記脆弱性を修正するためのパッチを含むよう前記スマートコントラクトを書き換えて、前記脆弱性のタイプと前記脆弱性の命令位置に基づいてパッチ適用スマートコントラクトを生成し、
前記デプロイコンポーネントが、前記パッチ適用スマートコントラクトが前記ブロックチェーンネットワークにデプロイされるよう当該パッチ適用スマートコントラクトを含むアップグレードトランザクションを前記ブロックチェーンネットワークに発行する、
コントラクト書き換えフレームワークシステム。
【発明の詳細な説明】
【技術分野】
【0001】
本発明は、ブロックチェーンネットワークにおけるスマートコントラクトをサポートするための方法及びコントラクト書き換えフレームワークシステムに関する。
【背景技術】
【0002】
ビットコインの採択によりイノベーションが促進され、現在では500を超える代替ブロックチェーンが存在している。特に、分散アプリケーションとしてのスマートコントラクトの拡張定義により、ユーザは、ブロックチェーン内のアプリケーションとともに、さまざまなタイプの支払いシステムと暗号通貨を構築できる。
【0003】
本願においてブロックチェーンのスマートコントラクトに関する現在の技術は、例えば、以下のラベル[1]から[9]の非特許文献を参照している。
[1] C. Jentzsch, "The History of the DAO and Lessons Learned," October 10, 2017. [Online]. https://blog.slock.it/the-history-of-the-dao-and-lessons-learned-d06740f8cfa5.
[2] L. D.-H. C. H. O. P. S. a. A. H. Luu, "Making smart contracts smarter.,", the 2016 ACM SIGSAC conference on computer and communications security, 2016.
[3] P. A. D. D. D.-C. A. G. F. B. a. M. V. Tsankov, "Securify: Practical security analysis of smart contracts," the 2018 ACM SIGSAC Conference on Computer and Communications Security, 2018.
[4] S. S. G. M. D. a. S. S. Kalra, "Zeus: Analyzing safety of smart contracts," 25th Annual Network and Distributed System Security Symposium, 2018.
[5] J. a. C. R. Krupp, "teether: Gnawing at ethereum to automatically exploit smart contracts," 27th USENIX Security Symposium , 2018.
[6] I. A. K. I. S. P. S. a. A. H. Nikolic, "Finding the greedy, prodigal, and suicidal contracts at scale," the 34th Annual Computer Security Applications Conference, 2018.
[7] "Manticore," [Online]. https://github.com/trailofbits/manticore.
[8] "Ethereum Smart Contract Best Practices: Upgrading Broken Contracts," [Online]. https://consensys.github.io/smart-contract-best-practices/software_engineering/#upgrading-broken-contracts.
[9] "ZeppelinOS," [Online]. https://zeppelinos.org/.
【発明の概要】
【発明が解決しようとする課題】
【0004】
ブロックチェーンに関してこのように広く採用されている状況では、イーサリアムなどの人気のあるブロックチェーンプラットフォームの利用において、コントラクトの脆弱性を悪用して暗号通貨を盗む攻撃者の標的になることがよくある。特に重大な事件の1つとしてDAO攻撃があり、2016年に攻撃が発生した時点で、5000万米ドル相当のEtherが失われている(非特許文献[1]を参照)。それ以来、開発段階および実行時のスマートコントラクトの脆弱性を検出するために、非特許文献[2],[3],[4]に記載されているような多くの静的および動的分析ツールが提案されている。このようなアクセス制御の脆弱性の自動検出も、自動的不具合生成の分野で以前より研究されている(例えば、非特許文献[5],[6]を参照)。
【0005】
スマートコントラクトは、ほぼ任意(チューリング完全)のビジネスロジックを実装できるようにするために、最新のブロックチェーンシステムで使用される。それらは、暗号通貨またはトークンの自律管理を可能にし、たとえば支払い、保険、クラウドファンディング、サプライチェーンのアプリケーションにおいて、信頼できる(悪意があるかもしれない)サードパーティの必要性を排除することにより、多くのビジネスアプリケーションに革命を起こす可能性がある。これらの使いやすさとこれらのコントラクトが保持する高い暗号通貨の価値のために、スマートコントラクトは攻撃の魅力的なターゲットになっている。スマートコントラクトコードのプログラミングエラーは、攻撃者がこれらのバグを悪用して暗号通貨やトークンを盗む可能性があるため、壊滅的な結果をもたらす可能性がある。
【0006】
最近では、ブロックチェーンコミュニティでスマートコントラクトエラーによるいくつかの事件を目撃している。上述したように、特に重大な事件の1つは「TheDAO」攻撃であり、その結果、5000万米ドル相当のEtherが失われている。このことは、イーサリアムブロックチェーンの大いに議論されたハードフォークに至っている。再入可能性の脆弱性により、「TheDAO」攻撃が発生する可能性があった。いくつかの提案では、開発時のオフライン分析または実行時検証の実行のいずれかによって、再入可能性の脆弱性を防御する方法を示している。
【0007】
もう1つの重大な事件は、パリティウォレット攻撃である。このケースでは、攻撃者はスマートコントラクトを、コントラクトが保持する通貨にアクセスできない状態に移行した。これによるアクセス制御エラーのために、合計約500kのEtherがスマートコントラクトでスタックすることになった。このようなアクセス制御の脆弱性の自動検出は、自動的不具合生成の分野で以前より研究されている。さらに、整数オーバーフローバグは、スマートコントラクトの重大な脆弱性クラスとなっている。このようなバグは、計算実行の結果が、整数型が保持できるよりも長い幅である場合に発生する。Torresらによる研究によると、42kを超えるコントラクトに整数のバグがある(参考:C. Ferreira Torres, J. Schutte, and Others, “Osiris: Hunting for integer bugs in ethereum smart contracts,” 34th Annual Computer Security Applications Conference (ACSAC18), San Juan, Puerto Rico, USA, December 3-7, 2018, 2018. [Online]. http://orbilu.uni.lu/handle/10993/36757)。これらは特に、イーサリアムでサブカレンシーを作成するために活用される、いわゆるERC-20トークンコントラクトに影響を与える。興味深いことに、開示された脆弱性のほとんどは実際に悪用され、トークンとEtherの大幅な損失につながっている。
【0008】
これらの攻撃は、スマートコントラクトのセキュリティを強化するためにコミュニティへの関心を高めている。この点において、より良い開発環境の考案からより安全なプログラミング言語の使用、フォーマル検証、シンボリック実行、動的ランタイム分析に至るまで、多くのソリューションが過去数年間に提案されてきている。それにもかかわらず、これらのソリューションはすべて、特定のタイプの脆弱性の正しさまたは欠如を証明することのみを目的としているため、すでにデプロイされている(レガシー)コントラクトを保護するために使用することはできない。さらに悪いことに、特定のコントラクトが脆弱であるとフラグが立てられると、それをアップグレードする方法が不明確になる。単純なアプローチでは、コントラクトの所有者が脆弱なコントラクトを廃止し、すべての資金をコントラクトから外し、新しいコントラクトをデプロイし、資金を新しいコントラクトに移動する必要がある。脆弱なコントラクトのアドレスが他のコントラクトによって参照されている場合、このプロセスはさらに悪化することとなる。さらに、開発者は、パッチが適用されたバージョンのコントラクトが、以前にデプロイされたバージョンと互換性があることを確認する必要もある。ソースコード内の変数の順序を変更するなどの小さな変更でさえ、すでにこの互換性を損なう可能性がある。その結果、スマートコントラクトエラーへのパッチ適用は、現在、時間がかかり、面倒であり、エラーが発生しやすいプロセスである。たとえば、Parityマルチシグウォレットコントラクトにパッチを適用しているときに、開発者が誤って別のバグを導入したためにEtherが失われており、これは単に関数の名前が間違っていることによる。
【0009】
その上、スマートコントラクトのバグにパッチを適用することは非常にタイムクリティカルである。PCまたはモバイルソフトウェアで発見されるエラーとは対照的に、スマートコントラクトエラーは、以下のように攻撃者の観点からは独特である。(1)スマートコントラクトは常にブロックチェーン上でオンラインである。(2)通常はかなりの量の資産を保持している。(3)攻撃者は他の環境変数(例えば、ソフトウェアとライブラリのバージョン、ネットワークトラフィック分析、ユーザーアクションを通じてエクスプロイトをトリガーするスパムまたはフィッシングメールなど)を考慮する必要はない。
【0010】
したがって、スマートコントラクトにより、信頼できるサードパーティが関与することなく、ブロックチェーン上でビジネスロジックを確実に実行できる。しかし、最近のいくつかの攻撃は、スマートコントラクトコードのエラーを悪用し、壊滅的な結果をもたらし、それによって、このテクノロジーの利点に疑問を投げかけている。特に、現在では、エラーを修正し、パッチを適用したコントラクトを期限内にデプロイすることは非常に困難である。インスタントパッチは、2つの理由からスマートコントラクトにとって特に重要である。つまり、スマートコントラクトはブロックチェーンシステムの分散性のために常にオンラインであり、スマートコントラクトはかなりの量の資産を管理している、ということから、危険にさらされており、法の原則のために回復できないことがよくある。
【0011】
スマートコントラクトをアップグレードするための既存のソリューションは、手動および/またはエラーが発生しやすいプロセスで構成されている。このため、上記を考慮して、本発明の目的は、脆弱性および/または欠陥のあるスマートコントラクトの取り扱いが改善されるような方法で、ブロックチェーンネットワークにおけるスマートコントラクトをサポートするための上述したタイプの方法及びコントラクト書き換えフレームワークシステムを改善し、さらに開発することである。
【課題を解決するための手段】
【0012】
本発明によれば、上述した目的は、ブロックチェーンネットワークにおいてスマートコントラクトをサポートするための方法によって達成される。このとき、ブロックチェーンネットワークは、ノードを有する分散ブロックチェーンネットワークであり、トランザクションを検証する各ノードは、スマートコントラクトを実行するための仮想マシンを実行する。本発明では、コントラクト書き換えフレームワークシステムが提供され、当該コントラクト書き換えフレームワークシステムは、脆弱性検出ツール、リライタツール、およびデプロイコンポーネントを含み、上記方法は、以下を含む。
デプロイコンポーネントが、スマートコントラクトの作成フェーズ中に、当該スマートコントラクトの作成者及び/又は所有者によって与えられる当該スマートコントラクトをアップグレードする許可を取得し、コントラクト書き換えフレームワークシステムが、ブロックチェーンネットワークからスマートコントラクトを取得して、当該スマートコントラクトを脆弱性検出ツールに渡し、脆弱性検出ツールが、スマートコントラクトの脆弱性を検出して、当該脆弱性のタイプと当該脆弱性の命令位置を検出し、リライタツールが、脆弱性を修正するためのパッチを含むようスマートコントラクトを書き換えて、脆弱性のタイプと脆弱性の命令位置に基づいてパッチ適用スマートコントラクトを生成し、デプロイコンポーネントが、パッチ適用スマートコントラクトがブロックチェーンネットワークにデプロイされるよう、パッチ適用スマートコントラクトを含むアップグレードトランザクションをブロックチェーンネットワークに発行する。
【0013】
さらに、上述した目的は、ブロックチェーンネットワークにおいてスマートコントラクトをサポートするためのコントラクト書き換えフレームワークシステムによって達成される。このとき、ブロックチェーンネットワークは、ノードを有する分散ブロックチェーンネットワークであり、トランザクションを検証する各ノードは、スマートコントラクトを実行するための仮想マシンを実行する。本発明では、コントラクト書き換えフレームワークシステムが提供され、当該コントラクト書き換えフレームワークシステムは、脆弱性検出ツール、リライタツール、およびデプロイコンポーネントを含む。
デプロイコンポーネントは、スマートコントラクトの作成フェーズ中に、当該スマートコントラクトの作成者及び/又は所有者によって与えられる当該スマートコントラクトをアップグレードする許可を取得する。コントラクト書き換えフレームワークシステムは、ブロックチェーンネットワークからスマートコントラクトを取得して、当該スマートコントラクトを脆弱性検出ツールに渡す。脆弱性検出ツールは、スマートコントラクトの脆弱性を検出して、当該脆弱性のタイプと当該脆弱性の命令位置を検出し、リライタツールは、脆弱性を修正するためのパッチを含むようスマートコントラクトを書き換えて、脆弱性のタイプと脆弱性の命令位置に基づいてパッチ適用スマートコントラクトを生成する。デプロイコンポーネントは、パッチ適用スマートコントラクトがブロックチェーンネットワークにデプロイされるよう、パッチ適用スマートコントラクトを含むアップグレードトランザクションをブロックチェーンネットワークに発行する。
【0014】
本発明によれば、ブロックチェーンネットワークにおけるスマートコントラクトの処理に関して、デプロイされたコントラクトにタイムリーにパッチを適用することによって、大幅な改善を達成できることが認識されうる。ブロックチェーンネットワークは、ノードを持つ分散ブロックチェーンネットワークであり、トランザクションを検証する各ノードは、スマートコントラクトを実行するための仮想マシンを実行するよう構成されている。本発明によれば、コントラクト書き換えフレームワークシステムが提供され、コントラクト書き換えフレームワークシステムは、脆弱性検出ツール、リライタツール、デプロイコンポーネントを含む。デプロイコンポーネントは、スマートコントラクトをアップグレードするためのアクセス許可を取得する。つまり、スマートコントラクトの作成者または所有者、あるいはその両方が、デプロイコンポーネントにコントラクトにアップグレードする権限を付与する。これは、スマートコントラクトの作成フェーズで行われる。コントラクト書き換えフレームワークシステムは、ブロックチェーンネットワークからスマートコントラクトを取得し、スマートコントラクトは脆弱性検出ツールに渡される。脆弱性検出ツールは、スマートコントラクトの脆弱性を検出するよう構成されており、さらに脆弱性検出ツールは、脆弱性のタイプと脆弱性の命令位置を検出する。そして、リライタツールは、スマートコントラクトをリライトして、脆弱性を修正するためのパッチを適用する。パッチが適用されたスマートコントラクトは、脆弱性のタイプと脆弱性の命令位置に基づいて、リライタツールによって生成される。その後、デプロイコンポーネントは、パッチが適用されたスマートコントラクトを含むアップグレードトランザクションをブロックチェーンネットワークに発行し、パッチが適用されたスマートコントラクトがブロックチェーンネットワークにデプロイされる。
【0015】
このようにして、本発明は、ブロックチェーンネットワークにおいてスマートコントラクトをサポートするための方法およびコントラクト書き換えフレームワークシステムを提供し、脆弱なおよび/または欠陥のあるスマートコントラクトの処理が改善される。
【0016】
本発明の実施形態では、ブロックチェーンネットワーク内に展開されたコントラクトにタイムリーにパッチを適用することができる。本発明の実施形態によるフレームワークは、ソースコードを必要とせず、特定のコンパイラから独立している。また、実施形態では、EVMバイトコードレベルで動作する分析ツールと互換性があり、非推奨のコントラクトから新しいコントラクトに資金を手動で移動する必要がない。
【0017】
本発明の実施形態では、イーサリアムに展開されたすべてのスマートコントラクトの中で、主要なクラスのコントラクトは、いわゆるERC-20トークンコントラクトであると考えられる。これらのコントラクトは、指定されたインターフェイスのセットを実装し、Ethereumプラットフォームでカスタマイズされたサブ通貨を管理するために使用される。ただし、このようなトークンを正しく実装することは大きな努力である。過去数年間、ERC-20トークンにさまざまな脆弱性が見つかった。これらの脆弱性の大部分は、整数オーバーフローのバグによるものであった。経済的損失の可能性があるため、脆弱性を修正するためにスマートコントラクトにタイムリーにパッチを適用する必要がある。ただし、スマートコントラクトのアップグレードは、イーサリアムなどの許可のないブロックチェーンシステムでは簡単なプロセスではない。スマートコントラクトは通常、デプロイされると不変と見なされる。イーサリアムのスマートコントラクトをアップグレードするには、スマートコントラクト自体がアップグレードを容易にするコードを実装する必要がある。多くの場合に問題となる複数のアップグレード方法がある(たとえば、上記の文献[7]および[8]を参照)。文献[9]などのコントラクトアップグレード機能を提供する一部のフレームワークは、複雑さを隠すことによって、文献[8]の手法を採用している。スマートコントラクトが安全なアップグレードパスを実装している場合でも、パッチをデプロイできるようになるまでの時間はかなり長くなる可能性がある。しかしながら、本発明の実施形態では、ブロックチェーン内にデプロイされたスマートコントラクトに自動的にパッチを適用してアップグレードするためのコントラクト書き換えフレームワークを含む。これにより、開発者はスマートコントラクトの強化されたバリアントを半自動的にデプロイし、考えられる脆弱性にタイムリーにパッチを適用できる。
【0018】
ここで、「トランザクション」という用語は、最も一般的な意味で理解されるべきであり、特許請求の範囲や明細書において参照され、例えば、トランザクションを送信するノードに接続されたノードなどのネットワークに、送信され、または、伝送される情報を指す。そして、トランザクションは、メッセージ、データパケットなどの形式で提供され、トランザクションの受信者のための情報を含む。
【0019】
「ブロックチェーン」という用語は、特に特許請求の範囲や明細書において、データベースをホストするデータ格納ノードのオペレータによってさえも改ざんおよび改訂に対して強化されたデータレコードの継続的に増大するリストを維持する分散データベースとして理解されうる。ブロックチェーンは、たとえば、トランザクションとブロックと呼ばれる2種類のレコードで構成される。トランザクションは、ブロックチェーンに格納される実際のデータであり、ブロックは、特定のトランザクションがブロックチェーンデータベースの一部としてジャーナル化された時期と順序を確認するレコードである。トランザクションは参加者によって作成される場合があり、ブロックは、ブロックを作成するために特別に設計された専用のソフトウェアまたは機器を使用する可能性のあるユーザによって作成される場合がある。
【0020】
「ネットワーク」という用語は、その最も広い意味で理解されるべきであり、特許請求の範囲や明細書において、通信のために少なくとも2つのエンティティを相互に接続するものを指す。
【0021】
スマートコントラクトの「作成者」という用語は、その最も広い意味で理解されるべきであり、特許請求の範囲や明細書において、スマートコントラクトのコードを作成/開発したエンティティを指す。
【0022】
スマートコントラクトの「所有者」という用語は、その最も広い意味で理解されるべきであり、特許請求の範囲や明細書において、ブロックチェーンにコントラクトを展開した対応する公開鍵の秘密鍵を所有するエンティティを指す。
【0023】
本発明の実施形態によれば、コントラクト書き換えフレームワークシステムによって取得されるスマートコントラクトは、バイナリフォーマット、特にバイトコードのブロックチェーンネットワークの(元の)スマートコントラクトコードで提供されうる。
【0024】
バイトコードは、コンパイルされたコードでありうる。たとえば、バイトコードは、コンパイルされたコードの任意の部分でありう。さらに、バイナリ形式は、ビット単位の文字列の表現でありうる。
【0025】
本発明の実施形態によれば、リライタツールによって生成/改修されたパッチ適用スマートコントラクトは、バイナリフォーマット、特にバイトコードの、新規な、および/または、変更されたスマートコントラクトコードである。新しいスマートコントラクトコードは、(元の)スマートコントラクトコードが、検出された脆弱性がスマートコントラクトから削除/排除されるように修正されることを意味する。
【0026】
本発明の実施形態によれば、パッチ適用スマートコントラクトは、元のスマートコントラクトコードの脆弱ブロックを置き換えるためのバイナリフォーマット、特にバイトコードのパッチ適用コードを準備することによって生成される、ことが提供される。
【0027】
本発明の実施形態によれば、脆弱性の命令位置がプログラムカウンタを含む、ことが提供される。
【0028】
本発明の実施形態によれば、ブロックチェーンネットワークからコントラクト書き換えフレームワークシステムによって取得されたスマートコントラクトが、リライタツールに渡されることが提供される。そして、リライタツールは、脆弱性のタイプおよび脆弱性の命令場所に基づいてスマートコントラクトにパッチを適用し、パッチ適用スマートコントラクトが生成されるよう構成される。
【0029】
本発明の実施形態によれば、脆弱性の命令位置が解釈されている間、リライタツールがスマートコントラクトを中間表現にリフトすることが提供され得る。そして、中間表現にパッチコード片を含めた後、パッチ適用スマートコントラクトが生成されるよう中間表現をバイナリ形式にコンパイルして戻すことができる。
【0030】
本発明の実施形態によれば、リライタツールは、例えばスマートコントラクトの末尾に、パッチコード片を未使用アドレス領域に追加することができる。さらに、リライタツールは、スマートコントラクトの脆弱なコードをトランポリンジャンプに置き換えて、命令ポインタがスマートコントラクトの未使用アドレス領域にあるパッチコード片にジャンプするようにする。そして、パッチコード片の実行が終了した後、命令ポインタはスマートコントラクトの元の後続コードにジャンプして戻り、スマートコントラクトの残りの部分の実行を続行できる。したがって、スマートコントラクトの脆弱な部分を効率的に修正/パッチ適用することができます。
【0031】
本発明の実施形態によれば、コントラクト書き換えフレームワークシステムのデプロイコンポーネントは、予め設定されたアカウントを含む/務めることが提供される。予め設定されたアカウントは、ブロックチェーンネットワークのスマートコントラクトをアップグレードするために定義され使用される。これにより、アップグレードのトランザクションが予め設定されたアカウントによって署名されている場合は、アップグレードトランザクションが、取得されたスマートコントラクトからブロックチェーンネットワークのノードによって受け入れられる、ことが実行されうる。アップグレードトランザクションは、予め設定されたアカウントの秘密鍵を使用して署名されうる。
【0032】
本発明の実施形態によれば、コントラクトをデプロイするための予め設定されたアドレスが定義されており、予め設定されたアドレスに送信されたトランザクションが、スマートコントラクトをアップグレードするためのアップグレードトランザクションとして理解される。したがって、ブロックチェーンのスマートコントラクトを効率的にアップグレードすることができる。
【0033】
本発明の実施形態によれば、アップグレードトランザクションは、パッチ適用スマートコントラクトおよびアドレスAddrを含むペイロードを有する。したがって、ブロックチェーンネットワークから最初に取得されたスマートコントラクトは、パッチ適用スマートコントラクトを使用してアドレスAddrでアップグレードできる。
【0034】
本発明の実施形態によれば、アップグレードトランザクションを受信したブロックチェーンネットワークのノードは、アップグレードトランザクションに基づいてアドレスAddrで元のスマートコントラクトを確認して、デプロイコンポーネントによって示された予め設定されたアカウントを取得する。
【0035】
本発明の実施形態によれば、ブロックチェーンネットワークのノードがアップグレードトランザクションの署名を検証することが提供され、アップグレードトランザクションが有効である場合に、ブロックチェーンノードはアドレスAddrでスマートコントラクトをパッチ適用スマートコントラクトに置き換える。
【0036】
本発明の実施形態によれば、コントラクト書き換えフレームワークシステムは、パッチ検証者をさらに含むことが提供される。これに伴い、リライタツールは、パッチ適用スマートコントラクトをパッチ検証者に渡し、パッチ検証者は元のスマートコントラクトに送信されたトランザクションを抽出して再実行する。元のスマートコントラクトとパッチ適用スマートコントラクトから収集された実行トレースを比較して、それらが異なる状態の更新にならないことを検証して、パッチ適用スマートコントラクトによって元に戻された悪意のあるトランザクションを除き、これにより、パッチ検証者がパッチ適用スマートコントラクトのロジックの一貫性を確認する。これは、アップグレードトランザクションを準備する前に実行できる。
【0037】
スマートコントラクトをアップグレードするための既存のソリューションは、手動および/またはエラーが発生しやすいプロセスのみで構成されている。本発明の実施形態では、即時及び自動的に障害のあるスマートコントラクトにパッチを適用するフレームワークシステムを提供することにより、この問題に取り組むことを目的としている。より具体的には、実施形態では、普及しているイーサリアムブロックチェーンのバイトコード形式用のバイトコード書き換えエンジンが提供される。実施形態によれば、対応する概念実証の実装により、整数オーバーフローの主要なバグクラスに対して脆弱であるスマートコントラクトに自動的にパッチを適用することができる。このアプローチでは、コントラクトの通常の機能を維持しながら、これらのコントラクトで開始されたすべての攻撃トランザクションを正常にブロックできる。
【0038】
本発明の実施形態によれば、スマートコントラクトの自動化されたタイムリーなパッチ適用の問題は、開発者が報告されたスマートコントラクトエラーに対して即座に行動を起こすのを助けるために対処される。イーサリアムのスマートコントラクト用のバイトコードリライタ(リライタツールとして)を特徴とするパッチフレームワークの設計と実装が提供される。本実施形態のコントラクト書き換えフレームワークシステムでは、パッチが最小限に適用され、新しいパッチ適用コントラクトが元のコントラクト契約と互換性があることを保証する、バイトコード書き換えエンジンをしている。バイトコードレベルでパッチを適用することにより、コントラクト書き換えフレームワークシステムは、使用されるコンパイラおよびコンパイラバージョンから独立できることとなる。つまり、コントラクト書き換えフレームワークシステムは、市販のスマートコントラクトコードをサポートしている。
【0039】
本発明の実施形態では、以下のステップの1つまたは複数を実行しうる。
- スマートコントラクトの作成フェーズでは、作成者(またはコントラクトの所有者)がアカウントAにスマートコントラクトをアップグレードする権限を付与する。この場合におけるアカウントAは、コントラクト書き換えフレームワークシステムのデプロイコンポーネントである。
- コントラクト書き換えフレームワークシステムは、アドレスAddrで新しく作成されたコントラクトのバイナリコードをブロックチェーンネットワークから取得して、そのバイナリコードを1つ以上の脆弱性検出ツールに渡す。
- 1つ以上の脆弱性検出ツールが、スマートコントラクトに静的および/または動的分析を適用し、i)検出された各脆弱性のタイプと、ii)検出された各脆弱性の命令位置(つまり、プログラムカウンター「PC」)と、を出力する。
-脆弱性分析の出力は、元のスマートコントラクトコードとともにリライタツールに送信される。リライタツールは、脆弱ブロックを特定し、脆弱ブロックにパッチを適用し(たとえば、必要なチェックを挿入することにより)、パッチ適用ブロックをコントラクトの末尾または未使用のアドレス領域に追加する。リライタツールは、脆弱ブロックの先頭を、パッチ適用ブロックにジャンプするトランポリンジャンプに置き換える。リライタツールは、パッチが適用されたコントラクトバイナリC’を生成し、それをデプロイコンポーネントに渡す。
- デプロイコンポーネントは、アカウントAの秘密鍵で署名されたペイロード(C’,Addr)を使用して、アドレス0x1にアップグレードトランザクションTxupgradeを送信する。
- ブロックチェーンノードは、アドレスAddrでコントラクトをチェックし、アップグレードを許可されたアカウントAを取得する。
- ブロックチェーンノードは、アップグレードトランザクションTxupgradeの署名を検証する。
- トランザクションが有効な場合、ブロックチェーンノードは、アドレスAddrのコードをC’に置き換える。
【0040】
さらに、本発明の実施形態では、少なくとも一つ以上の以下の特徴および特性を有する。
- スマートコントラクトパッチ適用フレームワークの設計と実装が提供され、ソースコードへのアクセスを必要とせずにイーサリアムスマートコントラクトの即時パッチ適用を可能にする。
- 整数オーバーフローの脆弱性にパッチを適用するスマートコントラクト用のバイトコードリライタ(リライタツールとして)に基づいて、エンドツーエンドの自動パッチ生成ツールのインスタンス化が提供される。
- 本発明の実施形態では、異なるクラスの脆弱性のパッチ適用をサポートする。
- 検出された脆弱性を修正する新しいコードへのジャンプ命令を使用して、スマートコントラクトコードをインストルメント化する。
- コントラクトのアップグレードを可能にするために、コントラクト作成時にスマートコントラクトを調整する。
【0041】
本発明における教示内容を設計し、さらに発展させる好適な方法はいくつかある。このため、一方では、請求項1に従属する請求項を参照し、他方では、図面によって示されるような例示の方法による本発明の実施形態の説明を参照する必要がある。図面を用いた本発明の好ましい実施形態の説明に関連して、一般的に好ましい実施形態と教示内容のさらなる改良が説明されうる。
【図面の簡単な説明】
【0042】
【
図1】本発明の実施形態における方法及びコントラクト書き換えフレームワークシステムを示す概略図である。
【
図2】本発明の実施形態における、書き換えツールが、元のバイナリつまり元のスマートコントラクトを中間表現に上げ、コードにパッチを当てることができることを例示した中間表現アプローチを示すブロック図である。
【
図3】本発明の実施形態における、書き換えツールが、スマートコントラクトの末尾のパッチが適用されるブロックにリンクするトランポリンジャンプによりスマートコントラクトの脆弱ブロックを置き換えることができることを例示したトランポリンアプローチの概略図である。
【
図4】本発明で開示される、任意の操作(例えば、フレームワーク、方法など)を実行する、特に、本発明の実施形態においてブロックチェーンネットワークにてスマートコントラクトをサポートするためのコントラクト書き換えフレームワークシステムの任意の操作を実行する、よう構成された情報処理システムの一例を示すブロック図であり、
【
図5】スマートコントラクトのコードの抜粋であり、整数オーバーフローにより攻撃者はビジネスロジックチェックをバイパスでき、金銭的な損失が発生することを表している。
【
図6】本発明の実施形態における自動化されたパッチ適用プロセスの全体を示す概略図である。
【
図7】ジャンプ命令の直前に配置されたプッシュ命令を使用した一定のターゲットへの典型的なジャンプを示すコード例である。
【
図8】内部関数をSolidityで呼び出すときのジャンプを示すコード例である。
【
図9】本発明の実施形態における書き換えがどのように動作するかを例示する概略図である。
【
図10】本発明の実施形態におけるバイトコードリライタによって生成された同じバイトコードのオリジナル及びパッチ適用されたバージョンを示すコードリストである。
【
図11】整数オーバーフロー/アンダーフローの脆弱性の不具合を改善するイーサリアムスマートコントラクトのCVEのリストを示す表である。
【
図12】関連するトランザクション呼び出しのガス消費におけるオーバーヘッド量と、本実施形態におけるパッチ適用されたコントラクトによって生じたコントラクトサイズの増加と、Osirisによって報告され本実施形態におけるバイトコードリライタによりパッチされたものに相当するパッチの数と、を示すテーブルである。
【
図13】オシリスによって検出された脆弱なコントラクトの平均サイズと、バイトコードパッチ後のコードサイズの増加を示す表である。
【
図14】各コントラクトのアクティブタイムラインを示す図であり、灰色の影は、これらコントラクトの脆弱性がPeckshieldによって開示される時間帯を示し、大きな中空点は、攻撃の発生を示す。
【
図15】ヘキサゴンコントラクト(上のリスト)における問題のあるSolidity lineを示すコードリストであり、Solidityは、下のリストにEVMコードを生成し、符号なし整数から2を引く代わりに、Solidityはこれを符号付き整数にして-2を加える、ことを示す。
【発明を実施するための形態】
【0043】
図1は、本発明における方法及びコントラクト書き換えフレームワークシステムを示している。
図1で示す実施形態では、トランザクションを検証する各ノードが、対応するスマートコントラクトを実行する仮想マシンを実装した分散型ブロックチェーンネットワークを想定している。
図1に開示されているコントラクト書き換えフレームワークシステムは、ブロックチェーンネットワークの1つまたは複数の検証ノードに接続されており、ブロックチェーンにデプロイされたスマートコントラクトを読み取る。読み取ったスマートコントラクトはバイナリ形式である(例えば、Ethereumブロックチェーンのバイトコード)。次に、オリジナルのスマートコントラクトバイナリが1つまたは複数の脆弱性検出ツールに送られる。脆弱性検出ツールは、コントラクトに静的または動的分析を適用する場合があり、i)検出された各脆弱性のタイプ、ii)各脆弱性の命令位置つまりプログラムカウンタ(PC)、を出力することができる。脆弱性分析の出力は、オリジナルのスマートコントラクトコードとともにリライタツールに送信される。リライタツールは、指定された命令位置に対応するパッチを挿入し、パッチが適用されたコントラクトバイナリをパッチ適用スマートコントラクトとして返す。その後、パッチ適用スマートコントラクトは、デプロイコンポーネントによって準備され、ブロックチェーンネットワークに再デプロイされる。これは、アップグレードトランザクションTxの形式で実行できる。
【0044】
図2は、本発明の実施形態における例示的な中間表現アプローチを示している。リライタツールは、オリジナルのバイナリすなわちオリジナルのスマートコントラクトを中間表現にリフトし、スマートコントラクトのコードにパッチを当てることができる。実施形態において、バイナリリライタツールは、様々な書き換え方法で実装することができる。
図2に示す実施形態において、リライタツールは、最初にスマートコントラクトのオリジナルのバイナリを中間表現(IR)にリフトすることができ、脆弱性の命令位置も解釈される。リフトされた中間表現(IR)にパッチ片が挿入された後に、パッチ適用されたIRは、バイナリつまりパッチ適用バイナリにコンパイルされる。
【0045】
図3は、本発明の実施形態におけるトランポリンアプローチの例示を示している。リライタツールは、スマートコントラクトの脆弱なブロックを、スマートコントラクトの末尾にパッチ適用されたブロックにリンクするトランポリンジャンプで置き換えることができる。
図3に示される本実施形態(本明細書で開示されるすべての実施形態は、1つの実施形態に統合されうる)では、リライタツールは、トランポリン方法を採用している。より具体的には、
図3を参照すると、リライタツールは、最初に全てのパッチ適用されるコード片をオリジナルのスマートコントラクトの末尾(未使用アドレス)にコピーし、脆弱なコードをパッチ片にジャンプするトランポリンジャンプに置き換える。パッチ片の実行が終了すると、命令ポインタはオリジナルの後続コードにジャンプして戻り、スマートコントラクトの残りの部分の実行を続行する。
【0046】
リライタツールがパッチ適用コードを生成した後、デプロイコンポーネントは、パッチ適用コードを準備し、トランザクションの形式でブロックチェーンに再デプロイする。コントラクトをアップグレードする可能性は、基盤となるブロックチェーンプラットフォームに依存する可能性があることに注意すべきである。例えば、イーサリアムの場合、次の機能でイーサリアムプラットフォームを拡張できる。
- コントラクト作成フェーズで、コントラクトCをアップグレードするための特別なアカウントAを含めることで、Aによって署名されたコントラクトCに対する後続のアップグレード要求が受け入れられる。
- 0x1などのコントラクトデプロイ用の特別なアドレスを含めることで、0x1に送信され、ペイロード(C’,Addr)を持つトランザクションが、バイナリC’のアドレスAddrでコントラクトをアップグレードする要求として理解される。
【0047】
その後、本実施形態では、以下のように、コントラクトCがアドレスAddrでアップグレードされる。
- スマートコントラクト作成フェーズでは、作成者(またはコントラクトの所有者)がアカウントAにコントラクトをアップグレードする権限を付与する。多くのコントラクト所有者がいる場合、所有者はコントラクトがアップグレードされるよう署名を発行できる。この場合のアカウントAは、コントラクト書き換えフレームワークシステムのデプロイメントコンポーネントによって務められる。
- コントラクト書き換えフレームワークシステムは、コントラクトCにパッチを適用して脆弱性を修正し、新しい(パッチ適用された)コントラクトコードC’を生成する。
- コントラクト書き換えフレームワークシステムは、アカウントAによって署名されたペイロード(C’,Arrd)を使用して、アドレス0x1にアップグレードトランザクションTxupgradeを送信する。
- ブロックチェーンノードは、アドレスAddrでコントラクトをチェックし、権限を有するアップグレードアカウントAを読み取る。
- ブロックチェーンノードは、アップグレードトランザクションTxupgradeの署名を検証する
- トランザクションが有効な場合、ブロックチェーンノードは、アドレスAddrのコードをパッチ適用したコントラクトコードC’に置き換える
【0048】
コントラクトのアップグレードには複数の関係者の同意が必要な場合があり、利害関係者による採択が必要な場合があるため、実施形態では、権限を有するアップグレードアカウントとして複数のアカウントを使用できる。そのため、コントラクト作成トランザクションでは、複数のアカウントから複数の署名またはしきい値の署名を明確にして、コントラクトをアップグレードできる。さらに、コンセンサスレイヤー内のすべての検証ノードがコントラクトアップグレードプロセスの投票に参加できるようにするために、実施形態は、コントラクトアップグレードトランザクションがブロックにすぐに含まれないが、システムが、その後にコントラクトをアップグレードするかどうかを決定できる検証者に通知しうる。
【0049】
上述した技術により、スマートコントラクトを変更して、コントラクトのアップグレードを可能にする。アップグレードは、脆弱性を解決する新しいコードへのジャンプ命令を使用してスマートコントラクトコードをインストルメント化または挿入することで実行できる。
【0050】
実施形態では、方法を実行するように構成された処理システムを含みうる。この方法には、次のブロックが含まれうる。
- ブロック1:コントラクト作成フェーズ中に、作成者(またはコントラクト所有者)は、コントラクト作成トランザクションでアップグレード条件を定義することにより、アカウントAまたは複数のアカウント{A_i}にコントラクトをアップグレードする許可を付与する。
- ブロック2:コントラクト書き換えフレームワークは、アドレスAddrで新しく作成されたコントラクトのバイナリコードをブロックチェーンネットワークから取得し、そのバイナリを1つまたは複数の脆弱性検出ツールに渡す。
- ブロック3:脆弱性検出ツールは、コントラクトに静的または動的分析を適用し、i)検出された各脆弱性のタイプ、ii)各脆弱性の命令位置つまりプログラムカウンタ(PC)、を出力する。
- ブロック4:脆弱性分析の出力は、オリジナルのコントラクトコードと共にリライタツールに送信される。リライタツールは、関連するコード書き換え方法を適用し、パッチ適用バイナリC’を生成して、パッチ検証者に渡す。
- ブロック5:パッチ検証者は、オリジナルのコントラクトに送信されたトランザクションを抽出し、それらを再実行する。オリジナルのコントラクトとパッチ適用されたコントラクトから収集された実行トレースを比較して、パッチ適用のコントラクトによって元に戻される悪意のあるトランザクションを除いて、異なる状態の更新につながらないことを確認する。
- ブロック6:パッチ検証者は、パッチ適用されたコントラクトのロジックの整合性を確認した後、ペイロード(C’,Addr)を含む「0x1」などの特別なアドレスを対象とするアップグレードトランザクションTxupgradeを準備し、関連するアカウント{Ai}の利害関係者に送信する。
- ブロック7:利害関係者は新しいコントラクトC’を確認し、アップグレードに同意する場合は、マルチ署名またはしきい値署名スキームを使用して、Aiのアカウント公開鍵を使用してトランザクションTxupgradeに署名し、署名されたトランザクションをブロックチェーンネットワークにブロードキャストする。
- ブロック8:ブロックチェーンノードは、許可されたアカウント{Ai}に関連するアップグレード条件と併せてTxupgradeに基づいて、アドレスAddrでオリジナルコントラクトを取得する。ブロックチェーンノードは、アップグレードトランザクションTxupgradeの署名が対応するコントラクト作成トランザクションによって定義されたアップグレード条件を満たす場合、その署名を検証する。
- ブロック9:トランザクションが有効な場合、ブロックチェーンノードは、アドレスAddrでコードをC’に置き換える。
【0051】
本発明の実施形態(すなわち、開示されたシステムおよび方法)では、ブロックチェーンネットワーク内にデプロイされたスマートコントラクトにタイムリーにパッチを適用することができる。本発明の実施形態(すなわち、方法および対応して構成されたシステム)では、ソースコードを必要とせず、特定のコンパイラから独立している。実施形態では、EVMバイトコードレベルで動作する分析ツールと互換性を有する。いくつかの実施形態によれば、アップグレード中に資産を元に戻す必要はない。実施形態では、サブジェクトスマートコントラクトのアドレスを変更することなくサブジェクトスマートコントラクトの改訂を可能にし、それにより、外部スマートコントラクトにおけるサブジェクトスマートコントラクトへの参照を破損させる。
【0052】
図4を参照すると、処理システム400は、1つまたは複数のプロセッサ402、メモリ404、1つまたは複数の入出力デバイス406、1つまたは複数のセンサ408、1つまたは複数のユーザインターフェース410、および1つまたは複数のアクチュエータ412を含むことができる。
【0053】
プロセッサ402は、それぞれが1つまたは複数のコアを有する1つまたは複数の別個のプロセッサを含むことができる。個別のプロセッサはそれぞれ、同じ構造または異なる構造を持つことができます。プロセッサ402は、1つまたは複数の中央処理装置(CPU)、1つまたは複数のグラフィックス処理装置(GPU)、回路(例えば、特定用途向け集積回路(ASIC))、デジタル信号プロセッサ(DSP)などを含むことができる。プロセッサ402は、共通の基板上または異なる基板上に取り付けることができる。
【0054】
プロセッサ402は、1つまたは複数の別個のプロセッサの1つが、メモリ404に格納され、関数、方法、又は、操作が具体化されたコード(スクリプトを含む)を実行することで、所定の方法(つまり、フレームワーク、関数、操作など)を実行するよう構成されている。プロセッサ402つまり処理システム400は、本明細書に開示されるありとあらゆる機能、方法、および操作を自動的に実行するように構成することができる。従って、本明細書で特定されるユーザは、ユーザに関連する操作を自動的に実行するように構成された処理システムとして具体化することができる。
【0055】
本明細書において、処理システム400がタスク「X」を実行する/実行できる、ユーザがタスク「X」を実行する、またはタスク「X」が実行される、と記載されている場合には、かかる記載は、処理システム400がタスク「X」を実行するよう構成されている、と理解されるべきである。処理システム400は、少なくともプロセッサ402が同じことを実行するよう構成されている場合には、機能、方法、または操作を実行するように構成される。
【0056】
メモリ404は、揮発性メモリ、不揮発性メモリ、およびデータを記憶することができる他の任意の媒体を含むことができる。揮発性メモリ、不揮発性メモリ、およびその他のタイプのメモリのそれぞれは、複数の異なる場所に配置され、それぞれが異なる構造を有する複数の異なるメモリデバイスを含むことができる。
【0057】
メモリ404の例として、RAM、ROM、フラッシュメモリ、EEPROM、DVDなどのあらゆる種類の光ストレージディスク、Blu-Ray(登録商標)ディスク、磁気ストレージ、ホログラフィックストレージ、HDD、SSDなど、命令またはデータ構造などの形式でプログラムコードを格納するために使用できる任意の媒体であり、非一時的なコンピュータ可読メディアが含まれる。本出願で説明されるすべての方法、機能、および操作は、メモリ404に保存された有形および/または非一時的な機械可読コード(例えば、スクリプト)の形で完全に具体化することができる。
【0058】
入出力デバイス406は、ポート、アンテナ(すなわち、トランシーバ)、プリントされた導電性パスなどのようなデータを伝送するための任意の構成要素を含むことができる。入出力デバイス406は、USB(登録商標)、ディスプレイポート(登録商標)、HDMI(登録商標)、イーサネットなどを介した有線通信を可能にすることができる。入出力デバイス406は、適切なメモリ406との電子的、光学的、磁気的、およびホログラフィック通信を可能にすることができる。入出力デバイス406は、WiFi(登録商標)、ブルートゥース(登録商標)、セルラー(例えば、LTE(登録商標)、CDMA(登録商標)、GSM(登録商標)、WiMax(登録商標)、NFC(登録商標))、GPSなどを介した無線通信を可能にすることができる。入出力デバイス406は、有線および/または無線通信経路を含むことができる。
【0059】
センサ408は、環境の物理的測定値を取得し、それをプロセッサ402に通知することができる。ユーザインターフェース410は、ディスプレイ(例えば、LEDタッチスクリーン(例えば、OLEDタッチスクリーン)、物理的ボタン、スピーカー、マイクロフォン、キーボードなど)を含むことができる。アクチュエータ412は、プロセッサ402が機械的な力を制御することを可能にすることができる。
【0060】
処理システム400は、分散構造とすることができる。処理システム400は、所定の特徴が
図4に示される複数の態様を有するモジュラー設計とされうる。例えば、入出力モジュールには揮発性メモリと1つ以上のプロセッサを含めることができる。
【0061】
本発明のさらなる特徴および利点を、
図5乃至
図15を参照して以下に説明する。
【0062】
I.はじめに
I.A.EVMとスマートコントラクト
イーサリアムブロックチェーンシステムの中核には、イーサリアムスマートコントラクトを実行するイーサリアム仮想マシン(EVM)と呼ばれるカスタム仮想マシンがある。EVMは、カスタム命令フォーマットを備えた単純なスタックベースの仮想マシンで構成されている。すべての命令は1バイトのオペコードとして表される。引数はデータスタックに渡される。唯一の例外は、定数をスタックにプッシュするために使用されるプッシュ命令である。これらの定数は、命令バイトに直接エンコードされる。
【0063】
イーサリアムネットワークでは、ブロックの前後の状態を計算して検証するために、ネットワーク内のすべてのマイナーとすべてのフルノードがスマートコントラクトを実行する必要がある。すべてのスマートコントラクトを適切に実行するようマイナーを動機付けるために、EVMは、スマートコントラクトごとの実行時間を制限し、スマートコントラクトを実行することに対してマイナーに報酬を与えるメカニズムを備えている。すべてのEVM命令には、命令を実行するために必要な固定ガスバジェットがある。このガスは、すべての取引の発生元によって支払われる必要がある。常にユーザが制御する外部所有のアカウントであるトランザクションの発信元は、トランザクションでガス価格を提供できる。これにより、ガスユニットあたりのイーサリアムの使用量が決まる。このことは、スマートコントラクトを使用するコストを削減し、システムの全体的な負荷を軽減するために、コントラクトの実行のガスコストを最小限に抑えることが重要であることを意味している。そのため、セキュリティ強化チェックによって導入される追加のコードは、かなりのガスオーバーヘッドを引き起こさないように十分に小さくする必要がある。
【0064】
スマートコントラクトは、オブジェクト指向の方法で開発される。すべてのスマートコントラクトには、機能の定義されたインターフェイスがある。それは、コントラクトのABI(アプリケーションバイナリインターフェイス)である。イーサリアムユーザーやその他のスマートコントラクトは、ABIに従ってコントラクトを呼び出すことができる。スマートコントラクトが別のスマートコントラクトを呼び出したい場合は、常にCALLやSTATICCALLなどの呼び出し命令の1つを利用する。呼び出されたコントラクトは、提供された入力を処理し、それに応じて自身の状態を更新する。コントラクトは、他のコントラクトの状態に直接アクセスすることはできず、別のコントラクトから状態を取得するには、常にABIに従って関数呼び出しを使用する必要がある。Solidityなどの既存のプログラミング言語は、メソッドのような構文で他のコントラクトの関数を呼び出すコントラクトを持つオブジェクト指向モデルを提供するが、これらの呼び出しは、他のプログラミング言語の関数呼び出しというよりも、別々のプロセス間のリモートプロシージャ呼び出しに似ている。
【0065】
最近、イーサリアムの開発者は、イーサリアムブロックチェーン用のWebAssemblyベースの仮想マシンを導入している。この仮想マシンは、eWASMと呼ばれるWebAssemblyの決定論的バージョンであり、EVM実行モデルと互換性がある。これにより、開発者は、WebAssemblyにコンパイルされる他のプログラミング言語を利用してEthereumスマートコントラクトを開発しながら、古いEVMの既存のコントラクトと相互運用することができる。しかしながら、本発明の実施形態では、現在のEVMのために開発およびコンパイルされたレガシーコントラクトを書き換えることに焦点を合わせ得る。eWASM仮想マシンは、メインのイーサリアムブロックチェーンでまだ有効になっていないため、イーサリアムでの本番環境で使用されるeWASMスマートコントラクトはなく、有用なデータ(スマートコントラクトおよび対応するトランザクション)を取得できない。
【0066】
I.B.バイナリ書き換え
バイナリ書き換えは、コンパイル後にプログラムを最適化またはインストルメント化する手法である。バイナリ書き換えは、制御フローの整合性などのセキュリティ強化手法を改良するため、コンパイルされたバイナリに適用されるだけでなく、実行中のプログラムにセキュリティパッチを動的に適用するためにも適用されている。x86やARMなどの従来のアーキテクチャでのバイナリ書き換えでは、静的バイナリ書き換えと動的バイナリ書き換えの2つのアプローチが開発されている。後者は、動的バイナリ変換またはインストルメンテーションとも呼ばれる。
【0067】
ただし、動的バイナリインストルメンテーションは、コードの実行中にフライ上のコードを書き換える。これにより、大きなバイナリで不正確な静的分析を実行する必要がなくなる。実際には、このアプローチは通常、大きなアプリケーションバイナリや複数のライブラリを処理する場合、静的な書き換えアプローチよりも問題が少なくなる。動的バイナリインストルメンテーションの一般的なフレームワークの1つは、Valgrindである。ただし、動的バイナリ変換には、実行時にコードを分析して書き換える中間層が必要である。イーサリアム仮想マシンは、動的コード生成または変更をサポートしていないため、このアプローチをイーサリアムスマートコントラクトに適用することはできない。
【0068】
バイナリ書き換えのもう1つの特色は、静的バイナリ書き換えである。静的バイナリ書き換えは、完全にオフラインで機能し、静的分析に依存してターゲットに関する十分な情報を回復し、ターゲットを正確に書き換える。そのため、実行時にリライタのコードを分析するランタイムコンポーネントはない。ただし、静的なバイナリ書き換えでは、コードが最適ではないため、実行時のオーバーヘッドが増えるバイナリが生成されることがよくある。静的バイナリ書き換えは、最適化、イントロスペクション、およびセキュリティ防御の適用のためのコードを挿入するために利用されている。
【0069】
スマートコントラクトは、イーサリアムブロックチェーンで使用されているため、静的なバイナリ書き換え手法に適している。EVM用にコンパイルされ、イーサリアムにデプロイされたスマートコントラクトは、コードサイズが比較的小さい。さらに、EVMスマートコントラクトは、常にすべてのライブラリに静的にリンクされている。ダイナミックライブラリに似たものが、実行中のコントラクトのコードアドレス領域を切り替える特別な呼び出し命令で実装される。この場合、リライタは、コントラクトとライブラリコントラクトの両方に別々に適用できる。これにより、スマートコントラクトは、静的バイナリ書き換えの適切なターゲットになる。
【0070】
I.C.整数オーバーフローの脆弱性
一般的な整数型には、最小サイズまたは最大サイズがある。これは、整数型の固定ビット幅に起因する。ただし、プログラマーは、実際の整数型のこの制限を考慮せず、整数値の範囲に関するエッジケースを処理しないことがよくある。これにより、整数のバグが発生する。たとえば、整数のオーバーフローは、算術演算の結果が実際に整数型の最大サイズよりも大きい場合に発生する。次に、結果は整数型のビット幅に切り捨てられる。ほとんどのアーキテクチャでは、符号なし整数の加算が2ビット幅加算法として指定されるように、この動作はしばしば指定される。これにより、予期しない状況が発生し、加算の結果が2つのオペランドよりも小さくなる可能性があります。
【0071】
整数型の取り扱いを誤ると、悲惨な結果を招く可能性がある。たとえば、Androidシステムでの悪名高い「Stagefright」の脆弱性は、整数のオーバーフローが原因であった。この整数のオーバーフローにより、攻撃者は境界チェックとメモリの破損を回避でき、最終的にはリモートでコードが実行されることになる。そのため、古典的なシステム、特にC / C ++プログラムで整数のバグに対処することは、活発な研究トピックである。
【0072】
PythonやSchemeなどの一部の高級プログラミング言語は、整数を事実上無制限のサイズの任意精度の整数に自動的にプロモートするため、整数のバグの影響を受けない。ただし、スマートコントラクトのデファクトスタンダードプログラミング言語であるSolidityは、整数のオーバーフローや関連する問題を自動的に処理しない。これは開発者の負担になる。C / C ++のレガシーコードと同様に、開発者が整数のバグの可能性を考慮するのを忘れた場合、スマートコントラクトの脆弱性につながる。最近、このことはERC-20トークンコントラクトに複数の脆弱性をもたらした。これらのトークンコントラクトは、イーサリアムブロックチェーンにおけるトークンと呼ばれるサブ通貨を管理する。このようなトークンは、すべてのトークン所有者のトークン残高を追跡し、トークンとEtherの交換も処理するため、大量の通貨を処理でる。たとえば、BECトークンには整数のオーバーフローの脆弱性が含まれていた。
図5にコントラクトコードの抜粋を示す。8行目の合計金額を計算する際に、チェックされていない整数の乗算が使用される。攻撃中に、攻撃者は非常に大きな_valueを提供し、その結果、整数のオーバーフローが発生する。その場合、amount変数には非常に少量が含まれている。これにより、11行目のチェックが事実上バイパスされ、攻撃者のバランスが、_valueパラメータで指定されたように要求されたトークンを転送するのに十分な高さであることが確認される。これにより、攻撃者は大量のトークンを攻撃者が制御するアカウントに転送し、トークンをEtherと交換することができる。
【0073】
Solidityはチェックされた整数演算を統合しないため、スマートコントラクトの開発者は、オーバーフローチェックを自分で実装するか、一般的に推奨されるSafeMathSolidityライブラリを含める必要がある。ただし、このような手動の整数オーバーフローチェックではエラーが発生しやすくなる。そのため、整数のバグがないかスマートコントラクトをスキャンするために、シンボリック実行とフォーマル検証に基づくツールが提案されている。
【0074】
II.問題提起
現在、イーサリアムは、スマートコントラクトのコードをブロックチェーンにデプロイされると、不変として扱う。コードに許可される唯一の変更は削除である。これは、SELFDESTRUCT命令を使用してコントラクト自体によって実現できる。結果として、イーサリアムは現在、スマートコントラクトを更新するためのプラットフォームサポートを提供していない。回避策として、コミュニティは、デプロイされたスマートコントラクトのバグに対処し、スマートコントラクトにパッチを適用するためのいくつかの回避策を考え出した。ただし、アップグレード可能な契約を作成するためのベストプラクティスが何であるかはまだ明確ではない。現在、イーサリアムコミュニティは、アップグレード可能なコントラクトのさまざまな実装を実験している。
【0075】
一般的に使用される特徴の1つは、コントラクトに機能を実装することである。これにより、管理者はスマートコントラクトのすべての操作を一時停止できる。次に、重大なバグに気付いた場合、管理者はスマートコントラクトを一時停止し、コントラクトの現在の状態を凍結する。次に、すべての状態変更機能が内部状態を更新する代わりに、トランザクションを元に戻すようにコントラクトが実装される。コントラクトの状態は引き続き検査でき、すべての資金を保持している。これにより、管理者は、コントラクトの操作を緊急停止することができ、攻撃者がコントラクトを悪用するのを防ぐこともできる。この機能はすでにOpenZeppelinSolidityライブラリの一部であり、スマートコントラクト開発のベストプラクティスと見なされている。管理者がコントラクトを一時停止したら、パッチを適用したバージョンのコントラクトにアップグレードするために、アップグレード手法を実装する必要がある。
【0076】
新しいコントラクトへの移行:第1のアップグレード手法は、新しくデプロイされたコントラクトに移行することである。パッチが適用されたコントラクトは、ブロックチェーンの新しいクリーンな状態の別の新しいアドレスにデプロイされる。次に、コントラクトの管理者は、古いコントラクトの状態を検査し、関連するすべての状態を新しいコントラクトに手動で移行する必要がある。状態の移行はコントラクトに固有であり、コントラクトの開発者が手動で実装する必要がある。まず、コントラクト開発者は、移行する必要のあるすべての内部状態にアクセスできるようにする必要がある。設計上、スマートコントラクトのすべての状態は公開されているが、簡単にアクセスできる形式ではない。EVMのイベント機能を使用することで、スマートコントラクトのすべての重要なアクションをログに記録することができ、コントラクトの状態を簡単に回復できる。次に、コントラクト開発者は、レガシーコントラクトの古い状態を新しくデプロイされたコントラクトに転送できるようにする必要がある。
【0077】
移行には2つの大きな欠点がある。1つは、新しいコントラクトがデプロイされるため、アドレスが変更されることである。つまり、すべての関係者は、移行が完了したらすぐに、新しくデプロイされたコントラクトに切り替える必要がある。2つ目は、コントラクトが大量のデータを内部状態に保持している場合、移行はコストのかかる操作になる可能性があることである。新しいコントラクトに状態を書き込むには、大量のデータを処理する可能性のある1つ以上のトランザクションが必要であり、ガスの観点から支払いが必要となる。ただし、ERC-20トークンなどの一般的なコントラクトの場合、コントラクトが保有する金額が移行のコストよりも小さいことが示された。
【0078】
移行手法の最大の問題は、コントラクト固有のオフチェーン操作が含まれることである。開発者は、移行手法を実装およびテストして、プロセスでデータが失われないことを確認する必要がある。これは、移行自体が複雑で非常に困難なプロセスであることを意味する。
【0079】
プロキシパターンを使用したアップグレード可能なコントラクト:第2のアップグレード手法は、EVMレベルでもう少し複雑であるが、アップグレード中にコントラクトがアドレスと内部状態を保持できるようにする。これにより、アップグレードのコストと複雑さが軽減される。ただし、これには、コントラクトのコードの複雑さが増すという犠牲が伴う。アップグレード可能なコントラクトは、通常、プロキシパターンで実現される。ここでは、ビジネスロジックとデータストレージが複数の異なるコントラクトに分割されている。プロキシパターンの最も好ましいバージョンは、delegatecall-proxyであり、これは、ZeppelinOSプロジェクトのコントラクトをアップグレードするためにも使用される。delegatecall-proxyパターンは、2つの異なるコントラクトを利用する。最初のコントラクトは不変のプロキシコントラクトであり、すべての資金を保持し、すべての内部状態も保存する。ただし、プロキシコントラクトはビジネスロジックを実装していない。代わりに、プロキシコントラクトは、DELEGATECALL命令を使用して、すべての関数呼び出しを別のロジックコントラクトに転送する。この命令は、呼び出し側コントラクト、つまりプロキシコントラクトのコンテキストで論理コントラクトのコードを実行する。これにより、ロジックコントラクトは、プロキシコントラクトに格納されているすべての内部状態と資金にアクセスできる。プロキシコントラクトは、ロジックコントラクトのアドレスのみを格納し、コントラクトの所有者がこのアドレスを変更できるようにする機能を提供する必要がある。
【0080】
ただし、プロキシパターンは、現在、イーサリアム開発エコシステムで十分にサポートされていないため、技術的に複雑になる。たとえば、Solidityにはこのパターンのサポートがない。そのため、アップグレード可能なコントラクトを作成する際には、特別な注意を払う必要がある。たとえば、Solidityは、スマートコントラクトのストレージに変数を次々に配置するため、変数を単純に並べ替えたり削除したりすることはできない。変数を並べ替えると、コントラクトの内部状態が破損する。これは、レガシーコントラクトと新しいコントラクトのストレージレイアウトが異なるためである。一部の静的分析ツールは、開発者がそのような違反を検出するのを支援しようとしている。
【0081】
タイムリーなパッチ適用:脆弱性が通知されてからパッチを発行するまでの時間は、どのシステムにとっても、特にスマートコントラクトにとって重要である。スマートコントラクトにタイムリーにパッチを適用するには、現在、call-proxyパターンのみが実行可能なオプションである。ただし、このアップグレードパターンを正しく利用することは、開発者にとって非常に困難である。本発明の実施形態によれば、delegatecall-proxyの使用は、使用されるコンパイラとは独立してパッチを適用することによって単純化され得る。本発明の実施形態では、スマートコントラクトにパッチを適用するためのバイトコード書き換えアプローチを提案する。バイトコードの書き換えを使用すると、設計によりレガシーコントラクトとの互換性を確保できる。バイトコードリライターは、EVMレベルで動作するため、Solidityコンパイラの詳細に依存せず、オリジナルのコントラクトとまったく同じストレージレイアウトを自然に複製する。これにより、スマートコントラクトが破られるリスクを冒すことなく、タイムリーにパッチを適用できる。
【0082】
セクションIで説明したように、整数のオーバーフローの強化、整数のバグ、特に整数のオーバーフローは、多くのコントラクトに影響を与える大きなクラスの脆弱性である。EVMスマートコントラクトの一般的なプログラミング言語はSolidityであり、デフォルトではチェック演算を備えていない。これはSolidityコンパイラで簡単に修正できる問題のように聞こえるが、すべての算術命令に対して整数のオーバーフローチェックを単純に有効にすることはできない。整数のオーバーフローチェックは、EVMの機能セットが単純であるため、かなりコストがかかる。そのため、オーバーフローチェックですべての算術命令を拡張することはできない。ただし、以前の作業では、通常、限られた数の算術命令のみがオーバーフローする傾向があることが示されていた。そのため、既存の分析ツールによって脆弱である可能性があると報告されている算術命令を選択的に強化することができる。本発明の実施形態では、バイトコード書き換えベースのパッチ適用フレームワークの特定の使用例として、起こり得る整数オーバーフローの脆弱性の自動パッチ適用を示している。
【0083】
III.アーキテクチャ
本発明の実施形態では、スマートコントラクトにタイムリーにパッチを適用し、強化するための自動パッチ適用プロセスを提供することができる。本発明の実施形態では、バイトコードリライタを利用して、バイトコードレベルでEVMスマートコントラクトに最小限の侵入パッチを適用することができる。設計上、バイトコードリライタは、オリジナルのコントラクトのコードと書き換えられたコントラクトの間のストレージレイアウトの互換性を保証する。そのため、スマートコントラクトにパッチを適用するのは簡単である。新しい攻撃タイプが発見されたり、バグ発見ツールが改善されたりすると、開発者の介入なしに、コントラクトを自動的にチェックし、パッチを適用し、短時間で再デプロイできる。
図6は実施形態における自動パッチ適用プロセスの概要を示している。パッチ適用プロセスには、脆弱性の検出、バイトコードの書き換え、パッチの検証、およびコントラクトの展開、という4つの主要なコンポーネントがある。より具体的には、
図6は、実施形態におけるスマートコントラクトに対する自動化されたパッチの生成のためのバイトコード書き換えに基づくプロセスのアーキテクチャを示している。このプロセスは、開発者によって実行される。入力として、バイトコードリライタは、脆弱なコントラクト、特別な機械可読脆弱性レポート、およびパッチテンプレートを受け取る。次に、バイトコードリライタは、パッチが適用されたバージョンのコントラクトを作成する。次に、このパッチが適用されたバージョンは、履歴トランザクションを再生および比較することによって検証される。最後に、パッチが適用されたコントラクトは、call-proxyパターンを使用したコントラクトのアップグレードパスを使用してデプロイできる。
【0084】
脆弱性の検出:最初に、対象のスマートコントラクトで脆弱性を検出する必要がある。脆弱性の検出は、一般的な脆弱性検出ツールを使用して実行できる。実施形態による実装においては、OSIRISシンボリック実行エンジンが整数オーバーフロー及びアンダーフローバグを検出するために利用される。ただし、静的分析またはシンボリック実行に基づく他のツールもシステムに簡単に統合できる。開発者またはセキュリティコンサルタントは、脆弱性レポートを手動で指定または確認することもできる。実施形態におけるシステムでは、脆弱性検出は、命令の正確なアドレス、脆弱性が配置されている場所、および脆弱性のタイプ、を識別する必要がある。次に、この情報はバイトコードリライタに渡される。
【0085】
バイトコードリライタ:バイトコードリライタは、脆弱なコントラクトのバイトコードと脆弱性レポートを取得し、脆弱なコントラクトを書き換えてパッチを含める。リライタは、脆弱性の種類に応じてパッチテンプレートを選択し、与えられたコントラクトに合わせてパッチテンプレートを特殊化する。
【0086】
パッチ検証者:生成されたパッチ適用されたコントラクトが機能的に正しいことを確認するために、パッチ検証者は既存のすべてのトランザクションを再実行し、すべてのトランザクションが一貫して動作することを検証する。次に、パッチ検証者は、オリジナルのコードとパッチが適用されたコードの動作が異なるトランザクションのリストを出力する。これらのトランザクションは、攻撃の可能性があると見なされる。次に、開発者はトランザクションが悪意のあるものであることを確認する必要がある。トランザクションの1つが安全である場合、生成されたパッチ適用コントラクトに欠陥がある。
【0087】
コントラクトのデプロイ:本発明の実施形態では、ZeppelinOSの一部として開発されたものと同様のdelegatecall-proxyベースのアップグレードスキームを提案している。実施形態では、コントラクトを、アドレスが一定でありすべての持続状態を格納するプロキシコントラクトと、ビジネスロジックを実装する実際のコードを含むロジックコントラクトと、に分離することができる。次に、スキームは、新しくパッチが適用されたコントラクトをデプロイし、ロジックコントラクトを古い脆弱なバージョンから新しくパッチが適用されたバージョンに切り替えうる。
【0088】
IV.実装
本発明の実施形態では、イーサリアムスマートコントラクトのバイトコードを書き換えるためのツールを提供する。実施形態では、バイトコードリライタは、イーサリアム仮想マシン(EVM)用にコンパイルされたスマートコントラクトにおける命令の挿入、削除、および上書きをサポートする。これにより、自動生成されたパッチをスマートコントラクトに挿入できる。
【0089】
IV.A.バイトコード書き換えの課題
EVMのスタックベースのアーキテクチャは、静的分析を困難にする。ジャンプターゲットもスタック上で渡されるため、すべてのジャンプは間接ジャンプになる。単純なヒューリスティックは、ジャンプターゲットが同じ基本ブロック内のスタックにプッシュされる大抵のジャンプに使用できる。たとえば、
図7は、プッシュ命令が直前にあるジャンプ命令を示している。これは、スタックの最上位が定数値であり、プッシュ命令のバイトにエンコードされることを意味する。このとき、ジャンプターゲットはプッシュ命令からの定数値である。ただし、特に内部関数呼び出しを使用する場合、Solidityコンパイラは、より複雑な制御フロー構造を含むコードを生成する。
【0090】
たとえば、
図8は、Solidityコンパイラによって生成される内部関数呼び出しの典型的なコードを示している。ここでは、ジャンプターゲットをスタックにプッシュされる定数として識別するために、基本ブロックがエミュレートされる必要がある。2行目には、ジャンプターゲットの実際のアドレスが含まれる。3行目から5行目は、6行目と7行目の実際のジャンプターゲットのマスキングに続く、スタックワードをスワップする命令である。さらに問題なのは、内部関数からの戻り値をエミュレートするために、Solidityによって生成されるコードパターンである。Solidityは、通常のジャンプ命令を利用して関数の戻りをエミュレートする。この場合、ジャンプターゲットのソースは、内部関数の各呼び出しサイトにあるプッシュであり、ジャンプターゲットには複数の可能な定数値がある。
【0091】
間接ジャンプのジャンプターゲットの回復は、x86アーキテクチャのコンテキストで以前に研究されている。同様の手法が、EVMでの制御フローグラフの回復に適用されている。たとえば、抽象解釈は、たとえば選択値群分析を使用して、可能なジャンプターゲットを決定するために適用されている。他の研究では、スタック効果をモデル化し、プログラムの一部を実行する同様のアルゴリズムを使用している。同様に、部分的なシンボリック実行がジャンプターゲットを回復するために適用される。他の研究では、制御フローグラフを正確に回復するためにデータログベースのエンジンを適用している。一般に、ほとんどのアプローチは、最初に基本ブロックでローカル分析を実行し、次に固定小数点に達するまで制御フローグラフを段階的に改良する。アドレスを使用してコード内の場所をマークするバイナリ形式またはバイトコード形式の場合、バイトコードの書き換えは簡単ではない。バイトコードを変更する場合、リライタは、コード内のアドレスベースの参照が修正されていることを確認する必要がある。これにより、リライタ後も正しいアドレスを参照するようになる。その意味で、EVMバイトコードの書き換えは、x86やARMなどの通常のCPU命令セットアーキテクチャのバイナリコードの書き換えに似ている。EVMバイトコードの場合、アドレスを使用してコードアドレス領域にアクセスする2種類の命令を分類できる。
【0092】
コードジャンプ:EVMには、JUMPとJUMPIの2つの分岐命令がある。どちらも、スタックの最初のパラメータとして宛先アドレスを取る。EVMのスタックベースのアーキテクチャにより、すべてのジャンプが間接ジャンプに変わるため、アドレスの送信元を特定するのは簡単ではない。
【0093】
定数データ参照:CODECOPY命令は、コードアドレス領域からメモリアドレス領域にデータをコピーするためにコントラクトによって使用できる。これは、スマートコントラクトで大きなデータ定数が使用される場合に使用される。このようなデータ定数には、コントラクトで使用される文字列だけでなく、実行中のコントラクトがCREATEまたはCREATE2命令を使用して新しいスマートコントラクトをインスタンス化する場合の新しいスマートコントラクトのコンストラクターコードも含まれる。ジャンプ命令と同様に、メモリがロードされるアドレスは、スタックを介してCODECOPY命令に渡される。このアドレスの値を決定することは、ジャンプターゲットを決定することと同じ問題に直面する。
【0094】
EVMスマートコントラクトを書き換える場合、バイトコードリライタで両方のタイプの命令を考慮する必要がある。スマートコントラクトを書き直すための明白な方法は、コード内のすべての定数アドレスを修正して、コードにパッチを適用した後に新しいアドレスを反映することである。ただし、この方法は、2つの主な理由により困難である。まず、スマートコントラクトの制御フローグラフを正確に復元する必要がある。次に、どの命令がアドレス定数のソースであるかを判別するために、データフロー分析が必要である。従来のアーキテクチャのバイナリ書き換えの研究分野では、書き換えに対するより実用的なアプローチが開発された。本発明の実施形態では、以前にバイナリ書き換えに使用されてきた、バイナリ書き換えへのトランポリンアプローチに従うことができる。本発明の実施形態では、アドレスを修正する代わりに、すべてのオリジナルのコードおよびデータアドレスをそのままにして、既存のコントラクトにコードを追加することができる。本発明の実施形態では、基本ブロックのパッチされたコピーに即座にジャンプするトランポリンでパッチを当てるために必要とされる基本ブロックを置き換えることができる。これにより、オリジナルの基本ブロックへのジャンプが、パッチが適用された基本ブロックに確実にリダイレクトされる。
【0095】
IV.B.トランポリンベースのバイトコード書き換え
実施形態では、コントラクトのコード内の参照を修正する代わりに、トランポリンベースのリライタは、すべての新規および変更されたコードをオリジナルのコントラクトの末尾にコピーすることができる。次に、古いコードは、オリジナルのコードから新しく追加されたコードにジャンプするトランポリンに置き換えられる。これにより、オリジナルのコードで参照を修正する必要がなくなり、データフロー分析が不要になる。実際、リライタは部分的な制御フローグラフしか必要としないため、正確な制御フローグラフの回復でさえ必要ない。トランポリンベースのリライタは、変更された基本ブロックの境界と、これらの基本ブロックのフォールスルーエッジのみを回復する必要がある。
【0096】
実施形態では、トランポリンベースのリライタは、基本ブロックレベルで機能し得る。命令が変更されると、基本ブロック全体がコントラクトの最後にコピーされる。次に、パッチが基本ブロックのこの新しいコピーに適用される。オリジナルの基本ブロックは、トランポリンコードと呼ばれるコピーされた基本ブロックへのジャンプに置き換えられる。オリジナルのコントラクトコードがターゲットの基本ブロックにジャンプするたびに、トランポリンが実行され、パッチが適用された基本ブロックが配置されているコントラクトコードの最後にコントラクトがジャンプする。コントラクトコードの最後にあるパッチが適用された基本ブロックは、適用されたパッチが基本ブロックを終了する制御フロー命令を変更しない限り、自然に元の変更されていないコントラクトコードに戻る。ただし、すべての基本ブロックがJUMP命令のような明示的な制御フロー命令で終了するわけではない。基本ブロックが条件付きジャンプ命令(JUMPI)で終了するか、単に制御フロー命令で終了しない場合は、常に制御フローグラフに暗黙のエッジがある。このフォールスルーエッジは、単に次のアドレスでの命令の実行の継続である。
【0097】
フォールスルーエッジを処理するには、2つのケースを考慮する必要がある。フォールスルーエッジの対象となる基本ブロックがJUMPDEST命令で始まる場合、基本ブロックは通常のジャンプの正当なターゲットとしてマークされる。この場合、コントラクトの最後に書き換えられた基本ブロックに明示的なジャンプが追加され、元のコントラクトコードの次の基本ブロックの先頭から実行が継続されることが保証される。次の基本ブロックがJUMPDEST命令で始まらない場合、EVMはこのアドレスへの明示的なジャンプを禁止する場合がある。この場合を処理するために、リライタは、基本ブロックを書き換えられた基本ブロックのすぐ後ろのコントラクトの最後にコピーし、リライトされたコードの制御フローグラフに別のフォールスルーエッジを構築する。
【0098】
図9は、本発明の実施形態において、リライタがどのように機能するかの例を示している。左側がオリジナルのコード、右側が書き換えられたコードである。オリジナルの基本ブロックは、パッチが適用された基本ブロックのバージョンにジャンプするトランポリンで置き換えられる。パッチが適用された基本ブロックは、オリジナルのコントラクトの末尾直後に追加される。
【0099】
図9を参照すると、通常のADD命令は、整数のオーバーフローチェックを追加で実行するチェック追加ルーチンに置き換えられる。ADD命令のアドレスがパッチポインタと呼ばれることが提供され得る。これを実現するために、パッチポイントを含む基本ブロックがトランポリンに置き換えられる。このケースでは、すぐに0xFFBの基本ブロックにジャンプする。コントラクトの最後にある基本ブロックは、0xABにあるオリジナルの基本ブロックのコピーであるが、パッチが適用されている。基本ブロックはコントラクトの末尾にあるため、バイトコードリライタは、次の基本ブロックのアドレスを変更することなく、基本ブロックの命令を挿入、変更、および削除できる。オリジナルの基本ブロックの残りの部分は、INVALID命令で埋められる。リライタは、パッチが適用された基本ブロックの0xFFBに追加して明示的にジャンプする。これにより、アドレス0xCDのオリジナルのコントラクトのコードで実行が継続される。
【0100】
EVMは、コードアドレス領域内のコードとデータの分離を強制する。ほとんどのEVM実装は、PUSH命令に埋め込まれているデータ定数へのジャンプを防ぐ。プッシュ命令の定数オペランドは、命令オペコードのバイトの直後に続く。このような定数オペランドには、誤ってJUMPDESTオペランドのバイトが含まれる可能性がある。その場合、定数は正当なジャンプターゲットになり、新しい意図しない命令シーケンスが発生する。このEVM実装を回避するには、コードセクションで線形スイープを実行してプッシュ命令を見つる。これらのプッシュ命令の一部である定数は、データとしてマークされるため、無効なジャンプターゲットとしてマークされる。ただし、パフォーマンス上の理由から、EVM実装はデータをマークするときに制御フロー情報を無視する。そのため、プッシュ命令のオペコードバイトは、文字列やその他のバイナリデータなどのデータ定数の一部である可能性がある。このため、スマートコントラクトコンパイラは、到達可能なコードよりも厳密に大きいアドレスにすべてのデータ定数を蓄積する。これにより、生成されたコードとコードアドレス領域にエンコードされたデータとの間の競合が回避される。ただし、トランポリンベースのリライタは、スマートコントラクトのデータ定数の背後にコードを追加する。リライタによって追加されたコードが、先行するプッシュオペコードバイトのために誤って無効なジャンプ先としてマークされることを回避するために、オリジナルのコントラクトのデータと新しく追加されたコードの間にパディングが挿入される。パディングの必要な長さを計算するには、EVM実装と同じ線形スイープを実行できる。
【0101】
ほとんどのコントラクトには、コントラクトの最後に追加のメタデータが含まれている。たとえば、Solidityは、各コントラクトの最後に、スウォームハッシュと呼ばれるハッシュ値の特別なエンコーディングを追加する。コントラクトは、スウォームハッシュで終了することが期待される。そのため、バイトコードリライタは、スウォームハッシュを特別な方法で処理する。バイトコードリライタは、スウォームハッシュの後にコードを追加する代わりに、元のスウォームハッシュの直前の間に新しいコードとデータを挿入する。これにより、書き換え後でも、スウォームハッシュが常にコントラクトの最後にあることが保証される。通常のコントラクトはコード内のスウォームハッシュを参照しないため、スウォームハッシュのアドレスは元のコードに影響を与えることなく変更できる。
【0102】
トランポリンベース書き換えアプローチでは、最小限のコード分析のみが必要であり、ほとんどのユースケースで機能する。ただし、このアプローチには2つの欠点がある。まず、命令は、コントラクトの最後にジャンプするトランポリンコードも含めるのに十分な大きさ(バイト単位のサイズ)の基本ブロックにのみパッチを適用できる。ただし、通常のトランポリンには4~5バイトが必要であり、通常、意味のある計算を実行する基本ブロックは、トランポリンコードを含めるのに十分な大きさである。次に、基本ブロックのコピーにより、パッチが適用される基本ブロックに応じてコードサイズが大きくなり、デプロイコストが増加する。トランポリンを挿入することによって誘発されるオーバーヘッドの評価は、以下のセクションVBに示される。
【0103】
実施形態では、Pythonでトランポリンベースリライタを実装することができる。リライタは、pyevmasmライブラリを利用して、生のEVMオペコードを逆アセンブルおよびアセンブルできる。さらに、リライタは制御フローグラフ回復ライブラリevm_cfg_builderを使用できる。このライブラリは、選択値群分析を実行してジャンプターゲットを回復し、正確な制御フローグラフを作成する。ただし、リライタがこの制御フローグラフの回復に依存せず、制御フローグラフの回復が失敗した場合に、フライ上に部分的な制御フローグラフを作成できることが規定されている場合がある。
【0104】
IV.C.パッチの検証
パッチを適用したコントラクトの機能的正確性を確保するために、本発明の実施形態では、コントラクトのすべてのトランザクションを再実行し、オリジナルの脆弱なコードと新しくパッチを当てたコードの動作が異なるかどうかを判断することができる。まず、脆弱なコントラクトに対するトランザクションのリストを取得する場合がある。次に、トランザクションを再実行し、脆弱なコントラクトに対する各トランザクションの実行トレースを取得する場合がある。次に、同じトランザクションを再実行するが、脆弱なコントラクトのコードをパッチを適用したコントラクトコードに置き換える。元のEthereumクライアントはこの機能をサポートしていないため、これは、人気のあるgo-ethereumクライアントに基づいて変更されたEthereumクライアントを使用して実行できる(たとえば、バージョン1.8.27-stable-3e76a291を使用できる)。パッチが適用されたコントラクトを使用したトランザクションの実行トレースも取得される場合がある。最後に、両方の実行トレースを比較して、両方のコントラクトの動作が等しいことを確認できる。パッチ検証者は、動作が異なるトランザクションのリストを生成する場合がある。そのようなトランザクションがない場合は、パッチがコントラクトの機能を阻害していないと見なすことができる。
【0105】
パッチ適用プロセスは、制御フローを変更し、命令を挿入するため、脆弱なコントラクトとパッチ適用されたコントラクトの実行トレースを完全に等しくすることはできない。したがって、状態を変更する可能性のある命令のみが検査されることが提供される場合がある。さらに、すべての命令がストレージに書き込むか、実行フローを別のコントラクト(CALL命令など)に転送する場合、すべての命令を状態変更と見なすことが提供される場合がある。次に、実施形態では、すべての状態変更命令の順序、パラメータ、および結果を比較し、2つの実行トレースが異なる最初の命令を報告することができる。現在、実施形態では、導入されたパッチが新しい状態変更命令を導入しないと想定することができる。この仮定は、入力検証コードを導入し、無効な入力が渡されたときに元に戻すパッチにも当てはまる。ただし、トレース差の計算は、パッチによって導入される潜在的な状態変化を認識し、それらの命令を無視するように適合させることができる。
【0106】
次に、パッチ検証者は、動作が異なるトランザクションのリストを最終的に出力する。次に、パッチが適用された実行トレースがより詳細に調べられる。失敗したトランザクションがパッチを適用したコードの復帰によるものである場合、トランザクションは潜在的な攻撃としてマークされる。失敗したトランザクションがガス不足のために失敗した場合、実施形態では、ガスバジェットを増やして同じトランザクションを再実行することができるが、警告を発する。最後に、開発者は失敗したトランザクションを調べて、失敗したトランザクションの特定のリストが正当なトランザクションなのか実際の攻撃なのかを判断する必要がある。
【0107】
IV.D.パッチテンプレート
実施形態では、バイトコードリライタは、EVMアセンブリ言語の短い小片として形成されたパッチテンプレートを取得ことができる。このテンプレートは、パッチが適用されるコントラクトに従って特殊化され、パッチが適用されたコントラクトの最後に再配置される。バイトコードリライタの拡張アセンブラは、パッチテンプレートでシンボリックラベルをサポートする。これは、パッチが適用されたバイトコードが生成されるときに解決される。これにより、パッチテンプレートの移植可能な実装が可能になる。
【0108】
パッチ生成におけるテンプレートベースアプローチにより、脆弱性のクラス全体に複数の汎用パッチを指定できる。次の脆弱性クラスは、テンプレートベースアプローチを使用して自動的にパッチを適用できる。
【0109】
重要な関数への不適切なアクセス制御は、関数の先頭にチェックを挿入して、呼び出し元が特定の固定アドレスであるか、コントラクトの状態に格納されているアドレスと等しいことを確認することでパッチを適用できる。
【0110】
低レベルの呼び出し命令をSolidityで使用する場合の誤った処理の例外戻り値は自動的に処理されず、コントラクトは例外を発生させない。このような問題は、呼び出し命令の後に一般的な戻り値チェックを挿入することで修正できる。
【0111】
Solidityはデフォルトでチェックされた算術を使用しないため、整数の算術を処理するときの整数のバグは、問題が発生しやすくなる。これにより、脆弱な可能性のある多くのコントラクトがデプロイされ、一部は積極的に攻撃される。実施形態では、バイトコードリライタのショーケースとして、整数のバグに自動的にパッチを適用することに焦点を当てている(セクションVを参照)。
【0112】
ただし、コントラクトのビジネスロジックに深く関係している特定の種類の脆弱性については、一般的なパッチテンプレートを作成できない場合がある。この場合、開発者は、パッチ自体を開発する必要があり、本発明の実施形態にてシステムによってサポートされる。
【0113】
IV.E.パッチを適用したコントラクトのデプロイ
本発明の実施形態では、アップグレード可能なスマートコントラクトをサポートするために、delegatecall-proxyベースのアップグレードパターンを利用することを提供することができる。このパターンは、ZeppelinOSプロジェクトですでに正常に実装されている。スマートコントラクトは、プロキシコントラクトとロジックコントラクトの2つのコントラクトに分割される。プロキシコントラクトは主要なエントリポイントである。プロキシコントラクトのアドレスは固定されており、変更されない。プロキシコントラクトでは、すべてのデータも直接保存される。プロキシコントラクトのコードは、デプロイ後にアップグレードできないため、最小限に抑えられる。プロキシコントラクトは、すべての呼び出しをロジックコントラクトに転送するだけである。ロジックコントラクトには、コントラクトのすべてのビジネスロジックが含まれ、到着したトランザクションを処理する。プロキシコントラクトは、DELEGATECALL命令を利用してロジックコントラクトを呼び出す。これにより、ロジックコントラクトはプロキシコントラクトのストレージメモリ領域に直接完全にアクセスできるようになり、ロジックコントラクトが追加のオーバーヘッドなしで持続データにアクセスできるようになる。
【0114】
アップグレードを容易にするために、プロキシコントラクトはロジックコントラクトのアドレスを保存および更新する機能も実装している。悪意のあるアップグレードを防ぐために、プロキシコントラクトには、アップグレードの発行が許可されている所有者のアドレスも格納される。アップグレードは、プロキシコントラクトへの1つのトランザクションであり、(1)呼び出し元が所有者であるかどうかを確認し、(2)ロジックコントラクトのアドレスを更新する。このトランザクションの後、プロキシコントラクトはすべての呼び出しを新しくデプロイされたバージョンのロジックコントラクトに転送する。
【0115】
V.ユースケース:整数オーバーフローハードニング
スマートコントラクトの脆弱性の1つの主要なクラスは、整数のバグである。従来の機能では、多くのコントラクトが脆弱であり、一部は積極的に攻撃されていることが示されている。このため、整数バグと特に整数オーバーフローは、本発明の実施形態におけるバイトコード書き換えベースのパッチ適用フレームワークを紹介するための優れたターゲットとなっている。
【0116】
V.A.整数オーバーフローパッチ
本発明の実施形態では、符号なし256ビット整数型の整数オーバーフローおよびアンダーフローを検出するためのパッチテンプレートを提供することができる。これらのパッチテンプレートは、Cプログラミング言語のセキュアコーディングルールによるチェックと、SafeMathSolidityライブラリで実行されるチェックを追加する。実施形態では、バイトコードリライタには、整数の加算、減算、乗算をチェックするためのパッチテンプレートが付属している。パッチテンプレートを使用して、整数オーバーフローに対して脆弱な単一の算術命令を、チェックされたバリアントに置き換えることができる。そのため、パッチは、ガスのオーバーヘッドを最小限に抑え、コントラクトへの侵入を最小限に抑えるように最適化されている。パッチは、整数オーバーフローまたはアンダーフローが発生したことを検出し、例外を発行する。例外は、現在のコールを中止してコントラクトにロールバックする。セクションV.B.において通常のSafeMathSolidityライブラリと比較したチェックの効率の評価が示される。
【0117】
図10は、オリジナルのバイトコードと、本発明の実施形態におけるバイトコードリライタによって生成された、オリジナルと同じバイトコードのパッチ適用されたバージョンと、を示している。上のリストはオリジナルのコードを示し、下のリストはチェックされた追加パッチが適用された書き換えられたバージョンのコードを示している。コメントは、命令のガス利用を示している。オリジナルのターゲットコントラクトは、2つの定数を追加するだけで、実行を停止する。パッチが適用されたコードでは、アドレス0x00のオリジナルの基本ブロックがトランポリンに置き換えられていることが示されている。トランポリンはすぐにアドレス0x07のパッチが適用された基本ブロックにジャンプする。ここで、チェックされた追加パッチテンプレートは、アドレス0x04にあった元のADD命令を置き換えている。挿入されたトランポリンコードとオリジナルのコードへのジャンプバックは、コントラクトで使用される23の追加ガスになる。この例では、チェックされた追加パッチテンプレートが適用され、(a + b)> = aという不変条件が検証される。チェックされたバージョンの追加では、オーバーフローが検出されない場合、追加の35ガスが必要になる。
【0118】
V.B.評価
実施形態におけるバイトコードリライタによって生成されたパッチの正確さを検証するために、Peckshieldと呼ばれるセキュリティ会社によって報告された既知の脆弱性に焦点を当てる。より具体的には、これらのエクスプロイトに基づいて攻撃された整数オーバーフロー/アンダーフローの脆弱性が確認された5つのERC-20トークンコントラクト(
図11の表を参照)が見つけられている。
【0119】
これらコントラクトには、セクションVで示されるバイトコードリライタによる自動パッチ適用プロセスが適用される。一方、手動でパッチを適用したコントラクトと比較するために、整数オーバーフローがSafeMathライブラリの関数に関係する算術演算を置き換えることにより、Solidityソースコードでこれらのコントラクトを書き換えている。パッチが適用されたソースコードは、etherscan.ioにあるオリジナルのコントラクトと同じsolcコンパイラバージョンと最適化オプションを使用してコンパイルされる。次に、パッチの正確性を検証するために、両方のパッチ適用方法から生成された結果のコントラクトに対してパッチ検証が実行される。また、ガス消費のオーバーヘッドとコードサイズの増加も測定される。これにより、コントラクトのデプロイおよび運用段階での取引手数料が高くなります。
【0120】
手動パッチ適用方法では、開発者がコードにパッチを適用する方法がシミュレートされるため、Osirisによって検出されたすべての脆弱性にパッチが適用されるわけではないことに注意すべきである。そのため、攻撃者がトリガーできない脆弱性のチェックはスキップされる。たとえば、潜在的に脆弱な演算は、良性のプレーヤーと見なされるコントラクトの管理者や所有者などの特別なアカウントによってのみ呼び出すことができる関数に含まれているためである。
【0121】
パッチ検証コンポーネントには、実際のトランザクションが提供される。より具体的には、ブロックチェーンからブロック7,755,100(2019年5月13日)までにこれらのコントラクトに送信されたすべてのトランザクションが抽出され、評価のために合計で最大506,607トランザクションがカウントされる。表Iは、パッチ検証フェーズでのトランザクション実行結果を示している。実施形態におけるバイトコードリライタとSafeMathライブラリの両方によってパッチが適用され改訂されたコントラクトによって実行された一部のトランザクションが失敗したことがわかる。これらのトランザクションがチェックされ、誤検知であるHXGへの1つのトランザクション(0x776da02ce8ce3cc882eb7f8104c31414f9fc756405745690bcf8df21e779e8a4)を除いて、これらがすべて本物の攻撃であることが確認できる。基本的に、このトランザクションは「ブラックホール」アドレスバランス[0x0]でいくつかのトークンを焼き込もうとしている。オリジナルのコントラクトでは、このアドレスにオーバーフローがあるかどうかは関係ない。状態の更新には多くのガスがかかるため、これは一般に悪いコーディング手法である。必要ない場合は保存すべきではない。このような状態は悪用できないが、Osirisは十分に正確ではなく、リライタはOsirisによって報告されたすべての算術命令に保守的にパッチを適用している。
【0122】
パッチが適用されたコントラクトによってオリジナルに戻される有効な攻撃トランザクションを除いて、再実行されたトランザクションの実行トレースは、オリジナルのトランザクションの実行トレースと一致する。これは、パッチが適用されたコントラクトが、検証されたトランザクションに関する限り、元の動作を保持することを意味している。実行トレースの比較では、正確な操作シーケンスはチェックされないが、ストレージへの書き込みや外部呼び出しの開始など、状態が変化する可能性のある命令が調べられることを思い出すべきである。また、パッチが適用されたコードを使用してトランザクションを実行するときのガス切れ例外も無効になっている。これは、オリジナルのトランザクションで提供されたものよりも多くのガスを消費する可能性があるためである。このようにして、パッチが適用されたコントラクトが異なる状態更新をもたらすかどうかの検証にのみ焦点を当てているため、ガス不足によって再実行されたトランザクションが失敗することを回避できる。もしそうなら、それはトランザクションをオリジナルに戻す原因となる潜在的なエクスプロイトのみを含むべきである。
【0123】
ガスオーバーヘッド:トランザクションの再実行中に、ガス消費量が追加で記録され、その結果を
図12の表に示す。一部のトランザクションは、脆弱なコードを含むこれらのパスを実行しないことに注意すべきである。実施形態におけるパッチは、これらのパスに影響を与えないため、バイトコードリライタもSafeMathもガスオーバーヘッドを発生させていないトランザクションは結果から除外される。
図12の表では、コントラクトBEC、SMT、HXGの場合、EVMレベルでパッチが適用されたものは、ソースコードレベルでパッチが適用されたものと比較して(164、108、541)、実行時のガスオーバーヘッドが少ない(83、47、120)、ことが示されている。SafeMathライブラリを使用してソースコードレベルで整数オーバーフローチェックにパッチを適用すると、追加されるチェックが非常に少ない場合、Solidityコンパイラは最適でないコードを生成する。これは、SolidityがSafeMathライブラリ関数を呼び出すための内部関数呼び出しを生成するためである。これにより、ライブラリ関数が多くの呼び出しサイトから呼び出されるときにコードサイズが削減される。ただし、内部関数呼び出しでは、内部呼び出しをセットアップし、内部呼び出しから戻るために追加のコードが必要である。そのため、内部呼び出しを利用すると、全体的なコードサイズは減少するが、ガスのオーバーヘッドは増加する。通常のかなり短い整数オーバーフローチェックの場合、評価は、バイトコード書き換えアプローチによりガスオーバーヘッドが少なくなることを示している。典型的なコンパイラの最適化は関数のインライン化である。これにより、ソースレベルのパッチが適用されたバージョンが、書き換えられたバージョンと同様のオーバーヘッドになる可能性がある。
【0124】
EVMレベルでパッチが適用されたコントラクトUETとSCAが同じ結果を示さないことにも注意すべきである。実際、UETは、アップグレード後のすべてのトランザクションで平均255ユニットの追加ガスを必要とする。これに対して、手動でパッチを適用したアプローチを使用した場合は21ガスである。これは、バイトコードリライタがこれら2つのコントラクト(それぞれ12と10)で報告されたすべての脆弱性にパッチを適用しましたが、関連する整数オーバーフローのバグはコントラクトの所有者またはコントローラーによってのみトリガーされるため、これらの脆弱性のすべてが手動パッチで処理されるわけではないためである。時々それはまた悪いコーディング慣行とOsiris分析の正確さのためである。たとえば、コントラクト内の一部の状態で潜在的なオーバーフロー/アンダーフローが発生する可能性があるが、変数はコントラクト内の他の場所で参照されないため、オーバーフロー/アンダーフローを利用できない。手動パッチ方式では、SCAのガスオーバーヘッドが0であることに注意すべきえある。このコントラクトに送信されるトランザクションは292しかないため、SafeMathパッチによって追加された整数境界チェックをトリガーするトランザクションは攻撃トランザクションのみであり、結果として元に戻る。したがって、このトランザクションは統計分析中に考慮されない。
【0125】
コードサイズの増加:ブロックチェーンにコントラクトをデプロイすると、デプロイされたコントラクトのサイズに比例するコストも発生する。より具体的には、イーサリアムは、コントラクトコードを状態に格納するためのCREATE操作に対してバイトあたり200ガスを請求する。したがって、両方のパッチ適用方法によってコントラクトに追加された余分なバイトの量も測定され、結果は
図12の表に示されている。脆弱性が1つある場合、リライタによって追加される追加コードの量は、SafeMathアプローチによるものと同等であることが示されている。たとえば、BECコントラクトのサイズはそれぞれ117Bと133B増加するが、SMTコントラクトのサイズはそれぞれ191Bと97B増加する。実施形態によるアプローチはオリジナルの基本ブロックを複製しているため、これによるコードサイズのオーバーヘッドは脆弱性の具体的な位置に依存する。コンパイラはパッチに必要なコードよりもSafeMathライブラリに対するコードを多く生成するため、SafeMathアプローチ(BECの場合)よりも小さくすることができます。または、SMTの場合のように、関連する基本ブロックに多くの命令が含まれている場合は、さらに大きくなる可能性がある。
【0126】
ただし、より多くの脆弱性が関係している場合、実施形態のバイトコードリライタもより高いオーバーヘッドを被る。実施形態のリライタは、パッチコードを再利用せずにすべての脆弱性に対してパッチを生成するため、アップグレードされたコントラクトのサイズは、適用されたパッチの数とともに増加する。たとえば、バイトコードリライタは、UETコントラクト用に12パッチ、SCAコントラクト用に10パッチを生成するため、コードサイズが1,299 B(18.2%)および3,811 B(17.3%)増加する。それどころか、SafeMathアプローチでは、サイズがそれぞれ541 B(7.6%)と361 B(1.6%)だけ増加する。SafeMathはソースコードレベルで機能するため、いくつかの最適化を適用できる。第一に、SafeMathはパッチごとに基本ブロックを複製する必要はない。第二に、SafeMathは内部関数呼び出しを利用して、整数のオーバーフローチェックコードにジャンプする。一方、実施形態では、パッチが適用されたすべての基本ブロックにチェックコードを直接挿入する。第三に、手動パッチ適用により、SafeMathパッチ適用コントラクトには開発者が悪用できない整数演算にパッチを適用しないため、整数オーバーフローチェックが少なくなる。ただし、パッチテンプレートは、単一の脆弱な演算にパッチを適用するように最適化されている。実施形態では、バイトコードリライタ用のパッチテンプレートを開発する場合、Solidityの内部関数呼び出しに類似したアプローチを採用するのは簡単である。これにより、多数の整数オーバーフローにパッチを適用するときに、コードサイズのオーバーヘッドを削減できる。
【0127】
これらの5つのコントラクトに加えて、Osirisは14,107の個別のコントラクトのセットを提供し(OsirisはEthereumブロックチェーンの最初の5,000,000ブロックで50,535の一意のコントラクトを分析した)、Osirisは少なくとも1つの整数オーバーフローの脆弱性を検出する。これらのコントラクトのすべてにソースコードが利用できるわけではないため、これらのコントラクトにはバイトコードリライタでのみパッチが適用される。
図13の表に示した結果から、コントラクトの元のサイズは平均で8,142.7 Bであるのに対し、パッチを適用した後のサイズは平均で455.9 B(5.6%)増加することが示されています。イーサリアムがコントラクト作成トランザクションに1バイトあたり200ガスを請求することを考えると、コントラクトのデプロイ中に平均91,180ガスまたは0.021 USDのオーバーヘッドが発生する(計算は235.091 USD / ETHおよび1gweiのガス価格に基づいている)。これは、バイトコードの書き換えでパッチを適用するオーバーヘッドが、コントラクトのデプロイ中に無視できることを示している。
【0128】
最後に、
図14には、各コントラクトに対して呼び出されたトランザクションのタイムラインが描かれており、パッチが適用されたコントラクトによって元に戻される検出された攻撃と、対応するCVEが開示される時間窓と、が示されている。他のトークンコントラクトの脆弱性は最初の攻撃からかなり妥当な時間内に報告されているが、UETはバグが開示されるずっと前(5か月)に悪用されていることが示されている。さらに驚くべきことに、脆弱性が公開された後、取引量が減少したにもかかわらず、すべてのコントラクトは依然としてかなり活発である。これらの脆弱性はすべて、執筆時点の約1年前に発見されたが、攻撃の成功を含め、脆弱性の公開後、これらの脆弱なコントラクトに対して発行されたトランザクションは23,630件(評価されたトランザクションの4.66%)である。
【0129】
V.C.誤検知/失敗の分析
コントラクトの分析中に、OSIRISによって報告されたすべての整数オーバーフローバグにパッチを適用すると、誤検知と失敗が特定された。このことは、多くの解析ツールが完ぺきとは言えないように、本実施形態におけるパッチ検証がプロセスにおいて重要なステップであることを示している。詳細に分析された5つのトークンコントラクトでは、誤検知と失敗の両方が特定されている。オリジナルのOSIRISペーパー(C. Ferreira Torres, J. Schutte, and Others, “Osiris: Hunting for integer bugs in ethereum smart contracts,” in 34th Annual Computer Security Applications Conference (ACSAC18), San Juan, Puerto Rico, USA, December 3-7, 2018, 2018. [Online]. Available: http://orbilu.uni.lu/handle/10993/36757)の報告に反しているが、すべての脆弱性が正確に検出されるわけではない。デフォルトの構成では、OSIRISはしばしば不十分なコードカバレッジを行っている。分析全体とSMT解決者へのすべてのクエリの両方で異なるタイムアウト設定が使用される。複数の実行の結果をさまざまなタイムアウトオプションと組み合わせて、コードカバレッジを向上させている。それにもかかわらず、OSIRISが整数のオーバーフローのバグを正確に報告していない2つのケースが見つかった。
【0130】
ヘキサゴン(HXG)トークン:ヘキサゴントークンコントラクトは、整数オーバーフローに対して脆弱であるため、攻撃者は非常に大量のERC-20トークンを転送できる。Osirisは、Solidityコンパイラによって生成された奇妙なEVMコードが原因である2つの誤検知を報告する。
図15に、Solidityと対応するEVMコードを示す。Solidityソースコードではすべての型が符号なしの型であるが、コンパイラは符号付きの加算を生成する。ここで、Osirisは、balanceOfマッピング変数に-2が追加されたときに、整数オーバーフローの可能性を正しく報告する。負の値で符号付き整数の加算を実行する場合、結果が負の値の範囲から正の値の範囲に、またはその逆に移動すると、加算は自然にオーバーフローする。
図15の下のリストの12行目のADDにパッチを適用すると、追加がチェックされ、誤検知が発生する。パイプラインのパッチ検証者は、オリジナルのコントラクトが失敗しなかったときに、ほとんどすべてのトランザクションが失敗したことを示した。これは、失敗したパッチの指標である。パッチが適用されたコントラクトのバイトコードを手動で分析することにより、パッチに欠陥がある理由を特定し、Osirisの誤検知に起因する可能性がある。ただし、Osirisは整数の型を符号なし整数として正しく推測し、オーバーフローを正しく報告する。ここでの問題は、コンパイラが符号なし整数を符号付き整数として扱わないという仮定である。これは合理的な仮定である。単純な符号なし減算と比較した場合、生成されたコードには追加の命令が必要なため、根本的な原因はおそらくSolidityのコンパイラのバグであると結論付けられる。
【0131】
Social Chain(SCA):Osirisは、問題があると考えられているSolidityソースコード行のオーバーフローの可能性を検出していることがわかる。ただし、Osirisは、乗算が整数のオーバーフローに対して脆弱であると報告するだけである。実際の攻撃トランザクションでは、次の追加がオーバーフローする。そのため、OSIRISの誤検知により、自動的にパッチが適用されるコントラクトは依然として脆弱である。このことは、すべてのトランザクションを再実行するときと、本実施形態におけるパッチ検証を実行する部分としてコントラクトの手動パッチ適用したバージョンと比較するときに、気づかされる。
【0132】
VI.まとめ
DAO攻撃は、2016年に、莫大な経済的損害を伴うスマートコントラクトの脆弱性により、最初に一般の注目を集めた。それ以来、ブロックチェーンコミュニティはスマートコントラクトの監査と脆弱性分析の実施を開始し、ますます多くの不具合が発見されている。これらの研究の中で、シンボリック実行、フォーマル検証、および汚染分析に基づいて多くのツールが開発されている。これらの分析ツールは、開発者がコントラクトをデプロイする前にコントラクトの潜在的な脆弱性を確認するのに役立ち、攻撃を防ぐ。ただし、一度デプロイされたコントラクトに簡単にパッチを適用する効果的な方法はまだない。Sereumなどの一部の動的分析ツールをEVMに統合して、脆弱なコントラクトに対するライブ攻撃を阻止できる。ただし、このようなツールをデプロイするには、ブロックチェーン開発チームと協力してクライアントソフトウェアをアップグレードする必要がある。このようなプロセスは非常に時間がかかる可能性があり、これらの分析ツールはほとんどブロックチェーンネットワークから切断されたままである。
【0133】
より簡単であるが、アドホックなアプローチは、脆弱なコントラクトの開発者が不具合とバグについて通知を受け、パッチをコントラクトに手動で適用することである。次に、パッチが適用されたコントラクトは、delegatecallプロキシパターン(セクションIIを参照)を介してバグのあるバージョンをZeppelinOSなどのフレームワークに置き換えることができる。このアプローチの主な課題は、コントラクト開発者が、導入されたパッチがビジネスロジックを変更するかどうか、たとえばバージョンが異なるためにSolidityコンパイラが予期せず問題を解決するかどうかを確認する必要があることである。このような整合性チェックは、ユニットテストがある場合はそれと、Slitherなどの「アップグレード可能性」チェックを実行するいくつかのツールを使用して実行できる。静的分析フレームワーク[40]に加えて、Slitherはコントラクトのソースコードも確認し、それが引き続きdelegatecall proxyパターンと整合しているかどうか、および変数が同じ順序で宣言されているかどうかを確認する。Solidityコンパイラは、宣言の順序に基づいて、ストレージ内のシーケンシャルアドレスをコントラクトスコープ変数に割り当てる。アップグレードされたコントラクトで変数が異なる順序で宣言されている場合、既存のデータが異なる変数にマップされるため、問題が発生する可能性がある。このようなアドホックなパッチ適用方法には、コントラクト開発者の時間と経験の両方が必要である。
【0134】
本発明の実施形態におけるコントラクトパッチ適用フレームワーク(すなわち、コントラクト書き換えフレームワークシステム)は、既存の分析ツールを組み合わせて、検出された脆弱性にパッチを適用するための半自動方法を提供し、パッチ適用後のコントラクト一貫性を検証することができる。パッチ検証データセットは完全ではないかもしれないが、既存の単体テストを補完するものである。さらに、バイトコードの書き換えにより、コンパイラの予期しない動作によって引き起こされる潜在的な問題が防止される。
【0135】
また、本発明の実施形態では、整数オーバーフロー脆弱性にパッチを適用するユースケースも示されている。Osirisは、シンボリック実行ツールOyenteを拡張して、バイトコードレベルでの型推論と整数バグ検出をサポートしている。この改善されたシンボリックエグゼキュータは、最初に、Solidityコンパイラによって生成された特定の最適化命令から整数型、つまり符号とビット幅を推測しようとする。次に、切り捨て、オーバーフロー、アンダーフロー、間違った型キャストなど、考えられる整数のバグをチェックする。TeEtherやMAIANなどの他のツールは、スマートコントラクトの不具合が生じたときに、整数のバグを暗黙的に検出する。ただし、これらのツールは整数のバグを見つけることを目的としていないため、整数オーバーフローが発生するコード内の正確な場所を正確に特定することはできない。
【0136】
本発明の多くの変形例および実施形態は、上述した説明および関連する図面に記載された教示により、本発明が関係する当業者には思い浮かぶであろう。したがって、本発明は、開示された特定の実施形態に限定されるものではなく、変形例および実施形態は添付の特許請求の範囲内に含まれることが意図されていることを理解されたい。本明細書では特定の用語が使用されているが、それらは一般的かつ説明的な意味でのみ使用されており、限定の目的では使用されていない。
【0137】
特許請求の範囲で使用される用語は、上述した説明と一致する最も広い合理的な解釈を有すると解釈されるべきである。例えば、要素を説明する際の冠詞「a」または「the」の使用は、複数の要素を排除するものとして解釈されるべきではない。同様に、「または」の記述は、「AまたはB」の記述が「AおよびB」を除外しないというように、包括的であると解釈されるべきである。但し、文脈または先の記述から、AとBの1つのみが意図される場合を除く。さらに、「A、B、およびCの少なくとも1つ」の記述は、A、B、およびCで構成される要素のグループの1つまたは複数として解釈されるべきであり、A、B、Cがカテゴリとして関連付けられているかどうかに関係なく、A、B、Cからなるリストのうちいずれか1つを必要とするように解釈されるべきではない。さらに、「A、B及び/又はC」または「A、B又はCの少なくとも1つ」の記述は、リストされた要素からの任意の単一エンティティ、例えばA、リストされた要素からの任意のサブセット、例えばAとB、又は、要素A、B、Cといったリスト全体、を含むと解釈されるべきである。