该文章详细分析了Cashio协议遭受攻击的原因,并探讨了其智能合约中的漏洞及其如何被Soteria检测到。攻击者利用了缺失的银行账户检查,伪造多个输入账户来成功铸造了200万CASH代币。文章还阐述了如何修复这些漏洞,并强调了Soteria的自动审计工具在检测虚假账户方面的有效性。
Cashio 稳定币(CASH)协议最近在一次 攻击 中损失了 5000 万美元。攻击者几乎可以免费铸造 2,000,000,000 CASH 代币。根本原因是 Cashio 的 brrr 智能合约 存在一个漏洞。
Soteria 团队对这次攻击进行了深入分析,并发现:
(1) 攻击者非常 成熟(在攻击前五天开始准备)
(2) 漏洞深藏在缺失输入(银行)账户检查中
(3) C̶a̶s̶h̶i̶o̶ 的补丁仍然 不足(然而,brrr 智能合约在撰写时已被禁用)。 (更正:与来自 Neodyme 的 @siintemal 经过仔细讨论,我们发现补丁 确实修复了假银行问题。详情见“Cashio 的补丁”部分。鸣谢:@sinntemal 和 @nick_soteria)。
重要的是,该漏洞可以被 Soteria 的 Premium 自动审计工具自动检测到。本文详细阐述了细节。
Cashio 的 brrr 程序功能简单:铸造和销毁 CASH 代币。它只有两个指令:print_cash 和 burn_cash:
复杂的部分是 Cashio 使用 Saber LP Arrows 作为抵押品。这两个指令必须提供与 Saber 和 Arrow 相关的一系列输入账户。总共有 12 个账户在结构 BrrrCommon 中声明:
# | 账户 |
---|---|
1 | bank |
2 | collateral |
3 | crate_token |
4 | crate_mint |
5 | crate_collateral_tokens |
6 | arrow |
7 | saber_swap |
8 | pool_mint |
9 | reserve_a |
10 | reserve_b |
11 | token_program |
12 | crate_token_program |
(账户 6-10 被包装在结构 SaberSwapAccounts 中)
由于所有输入账户都是由不受信任的用户提供的,因此可能会被伪造,如何正确验证它们是一个挑战。brrr 程序包括以下检查:
注意:检查 arrow.mint
虽然这些 assert_keys_eq 检查看起来有点繁琐,但它们仍然不够充分:缺少对银行账户有效性的关键检查! 如果攻击者可以提供一个假 bank 账户,那么所有其他检查将变得毫无意义,因为 bank 是信任的根源。
实际上,这正是攻击者所做的:在这 12 个输入账户中,攻击者创建了 8 个假账户以通过所有有效性检查。
为了验证 bank 账户的有效性,输入账户必须满足两个条件:
条件 1:bank 账户的 crate_token 必须有效:
bank.crate_token == crate_token
条件 2:bank 账户的 crate_mint 必须有效:
bank.crate_mint == crate_mint
条件(1)确保如果提供的 crate_token 账户有效,则 bank 不能被伪造。原因是 bank 是一个在 bankman 智能合约 中初始化的 PDA,其种子的一部分就是 crate_token:
条件(2)确保提供的 crate_mint 无法伪造——它与 bank 账户的 crate_mint 相同。在这个上下文中,它确保 bank.crate_mint 确实是 CASH 代币的 mint。
🟥 补丁 v0.2.1 在仅保证条件 2 的情况下,也无法保 证条件 1. 攻击者仍然可以创建一个假银行满足条件 2,并同样创建 7 个其他假账户来通过所有其他有效性检查。
更正:在这篇文章发布后,@siintemal 和 Soteria 团队仔细讨论了 v0.2.1 的补丁。结果证明补丁确实足够确保条件 1(由于在 _bankman 中强制执行的不变性,bankman,@nick_soteria 提到的)!**
具体来说,bank 和 crate_token 都是由 crate_mint 唯一确定的 PDAs,由 bankman new_bank 指令中强制执行的一个不变性确保 bank.crate_mint == bank.crate_token.mint:
bankman 源代码:crate_mint 被分配给 bank.crate_token.mint
bankman 源代码:crate_mint 被分配给 bank.crate_mint
因此,crate_mint 与 crate_token 和 bank 的关系都是 1:1。
补充说明:有了这个补丁,输入的银行账户将不再存在伪造的可能性,但 银行的管理者仍然可以免费铸造 CASH 代币。
bankman 合约有一个 authorize_collateral 指令,用于通过银行的管理者将银行添加到抵押账户。因此,一个假抵押账户可以由银行的管理者授权以满足有效性检查:
然而,我们期望银行的管理者是可信基础的一部分,并且不会被妥协。
Soteria Premium 自动审计工具有一个检查器,可以自动检测不可信的账户(如此案中的 bank)。
该检查器使用一种算法推断所有输入账户之间的关系和约束。如果任何输入账户未通过验证(即不符合推断的约束),那么潜在的漏洞将被标记。
以下是检测到 bank 账户的漏洞的截图:
该工具还标记了其他未经验证的账户,如 arrow 账户:
Premium 版本目前向少量试点客户开放。 sec3 团队正努力与试点客户合作,尽快向社区发布一个版本。
sec3(前 Soteria)由区块链安全和软件验证领域的顶尖人士创立。
我们很高兴为 Solana 上的高影响力 Dapps 提供全面的审计服务。请访问 sec3.dev 或发送电子邮件至 contact@sec3.dev
- 原文链接: sec3.dev/blog/cashioapp-...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!