跨链桥:Web3黑客必争之地

news2024/10/2 16:17:36

跨链桥,区块链的基础设施之一,所实现的功能是允许用户将自己的资产从一条链转移至另外一条链上,是连接不同的区块链的关键桥梁,常使用中心化的方式进行实现。由于跨链桥自身往往存储有用户所质押的巨额资产,是Web3黑客最热衷于攻击的目标之一。近年来,与跨链桥相关的攻击与漏洞屡见不鲜,本文将详述Harmony跨链桥黑客攻击事件和Wormhole代理合约未初始化漏洞。

Harmony跨链桥黑客攻击事件

2022年6月23日,Harmony链与以太坊间的跨链桥上发生了恶意攻击,攻击者控制了跨链桥所有者的私钥后,直接使用管理员权限通过特权函数转移走了该桥所持有的大量各类代币,导致Harmony链上价值约9700万美元的资产被盗。

该跨链桥由一个多签钱包所控制,其本意是通过要求至少有N位管理员的授权才能执行操作,来提高钱包的安全性和攻击门槛,在实际代码实现中N=2。

多签钱包实现为一个合约MultiSigWallet.sol,其中能够处理资产转移的函数executeTransaction()本身带有confirmed(transactionId, msg.sender)校验,需要2位不同的owner依次调用submitTransactionconfirmTransaction两函数,才能通过操作权限校验,以多签钱包身份发起资产转移等任意操作。

多签钱包地址:

https://etherscan.io/address/0x715CdDa5e9Ad30A0cEd14940F9997EE611496De6

/// @dev Allows anyone to execute a confirmed transaction./// @param transactionId Transaction ID.function executeTransaction(uint256 transactionId)publicownerExists(msg.sender)confirmed(transactionId, msg.sender)notExecuted(transactionId){if (isConfirmed(transactionId)) {Transaction storage txn = transactions[transactionId];txn.executed = true;if (external_call(txn.destination,txn.value,txn.data.length,txn.data)) emit Execution(transactionId);else {emit ExecutionFailure(transactionId);txn.executed = false;}}}

https://etherscan.io/address/0x715CdDa5e9Ad30A0cEd14940F9997EE611496De6#code

MultiSigWallet.sol

于是,保证这些owner私钥的保密性是Harmony跨链桥的安全瓶颈之一。

从目前证据来看,攻击者可能通过其他链下攻击手段控制了多签钱包中的2个所有者私钥,成为了事实上的桥的所有者,通过这些权限校验都已经不在话下。攻击者可以正常地使用所有者权限进行资产的管理,包括将所有资产转移至攻击者账户中。

实际发生的资产转移交易https://etherscan.io/tokentxns?a=0x0d043128146654c7683fbf30ac98d7b2285ded00

小结

在由密码学为基础建构起的区块链世界中,没有什么比确保私钥自身的保密性更加重要的事情了,私钥泄漏是最无解、同时也是危害最大的安全隐患。跨链桥的开发者需要注意项目本身中心化的风险,确保项目所私用的私钥的安全性。同时,区块链的每一个使用者也都必须清楚地明白:道路千万条、私钥保密第一条。

Wormhole代理合约未初始化漏洞

2022年2月24日,匿名白帽子黑客satya0x负责任地披露了Wormhole主桥(以太坊侧)的一个代理合约未初始化漏洞,一举拿下Web3漏洞赏金平台immunefi有史以来单笔最高的漏洞赏金:一千万美元。看到这一数字的读者朋友们想必会不由得发问:究竟是如何逆天的漏洞才能够收割这笔天价赏金?

据长亭科技区块链安全研究员分析,该漏洞是Wormhole跨链项目以太坊侧代理合约未初始化而导致的漏洞,黑客可以通过提前控制代理合约背后的实际实现合约,并调用更新函数迫使实现合约自毁,使得Wormhole项目所有的以太币都被冻结在原地址中,用户已经转移至Wormhole的资产也将会被永久冻结、再也无法取出。

根据国家区块链漏洞库区块链漏洞定级细则中智能合约漏洞定级细则v1.0,该漏洞会使得智能合约核心业务无法正常运行,造成他人资产大额冻结,在危害程度上划分为
严重危害 ;同时利用成本较低,无特殊利用门槛,且漏洞可稳定触发,在利用难度上划分为 低难度 。综合这两个因素考虑,该漏洞定级为 高危
漏洞。

目前漏洞已修复,我们现在讨论一下本次wormhole漏洞的原理。

漏洞合约地址:

https://etherscan.io/address/0x736d2a394f7810c17b3c6fed017d5bc7d60c077d

什么是Wormhole

Wormhole跨链协议是连接solana和以太坊的桥,通过Wormhole,DeFi项目可以避开以太坊的拥堵和高费用,并享受Solana的低费用和高吞吐量、快速的交易体验。

——Solana Wormhole 项目主页

从Wormhole项目的介绍中我们可以知道,Wormhole是连接两条相互不兼容的公链:以太坊和Solana的一个协议,在以太坊和Solana上都部署有合约程序,在以太坊上运行的程序称为
以太坊智能合约 ,在Solana上运行的程序称为 Solana program
,两个分别运行于不同公链的程序需要共同发挥作用,完成用户的资产跨链请求。本次代理合约未初始化漏洞发生在Wormhole项目的以太坊智能合约中。

什么是以太坊智能合约

以太坊(Ethereum)是目前最广为人知的公链系统,其原生货币以太币是市值第二的加密货币。以太坊智能合约是运行于以太坊EVM(Ethereum
Virtual
Machine)之上的程序。以太坊智能合约的主要功能是实现各类资产管理的功能。初次接触智能合约一词的读者可以在概念上直接将智能合约理解为Java编写的程序,在Java虚拟机(类比EVM)内运行。

以太坊的一大特色是一个智能合约程序一旦部署上链后将再也无法对其代码逻辑进行修改,换句话说,一个运行中的以太坊智能合约的代码逻辑是不可更新的。

使用代理合约进行合约更新

以太坊的智能合约在部署后不可更改,使得开发者在发现安全漏洞后如何更新自己的智能合约代码成了一个问题。不过,也不是完全无法实现智能合约的代码更新,通过一个特殊的以太坊EVM调用:Delegatecall,一个以太坊程序可以间接实现智能合约代码的更新。

以太坊智能合约使用 代码与存储耦合
的编程模型,换句话说,一个合约的代码逻辑和合约的数据存储都是存放在同一个地址上的,一个合约只能够通过自己地址上存储的代码逻辑去修改自己地址上的数据存储。

但情况并不总是如此。以太坊智能合约在相互调用时除了最常用最普通的Call调用之外,还有一种特殊的调用方式:Delegatecall,实现了智能合约
代码 和智能合约 存储 的分离,也就是说,用别人的代码来修改自己的数据存储。

  • 合约间普通CALL,如下左图所示:A合约CALL调用了B合约,B合约的程序逻辑运行在B合约地址的数据存储中,所读取与修改的数据均为属于B地址的数据。

  • 合约间委托调用DELEGATECALL,如下右图所示:A合约委托调用DELEGATECALL调用了B合约,运行的程序代码仍为B的代码,但是与CALL根本性的不同是所有的代码都是运行在A的上下文中的,使用DELEGATECALL时B的代码修改的是调用者A的数据存储状态。

可以看到,使用Delegatecall可以运行B的合约代码而修改A的合约存储,利用这一特性能够自然地实现合约的升级。此时,合约A为代理合约(Proxy),合约B为实现合约(Implementation),每次合约调用,都由代理合约A将实际的调用参数使用Delegatecall传递给合约A的数据存储中所指定的实现合约B,由B的合约代码来修改合约A的数据存储。当实现合约B的代码发现了严重漏洞需要升级时,将合约A的数据存储中所指定的实现合约从B更改为新的B‘,这样就实现了合约的升级,原现的合约B虽然仍旧在链上保存着,但是实际上已经被废弃,代理合约不会再将调用转发到B合约上。而原本B运行所需要的数据本来就都存储在A中,可以无缝地被新合约B’继续继承使用。

以上就是实现智能合约代码升级的基本原理,目前以太坊社区有两种主流的通过代理合约实现智能合约升级的标准:Transparent Proxy Pattern
(TPP)和Universal Upgradeable Proxy Standard (UUPS)。

  • 透明代理模式(TPP)中代理合约A内会实现合约升级相关的逻辑,缺点是开销大、无法调用代理合约与实现合约中同名的函数。
  • 通用可升级代理标准 (UUPS) 中代理合约A被EIP-1822标准所统一,不实现任何逻辑,仅仅是将所有调用DELEGATECALL至目标合约,更新的逻辑也实现在目标合约中。

本文一开始所提到的Wormhole协议使用的是第二种 UUPS模式

UUPS代理合约模式

UUPS模式中代理合约A不实现任何逻辑,所有的合约都在实现合约B中由开发者自行实现,最主要的功能包括:合约初始化逻辑与合约更新逻辑。

contract Implementation {  // 实际合约 Baddress public upgrader;// 初始化逻辑:设置管理员账号function initialize() external onlyonce { upgrader = msg.sender;}// 更新逻辑function upgradeToAndCall(address newImplementation) external { authorizeUpgrade();                   // 鉴权setImplementation(newImplementation); // 设置新的实现合约的地址newImplementation.delegatecall('..'); // 调用新的实现合约的初始化函数}}

需要更新实际合约B时,由管理员预先部署好更新后的合约B‘,使用新合约B‘的地址作为参数调用upgradeToAndCall函数,该函数会将代理合约A中记录实现合约的存储从B修改为B’,随后便会使用delegatecall调用新合约B‘的初始化函数initialize完成初始化。在initialize中会更新A合约存储中的管理员账号。

UUPS模式使用时的风险

让我们一起来重点关注一下负责鉴权的upgrader变量在代理合约A和实现合约B中的作用:因为可更新的智能合约将原本在一个合约中完成的逻辑拆分到了两个合约中代理合约A和实际合约B,所以这两个合约都分别在自己的存储中维护了自己的upgrader存储变量。

当管理员通过调用upgradeToAndCall这一步骤完成更新之后,由于delegatecall的特性,代理合约A中的upgrader变量被顺利地更新了,但是实现合约B‘中的upgrader并没有被更新。虽然B’的存储在UUPS模式中不是实际的存储,但是B‘除了是代理合约A的实现合约之外,同时也是一个可以公开访问的普通合约。

实际上,在使用UUPS模式更新合约时,对于upgrader存储变量有两个分开的重要步骤:

1.将A的存储中的upgrader更新为msg.sender(upgradeToAndCall中已经实现)

2.将B’的存储中的upgrader更新为msg.sender(管理员需要的额外步骤)

管理员不仅需要通过调用原实现合约B中的upgradeToAndCall函数通过新实现合约B‘中的initialize函数更改A存储中的upgrader变量(第一步),同时也需要额外在外部独立调用一次initialize函数更改B’存储中的upgrader变量(第二步)。

在缺少第2步的情况下,相当于是代理合约A被正确的初始化了,用户无法通过代理合约A进行任何恶意的行为,但是B‘没有做任何的初始化,用户仍旧可以直接调用B’的初始化函数initialize,将B‘的存储中的upgrader更新为自己,通过控制B’的升级行为去调用自毁操作实现将B‘合约销毁的操作,使得A合约所指向的实现合约B’消失了,代理A合约所剩下的数据存储也将没有任何用处。

Wormhole的实际漏洞情况

Wormhole项目源码:https://github.com/certusone/wormhole

Wormhole负责更新与鉴权的具体逻辑与上文所描述的思路来说稍复杂。其负责实现UUPS标准upgradeToAndCall函数实际名称为submitContractUpgrade,并且鉴权时使用了parseVM等与自定义虚拟机相关的操作:

abstract contract Governance .. {function submitContractUpgrade(bytes memory _vm) public {Structs.VM memory vm = parseVM(_vm);...setGovernanceActionConsumed(vm.hash);upgradeImplementation(upgrade.newContract); // 设置新的实现合约的地址}}

wormhole/ethereum/contracts/Governance.sol

在实现合约中,initialize负责对管理员变量进行初始化:

contract Implementation is Governance {function initialize(..., bytes32 governanceContract) ... {...setGovernanceContract(governanceContract); // 设置upgrader}}

wormhole/ethereum/contracts/Implementation.sol

Wormhole在上一次调用submitContractUpgrade( )更新在区块高度13818843(2021年12月16日),之后实际合约B‘始终处于未初始化的状态。

攻击者可以未授权调用实际合约B’的初始化函数initialize( )获取B’合约管理员权限,随后凭借所获得的管理员权限恶意地调用更新函数submitContractUpgrade( ),该更新函数中的delegatecall允许执行攻击者指定的任意代码,其中危害最大的是执行selfdestruct让实际合约B’自毁,使得Wormhole项目中的资产被冻结。

Wormhole项目方在高度14269474(2022年2月24日)调用了初始化函数后修复了该问题。

使用UUPS代理模式时有需要特别注意的关键步骤,在没有完成必要的初始化的情况下,黑客能够通过初始化实现合约获取管理员权限,并恶意地并调用更新函数销毁实现合约,导致代理合约内的资产被永久锁定。

Side note.
你也想尝试独立发现这个千万美元悬赏的天价漏洞?以太坊安全练习平台Ethernaut提供了这一漏洞模式的练习环境,快来自己试试手吧!

总结

跨链桥因其自身的中心化特性而在去中心化的Web3世界中引入了中心化风险,其安全性很大程度上取决于跨链桥项目方自身。所以说,跨链桥的开发者,对跨链桥安全性起了决定性的作用。

最后

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

同时每个成长路线对应的板块都有配套的视频提供:


当然除了有配套的视频,同时也为大家整理了各种文档和书籍资料&工具,并且已经帮大家分好类了。

因篇幅有限,仅展示部分资料,有需要的小伙伴,可以【扫下方二维码】免费领取:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/369766.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

KUKA KR C4机器人与S7-1200PLC进行PROFINET通信的具体方法和步骤

KUKA KR C4机器人与S7-1200PLC进行PROFINET通信的具体方法和步骤 首先,从KUKA机器人控制柜中将KOP备选软件包拷贝出来,然后在“WorkVisual Development Environment”安装KUKA备选软件包(版本非常重要,尽量从控制柜中拷贝), 也可以从以下链接中获取: KUKA机器人PROFINET…

php 任务调度

在日常开发中,我们总会遇到一些在某个指定的时刻去执行,或是每隔xx时间执行,或是需要一直在后台监听的任务执行。基于这个需求,对于php我找了一些办法来实现这些功能 1、依赖于laravel的任务调度。 每隔xx时间执行一次命令&#…

七、虚拟机栈

虚拟机栈出现的背景 1.由于跨平台性的设计,Java的指令都是根据栈来设计的,不同平台CPU架构不同,所以不能设计为基于寄存器的。 2.优点是跨平台,指令集小,编译器容易实现,缺点是性能下降,实现同…

XC7K70T-1FBG676I【FPGA】XC3S200-4FTG256C参数XC7K70T-2FBG676C

Kintex-7 FPGA为快速增长应用和无线通信提供最优性价比和低功耗。Kintex-7 FPGA允许设计人员构建卓越带宽和12位数字可编程模拟,同时满足成本和功耗要求。Kintex-7内置支持8通道PCI Express (Gen1/Gen2),用于连接主机系统。7系列器件利用Xilinx统一架构保…

如何实现外网跨网远程控制内网计算机?快解析来解决

远程控制,是指管理人员在异地通过计算机网络异地拨号或双方都接入Internet等手段,连通需被控制的计算机,将被控计算机的桌面环境显示到自己的计算机上,通过本地计算机对远方计算机进行配置、软件安装程序、修改等工作。通俗来讲&a…

超图软件许可过期后的处理

超图软件许可过期,博主犯了一个很低级的错误,特此发帖记录一下。 按照官网的介绍,直接申请新的许可,配置本地许可很简单的。 1.打开桌面软件会弹出以下的框。 2.配置本地许可对话框 3.切换到激活更新页面 4.选择激活文件即可 以…

内容团队如何快速出稿

对于内容团队而言,每个内容选题就相当于一个小项目,它们并非简单的线性工作流,相反其复杂程度不亚于一个小型工厂。一个内容选题会涉及内容形式,选题类型等多个变量,这些变量因素组合起来就是十几种不同类型的工作流。…

我花6个月从0开始面上大厂自动化测试岗,拿个20K不过分吧?

我是着急忙慌的准备简历——3年软件测试经验,可独立测试大型产品项目,熟悉项目测试流程...薪资要求? 3年测试经验起码能要个20K吧?” 我一个朋友跟我说: “我加班肝了一页半简历,投出去一周,…

03--框架基础

1、目录结构1)创建项目使用测试号或小程序申请成功之后的appid即可,注意这里选择“不使用云服务”,选择javascript模板工具结构如图目录结构小程序包含一个描述整体程序的 app 和多个描述各自页面的 page。一个小程序主体部分由三个文件组成&…

python自学之《21天学通Python》(13)——第16章 数据库编程

数据库指的是以一定方式存储在一起、能为多个用户共享、具有尽可能小的冗余度、与应用程序彼此独立的数据集合。而我们平时所说的数据库实际上是包含了数据库管理系统(DBMS)的,数据库管理系统是为管理数据库而设计的软件系统,它一…

jvm调优参数配置

在JVM启动参数中,可以设置跟内存、垃圾回收相关的一些参数设置,默认情况不做任何设置JVM会工作的很好,但对一些配置很好的Server和具体的应用必须仔细调优才能获得最佳性能。通过设置我们希望达到一些目标: GC的时间足够的小 GC的…

Homekit智能家居DIY一WIFI智能插座

WiFi智能插座对于新手接触智能家居产品更加友好,不需要额外购买网关设备 很多智能小配件也给我们得生活带来极大的便捷,智能插座就是其中之一,比如外出忘记关空调,可以拿起手机远程关闭。 简单说就是:插座可以连接wi…

如何外网登录管理云通信短信网关平台?——快解析映射方案

云通信(Cloud Communications )是基于云计算商业模式应用的通信平台服务,简单易用,满足企业一键群发场景,支持多种语言SDK和API 接入。各个通信平台软件都集中在云端,且互通兼容,用户只要登录云通信平台,不…

【玩家心得】Smurf Society 游戏攻略

在深林的深处,生活着一群无忧无虑、快乐的小精灵,浑身蓝色,叫做蓝精灵。蓝精灵住在自己村子里蘑菇屋里,精灵爸爸、精灵妹妹、笨笨、乐乐等使得精灵村每天都欢声笑语。可是,在森林深处的城堡里住着一个邪恶的巫师格格巫…

量化择时——资金流择时策略(第1部分—因子测算)

文章目录资金流模型概述资金流模型的有效性逻辑资金流向指标MFI(Money Flow Index)MFI指标测算测算规则测算结论资金流模型概述 通常,资金流是一种反映股票供给信息的指标,宏观上来讲,我们知道一个道理:僧…

仅花半年时间,他从外包月薪5K到阿里月薪15K,究竟经历了什么?

背景介绍:“渣渣”二本,95年Java程序员**外包类型:**传统外包公司**内容简介:**朋友从一个传统公司是如何修仙到阿里巴巴?分享一些他的真实经历,希望对你有帮助。**学习路线:**基础(…

电阻串联的作用

电阻串联常见作用 第一个作用是:阻抗匹配: 因为信号源的阻抗很低,跟信号线之间阻抗不匹配,串上一个电阻后,可以改善匹配情况,以减少反射,避免振荡等。 常见的阻抗匹配方法 1、使用变压器来做…

(十)、kityminder支持富文本的编辑

前段时间,去试用了下processon 上的脑图功能,发现人家这块确实已经做的好强大了。而且他的节点竟然还可以支持单独某个文本的颜色字体的设置,这个可是连xmind,本身都没有实现的功能的。所以想着学习下人家的实现看看是否能够借鉴到…

会声会影2023电脑版下载及系统配置要求

平时大家可能会经常听到有人说会声会影,但是很多人都不知道这是什么软件。其实听它的名字就知道这是一款和声音、影像有关系的软件。下面,小编就来给大家具体介绍一下这款软件吧。 会声会影是一套操作简单的DV、HDV影片剪辑软件。会声会影不仅完全符合家…

Python并发编程-事件驱动模型

一、事件驱动模型介绍 1、传统的编程模式 例如:线性模式大致流程 开始--->代码块A--->代码块B--->代码块C--->代码块D--->......---&…