CashioApp攻击 - 漏洞是什么以及X-Ray如何检测它

  • Sec3dev
  • 发布于 2022-03-25 20:37
  • 阅读 18

该文章详细分析了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_cashburn_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 个假账户以通过所有有效性检查。

攻击

输入账户(BrrrCommon):

# 账户 地址 备注
1 bank伪造 5ahaayrV5epV3oKChn4S4F5oek2vzoMbRpuC2fB4Q2kv bankman 创建,带有 伪造 crate_mint伪造 crate_token
2 collateral伪造 HrCe9oUYRJKpfWiUwrkRNCxHSRx8gDX1bSF98Aq8qqjq token 程序创建,带有 伪造 collateral.mint
3 crate_token J77Nq48nbq4Etf1voss38R3dTdR3yD7y5F6W6TaVHvmb 有效的 crate_token 和有效的 CASH mint
4 crate_mint CASHVDm2wsJXfhj6VWxb7GiMdoLc17Du7paH4bNr5woT CASH mint
5 crate_collateral_tokens伪造 EAYzx8dqABiNdZKtfavg16rdyShHQB2k5hUa6UmXHiky token 程序创建,带有 伪造 crate_collateral_tokens.mint == collateral.mint
6 arrow伪造 HnWb284fT2yw2jjWyw6Ex7cf72PJvjBSYsK5H4fHEGpw arrow 程序创建,带有 伪造 arrow.mint == collateral.mint
7 saber_swap伪造 8uBqLjfRrwKxDG92nxDVGbkhbsZfaBqJ8Y2wJoXuHmHU 伪造 swap_info 账户,由 Saber 稳定交换程序初始化,带有 伪造 pool_mintreserve_areserve_b
8 pool_mint伪造 GoSK6XvdKquQwVYokYz8sKhFgkJAYwjq4i8ttjeukBmp
9 reserve_a伪造 DBgB7Bw7mQ5Qk7VVcV51qL8FyLDsJDHV5bnJNsPSwVgL
10 reserve_b伪造 3efHXgB12zP1EzKivsYTZeqAWc5YYCio9Dri9XATFsu3
11 token_program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
12 crate_token_program CRATwLpu6YZEeiVq9ajjxs61wPQ9f29s1UoQR9siJCRs

如何修复这个漏洞?

为了验证 bank 账户的有效性,输入账户必须满足两个条件:

条件 1bank 账户的 crate_token 必须有效:

bank.crate_token == crate_token

条件 2bank 账户的 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。

Cashio 的补丁 不足

🟥 补丁 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 如何检测漏洞?

Soteria Premium 自动审计工具有一个检查器,可以自动检测不可信的账户(如此案中的 bank)。

该检查器使用一种算法推断所有输入账户之间的关系和约束。如果任何输入账户未通过验证(即不符合推断的约束),那么潜在的漏洞将被标记。

以下是检测到 bank 账户的漏洞的截图:

该工具还标记了其他未经验证的账户,如 arrow 账户:

Premium 版本目前向少量试点客户开放。 sec3 团队正努力与试点客户合作,尽快向社区发布一个版本。


sec3 审计

sec3(前 Soteria)由区块链安全和软件验证领域的顶尖人士创立。

我们很高兴为 Solana 上的高影响力 Dapps 提供全面的审计服务。请访问 sec3.dev 或发送电子邮件至 contact@sec3.dev

  • 原文链接: sec3.dev/blog/cashioapp-...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Sec3dev
Sec3dev
https://www.sec3.dev/