文章详细讨论了Jet Protocol中的一个潜在漏洞,该漏洞若被利用可能导致2000万美元的用户资金损失。文章分析了漏洞的起因、如何变得可利用以及最后是如何修复的,并强调了sec3的X-Ray自动审计工具在自动识别此类漏洞中的作用。
最近,Charlie You 公开了 Jet Protocol 中的一个漏洞(查看推文)。如果这个漏洞被利用,将导致 Jet 用户损失 2000 万美元的资金。幸运的是,Jet 在任何用户受到影响之前进行了修复。
sec3 团队在 Jet-v1 的代码中发现了一些棘手的问题,并在披露后不久与 Charlie 进行了讨论。事实证明,这个漏洞的原因与 Charlie 预期的不同。以下是总结:
在 commit 6133de 中,Jet 添加了一个文件 withdraw_tokens.rs,该文件定义了一个函数 handler:
该函数做了两件事:
1. 从储备转移代币到用户的 withdraw_account
2. 从用户提供的 deposit_note_account 中销毁票据
函数 note_burn_context 在 deposit_note_account 上创建一个 Burn 指令(第 80 行),并与 market_authority(第 82 行)进行交互:
真正的漏洞在于 deposit_note_account 是一个 未验证的输入账户(第 54 行):
market_authority 是所有用户 deposit_account 的权限(代码):
因此,攻击者可以提供任何用户的 deposit_note_account 并成功销毁票据。
然而,该漏洞尚不可利用,因为 withdraw_tokens.rs 中的 withdraw_tokens::handler 函数 不是攻击面:用户不能直接 调用 它。
它只能通过 withdraw.rs 中的 handler 函数进行调用(第 74 行):
withdraw::handler 函数是一个攻击面(通过 Withdraw 指令):
然而,deposit_account 在 Withdraw 指令中是经过适当验证的:
在上述案例中,depositor 是签名者,deposit_account 是唯一属于存款人的账户(depositor.key 是 PDA 种子的一部分)。
deposit_account 作为 deposit_note_account 传递到 withdraw_tokens::handler。
因此,攻击者无法利用此漏洞,因为 deposit_account 是经过验证的。
在 commit 1f7da4 中,Jet 引入了 WithdrawTokens 指令,这使得 withdraw_tokens::handler 函数成为攻击面:
此后,该漏洞便变得可以直接利用。
在 1 月 27 日,漏洞在 commit-f4bb3b 中得到了修复,通过将权限更改为 depositor(第 82 行):
depositor 是签名者:
这确保了攻击者不能创建一个假 depositor 来成功调用 WithdrawTokens。
实际上,唯一成功调用 withdraw_tokens::handler 的方式是通过 Withdraw 指令。withdraw::handler 函数创建一个 CPI 来调用 WithdrawTokens 指令(第 108 行):
CPI 传递 market_authority 作为存款人(第 89 行),这将作为 Burn 指令的权限:
最初,我们怀疑该漏洞可能是由于 Anchor 无意中生成的额外攻击面所引起的。例如,Anchor 生成的攻击面是否未在 #program 宏中定义,而是通过 instructions::* 导入或使用 super::* 请求:
然而,经过仔细检查,我们确认 Anchor 确实正常工作:它生成的代码仅包含在 #program 宏中定义的攻击面。
X-Ray Auto Auditor 可以自动检测到该漏洞(即 deposit_note_account 是一个 未验证的输入账户)。以下是报告截图(第 54 行):
在提交 3178f93 中引入了未验证输入账户的漏洞。
受 Charlie 原推文 的启发,sec3 团队也为 SVE 数据库添加了一个新的漏洞签名:
该算法实际上很简单:(1)如果任何 PDA 账户(例如 market_authority)被用作转移/铸造/销毁代币的权限,并且(2)如果转移/铸造/销毁指令中的 from/to 账户与签名者账户无关(例如,PDA 种子)。
如果两个条件都为真,潜在的漏洞将被标记。
以下是 IncorrectAuthorityAccount 报告的截图:
总之,(1)sec3 的工具本可以检测到该漏洞,(2)sec3 从此事件中了解到一个新的漏洞签名,并将其添加到工具中。
sec3(前身为 Soteria)由区块链安全和软件验证领域的领先思想家成立。
我们很高兴为高影响力的 Dapps 提供全面的审计服务,尤其是在 Solana 上。请访问 sec3.dev 或发送邮件至 contact@sec3.dev
- 原文链接: sec3.dev/blog/on-a-20m-b...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!