Back to Blog

CashioAppのセキュリティインシデントを再検証する

Code Auditing
2022年5月16日
5 min read

2022年3月23日 16:20:08 UTC+8に始まった攻撃で、CashioAppの担保トークンアカウントから資産が流出し、約5,200万の損失が生じました。入力アカウントの検証が不十分だったため、攻撃者は何も預け入れずに200億の$CASHトークンを発行できました。以下、その技術的な詳細を示します。

概要

このインシデントは、Saber LP Arrowsを担保として$CASHトークンの発行とバーンを処理するよう設計されたBrrrプログラムのバグが原因でした。具体的には、ユーザーはArrow LPトークンを預け入れることで$CASHを発行できます。なお、Arrow LPトークンはSaber LPトークンを原資産として受け取ります。$CASHを発行できるprint_cash命令は、BankアカウントやCollateralアカウントを含むアカウントのリストを受け取ります。これらのアカウントは、$CASHの発行に使用できる担保、すなわちArrow LPトークンの記録と追跡に使われます。設計上、この2つのアカウントを初期化して権限を付与できるのは管理者だけであるべきです。しかし、プログラムはBankアカウントの有効性を確認していません。その結果、攻撃者はBankアカウントを含む一連の偽アカウントを作成してprint_cash命令に渡し、ほぼ無償で$CASHを発行できました(必要な費用はトランザクション手数料のみです)。

詳細

まず、以下のprint_cash命令で使用されるアカウントから分析を始めます。

属性common(75行目)は、プログラム内で型がBrrrCommonの構造体です。BrrrCommonでは、bankアカウントとcollateralアカウントが管理者によって初期化され、権限を付与されます。crate_tokenは$CASHトークンのアカウントであり、crate_mintの公開鍵(107行目)や管理者ロールの公開鍵など、$CASHに関する情報を格納します。crate_collateral_tokensは、ユーザーから送られた担保トークンを保管する保管庫アカウントです。担保はSaberのLPトークンを受け取るArrow LPトークンである必要があるため、ユーザーはsaber_swapの関連アカウントを入力しなければなりません。構造体BrrrCommonの最後の2つの属性は、この命令で使用される対象プログラムのプログラムIDです。なお、構造体PrintCashの最後の4つの属性は、ユーザーのシステムアカウント(トランザクションの署名者でもあります)、ユーザーの担保アカウント、発行された$CASHを受け取るユーザーの$CASHトークンアカウント、そして$CASHを発行する権限を持つアカウントの公開鍵です。

攻撃トランザクション

上記のアカウントの機能を踏まえ、次に攻撃トランザクション0x4fgL…z2K5を分析します。この攻撃は攻撃者のアドレス(0x6D7f)から開始されました。PrintCash命令への入力アカウントのリストを以下に示します。

上記のAccount #1(0x5aha)は、Bankアカウントに対応します。このアドレスはCashioAppの公式ウェブサイトに掲載されたアドレス(0xEm1P)と異なっていました。つまり、Bankアカウントの検証が不十分だったのです。

検証

この検証をどのように回避できたのかを明らかにするため、コード内での構造体BrrrCommonの検証を詳しく見ていきます。

入力されたBankアカウントに対する唯一のチェックは、入力されたCollateralアカウントがBankアカウントに関連付けられていることを確認するものです(12行目)。しかし、偽のCollateralアカウントも渡せば、このチェックは容易に回避できます。さらに、攻撃者は実際の担保資産を支払わずに済むよう、偽のsaber_swapアカウントも渡しました。攻撃者の狙いは、価値のない担保資産を預け入れて価値のある$CASHトークンを発行することだったため、攻撃者が渡すcrate_tokenとcrate_mintは真正なアドレスである必要があります。つまり、Bankアカウントのチェックが不十分だったことで、攻撃者は一連の偽アカウントを作成し、価値のない担保を使って$CASHを発行できたのです。

修正

修正内容は、assert_keys_eq!(self.bank.crate_mint, self.crate_mint)という文の追加です。この文は、Bankアカウントのcrate_mintが、$CASHに対応する正しいcrate_mintであることを保証します。しかし、これによってBankアカウントの有効性はどのように保証されるのでしょうか。答えを見つけるため、bankmanプログラムのNewBank構造体と、crate_tokenプログラムのNewCrate構造体を見てみましょう。

実際、Bankアカウントは、シードにcrate_tokenのアドレスを含むPDAです。一方、crate_tokenも、シードにcrate_mintのアドレスを含むPDAです。これにより、入力されたcrate_mintが有効であれば、Bankアカウントも有効であることが保証されます。正しいcrate_mintがなければ、攻撃者は$CASHを発行できず、攻撃を実行できません。

BlockSecについて

BlockSecは、世界的に著名なセキュリティ専門家のグループによって2021年に設立された、ブロックチェーンセキュリティの先駆的企業です。同社は、新興のWeb3世界の安全性と使いやすさを高め、その大規模な普及を促進することに取り組んでいます。この目的のため、BlockSecはスマートコントラクトとEVMチェーンのセキュリティ監査サービス、セキュリティ開発と脅威の先手を打ったブロックを行うPhalcon Securityプラットフォーム、資金の追跡と調査を行うMetaSleuthプラットフォーム、そしてWeb3の開発者が暗号資産の世界を効率的に探索するためのMetaSuites拡張機能を提供しています。

同社はこれまでに、MetaMask、Uniswap Foundation、Compound、Forta、PancakeSwapなど、300を超える著名な顧客にサービスを提供してきました。また、Matrix Partners、Vitalbridge Capital、Fenbushi Capitalなどの有力投資家から、2回の資金調達で数千万米ドルを調達しました。

公式ウェブサイト:https://blocksec.com/

公式Twitterアカウント:https://twitter.com/BlockSecTeam

Sign up for the latest updates
安全な保管を超えて、第2部:ウォレットの暗号技術を安全に実装する
Security Insights

安全な保管を超えて、第2部:ウォレットの暗号技術を安全に実装する

攻撃者は、保護された秘密鍵のコピーを読み取らずに、その秘密鍵を復元できるのでしょうか。『Beyond Secure Storage』の第2部では、乱数の品質不足、エントロピーの損失、署名用ノンスの不備によって鍵の予測や復元が可能になった6件の事例を検証します。そこから鍵生成と署名に関する実装要件を導き出し、決済機関がコードレビューと導入済みシステムのテストを通じて、それらをどう評価できるかを説明します。

安全な保管を超えて、第1部:安全な決済・署名ワークフローの設計
Security Insights

安全な保管を超えて、第1部:安全な決済・署名ワークフローの設計

攻撃者が秘密鍵を盗まずに、認可されていない操作が有効な署名を得ることは、なぜ可能なのでしょうか。「安全な保管の先へ」第1回では、Bitget、Bybit、Binanceなどの事例を通じて、支払い要求、トランザクションの構築、署名、実行、決済の各段階における認可の不備を検討します。そのうえで、認可されていない操作を防ぎ、損失を抑えるための設計原則を導き出し、レビュー、監査、ペネトレーションテスト、演習によって、それらの防御策をどう検証できるかを説明します。

NEAR Intentsの悪用:返金処理の欠陥とセキュリティ上の教訓
Security Insights

NEAR Intentsの悪用:返金処理の欠陥とセキュリティ上の教訓

NEAR Intentsへの攻撃では、過大な払い戻しイベントを利用し、預け入れた資産が返還された後も内部残高を維持しました。本分析では、レシートの処理の流れと、合計3,865,021 USDTに上るBNB Chainでの7件の出金を再構成します。また、これらの資金流出とプロジェクトが報告した全額回収を区別し、NEARスマートコントラクトの開発と監査におけるセキュリティ上の考慮事項を示します。

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit
CashioAppのセキュリティインシデントを再検証する