关于Jet Protocol中的2000万美元漏洞

  • Sec3dev
  • 发布于 2022-04-02 18:33
  • 阅读 42

文章详细讨论了Jet Protocol中的一个潜在漏洞,该漏洞若被利用可能导致2000万美元的用户资金损失。文章分析了漏洞的起因、如何变得可利用以及最后是如何修复的,并强调了sec3的X-Ray自动审计工具在自动识别此类漏洞中的作用。

最近,Charlie You 公开了 Jet Protocol 中的一个漏洞(查看推文)。如果这个漏洞被利用,将导致 Jet 用户损失 2000 万美元的资金。幸运的是,Jet 在任何用户受到影响之前进行了修复。

sec3 团队在 Jet-v1 的代码中发现了一些棘手的问题,并在披露后不久与 Charlie 进行了讨论。事实证明,这个漏洞的原因与 Charlie 预期的不同。以下是总结:

  • 原因实际上是 未验证的输入 账户,并且 sec3 X-RayAuto Auditor 可以轻松检测到这个问题。
  • 该漏洞是在 2021年12月15日的 commit 6133de 中引入的,但 不可利用。
  • 该漏洞 2021年12月21日的 follow-up commit 1f7da4变得可利用。
  • 可利用窗口 跨越五周,从 12月21日到 1月27日。
  • Anchor 按预期正确工作。

细节

1. 真正的漏洞

commit 6133de 中,Jet 添加了一个文件 withdraw_tokens.rs,该文件定义了一个函数 handler

该函数做了两件事:

1. 从储备转移代币到用户的 withdraw_account

2. 从用户提供的 deposit_note_account 中销毁票据

函数 note_burn_contextdeposit_note_account 上创建一个 Burn 指令(第 80 行),并与 market_authority第 82 行)进行交互:

真正的漏洞在于 deposit_note_account 是一个 未验证的输入账户(第 54 行):

market_authority 是所有用户 deposit_account 的权限(代码):

因此,攻击者可以提供任何用户的 deposit_note_account 并成功销毁票据。

2. 该漏洞尚未(还没)可利用

然而,该漏洞尚不可利用,因为 withdraw_tokens.rs 中的 withdraw_tokens::handler 函数 不是攻击面用户不能直接 调用 它。

它只能通过 withdraw.rs 中的 handler 函数进行调用(第 74 行):

withdraw::handler 函数是一个攻击面(通过 Withdraw 指令):

然而,deposit_accountWithdraw 指令中是经过适当验证的:

在上述案例中,depositor 是签名者,deposit_account 是唯一属于存款人的账户(depositor.key 是 PDA 种子的一部分)。

deposit_account 作为 deposit_note_account 传递到 withdraw_tokens::handler

因此,攻击者无法利用此漏洞,因为 deposit_account 是经过验证的。

3. 漏洞何时变得可利用

commit 1f7da4 中,Jet 引入了 WithdrawTokens 指令,这使得 withdraw_tokens::handler 函数成为攻击面:

此后,该漏洞便变得可以直接利用。

4. 漏洞何时以及如何被修复

在 1 月 27 日,漏洞在 commit-f4bb3b 中得到了修复,通过将权限更改为 depositor第 82 行):

depositor 是签名者:

这确保了攻击者不能创建一个假 depositor 来成功调用 WithdrawTokens

实际上,唯一成功调用 withdraw_tokens::handler 的方式是通过 Withdraw 指令。withdraw::handler 函数创建一个 CPI 来调用 WithdrawTokens 指令(第 108 行):

CPI 传递 market_authority 作为存款人(第 89 行),这将作为 Burn 指令的权限:

5. Anchor 按我们预期的方式正常工作

最初,我们怀疑该漏洞可能是由于 Anchor 无意中生成的额外攻击面所引起的。例如,Anchor 生成的攻击面是否未在 #program 宏中定义,而是通过 instructions::* 导入或使用 super::* 请求:

然而,经过仔细检查,我们确认 Anchor 确实正常工作:它生成的代码仅包含在 #program 宏中定义的攻击面。

X-Ray 如何检测漏洞

X-Ray Auto Auditor 可以自动检测到该漏洞(即 deposit_note_account 是一个 未验证的输入账户)。以下是报告截图(第 54 行):

在提交 3178f93 中引入了未验证输入账户的漏洞。

Charlie 原推文 的启发,sec3 团队也为 SVE 数据库添加了一个新的漏洞签名:

  • SVE1032: IncorrectAuthorityAccount — PDA 操作可能被错误地用作共享权限,并可能允许任何账户转移或销毁代币。

该算法实际上很简单:(1)如果任何 PDA 账户(例如 market_authority)被用作转移/铸造/销毁代币的权限,并且(2)如果转移/铸造/销毁指令中的 from/to 账户与签名者账户无关(例如,PDA 种子)。

如果两个条件都为真,潜在的漏洞将被标记。

以下是 IncorrectAuthorityAccount 报告的截图:

总之,(1)sec3 的工具本可以检测到该漏洞,(2)sec3 从此事件中了解到一个新的漏洞签名,并将其添加到工具中。


sec3 审计

sec3(前身为 Soteria)由区块链安全和软件验证领域的领先思想家成立。

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

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

0 条评论

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