GCSA 洞察: 链上协议资金安全, 基于 21 亿笔历史交易重放的任意外部调用漏洞剖析

本文重放 21 亿笔历史交易,扫描出超过一百个存在相关风险的合约,涉及多个代码族。文章系统介绍检测方法、分析漏洞构成并交叉验证,最终给出防御建议。

前言

本报告由 GCSA Web3 Labs ZkSec 发布:任意外部调用漏洞——合约将调用目标与数据完全交给调用者填写——是链上授权资金面临的一类核心风险。本文基于归档节点数据,重放 21 亿笔历史交易,扫描出超过一百个存在相关风险的合约,涉及多个代码族。文章系统介绍检测方法(历史交易重放、调用参数溯源与变异验证),分析漏洞构成与以太坊/BSC 链间差异,并以已知攻击与扫描检出案例进行交叉验证,最终给出防御建议。

1.1 任意外部调用漏洞

存在任意外部调用漏洞的合约,提供一个公开入口:调用的目标地址和数据由任何提交者填写,合约以自己的身份执行。正常合约不是这样——要调用谁、传什么数据,写在代码里或限定在白名单内。

这种入口有时是刻意的设计取舍(批量工具、跨链桥为了通用故意开放),有时是设计缺陷(本想限制调用范围,却漏了校验)。无论是刻意开放还是校验遗漏,只要合约持有用户授权或滞留资金,缺少调用者限制的入口就可能被非预期调用者利用。

1.2 一个目标限制不足的案例

BSC 上的 MetaAggregatorSwapContract(0xc17b234fad8e40642662f1d2a6cbd1d609e7b9b5)存在目标限制不足的任意外部调用风险。它的功能是代用户执行兑换:接收代币,调用外部聚合器完成交易。

// 入口:任何人可调用,全部参数来自 calldata
function swapERC20(SwapERC20Params calldata params) external nonReentrant {
    (uint256 amountOut, uint256 fee) = _swapERC20(params);
    // …… emit TokenSwapped(……)
} function _swapERC20(SwapERC20Params memory params) internal returns (uint256, uint256) {
    address aggregator = params.aggregator;   // 任意地址
    bytes memory swapData = params.swapData;  // 任意字节
    // ……
    uint256 balanceBefore = tokenOut.balanceOf(address(this));
    _executeAggregatorCall(swapData, isDelegate, aggregator, 0);
    uint256 amountOut = tokenOut.balanceOf(address(this)) - balanceBefore;
    if (amountOut < minAmountOut) revert InsufficientTokenOutAmount();
    // ……
} function _executeAggregatorCall(
    bytes memory swapData,
    bool isDelegate,
    address aggregator,
    uint256 value
) internal {
    (bool success, bytes memory returnData) = isDelegate
        ? SWAP_TARGET.delegatecall(swapData)
        : aggregator.call{value: value}(swapData);   // CALL 或 DELEGATECALL 的目标和代码路径由参数影响
    // ……
}

aggregator和swapData都来自调用者,合约没有白名单校验。非 delegate 模式下,合约通过CALL调用aggregator;delegate 模式下,代码在SWAP_TARGET的上下文中执行。目标限制不足,可能扩大合约可调用的范围;合约名下还挂着用户为兑换授权的额度。

aggregator和swapData可控,但这本身不能推出任意token.transferFrom攻击。minAmountOut在源码中要求大于零;非 delegate 模式下,MetaAggregator 通过CALL调用aggregator,代币看到的调用者还要由实际调用链确定。因此,本案例只有在给出完整 trace、spender 和资金路径后,才能判定为授权转移漏洞。

要把该入口判定为授权转移漏洞,还需列出实际 spender、受害者授权和资金流;现有示例只支持滞留余额路径。两条路径应分开列出。

2.1 漏洞扫描系统设计

把历史交易一笔一笔重新执行,拿到完整的调用树——每一层调用、每个参数都有记录。然后在树里找可操控的点:内部调用的某个参数(转账给谁、转多少、调用哪个合约、带什么数据),如果能一路追溯到交易顶层 calldata 里的原始字节,只能说明这个参数可能受外部提交者影响,还要通过变异重放确认。把这些点逐个替换后重放,验证参数是否确实可控,以及操控能否传导成真实的资金流动。

2.2 扫描执行流程

一笔交易在代码里的完整执行流程见图 1。

DpRG4KOZWXajCWR0T2lLtK0TsxapIdmALnUKFpEe.jpeg

2.3 调用参数溯源

扫描器先检查内层参数是否能在顶层 calldata 中找到原始字节。找到时,只能说明该参数在当前编码路径上可由提交者影响,仍需通过变异重放确认。

扫描器做字节级匹配:参数的 32 字节直接出现在顶层对齐位置,或整段调用 calldata 作为连续字节串嵌在顶层,即登记为可由外部参数改变的内部参数并记下偏移;匹配不到时标记为“无法建立参数来源”,不据此断定该值由合约内部算出。变异时改顶层偏移,重放验证内层是否跟随。

当前实现不做语义分析,只做 EVM 层的字节匹配,因此开源和闭源合约都能处理。已知缺口是:合约在内存里重组 calldata 时,参数来源可能无法继续追踪。

2.4 实现

整套系统只有一个核心设计:每笔历史交易,都在它发生前一瞬的世界状态上执行两遍(图 2)。

O7dAij1HMtxE9ajIlhBwqAugn8sQP196gE4gL1HX.jpeg

一笔交易的执行结果,取决于它之前所有交易留下的状态——区块里第 5 笔交易看到的余额,是前 4 笔执行完的余额。重放第 5 笔之前,先把前 4 笔逐笔执行到一个临时状态层(PreState)里,停在第 5 笔开始前。

然后在这份状态上,把这笔交易跑两遍。第一遍原样执行,记录完整过程:调用了哪些合约、转了哪些钱、改了哪些存储。第二遍换掉可操控的参数——发起人、收款人、金额——再执行,看结果有什么不同。两遍都不改这份状态,所以换不同参数可以反复试。

试完之后,把第一遍的结果写进状态层,继续处理下一笔交易。这样区块里的每一笔,都在它当年看到的那个世界上执行。

2.5 排除误报

重放产出的待审核记录以万计,人工逐条看完不可能,绝大多数在复核之前就被流水线筛掉了。图 1 的每个 ✕ 标记一类被筛除的原因,这里展开其中几种。

地址投毒批次钓鱼者用假币、零值或极小额转账污染地址记录。扫描器会看到多个受害者、官方代币名称和极小额转账等相似形态,因此需要结合代币代码、金额和调用批次排除。

// 批量转账入口(同一代码族的两个 selector)
transfer(address[] from, address[] to, address token, uint256[] amount)   // 0xe19c2253
transfer_7211834412884((uint8,address,address,address,uint256)[])          // 0x12514bba
// 受害者列表直接写在 calldata 里,一笔交易打几十个地址

实例:0x184aaf087ca6dd17eb1200dbfbee9f671bd906fc。该家族在同轮扫描中产生数百条记录,包含几十个 helper,未发现官方稳定币的非零余额。

仿冒币名假币攻击的升级——代币名字里混进西里尔字母或零宽字符,肉眼看是 USDT,字节上不是。一律标记。

USDT → 55 53 44 54          (ASCII)
USDТ → 55 53 44 d0a2        (末位是西里尔字母 Т,U+0422)

实例:0x9257cf49…f4253、0x6b1b80b4…1ca6cc,同一批地址投毒记录中转出的仿冒 USDT/USDC。

EIP-7702 重放限制在这组 type-4 重放中,原交易由原发起人携带authorizationList执行;换成测试地址并去掉该列表后,交易回滚。这个结果只说明该重放依赖原授权状态,不能推广为所有 EIP-7702 交易都必须携带authorizationList。扫描器保留这类记录,再用 caller_only 和 dual 两种变体区分真实可执行路径与重放条件导致的回滚。

原始交易   type-4,携带 authorizationList(账户本人签名)→ 执行成功换人重放   同一 calldata,发起人换成测试地址,无授权列表 → 整笔 revert

使用相同字节码的账户组多个地址运行同一段字节码、使用同一个发起人和归集地址,待审记录来自一组同特征账户。

// 一组账户的共同特征:字节码全部指向同一个委托目标
0xef0100 + 631af7731569e10b22a0430051cfd5c8930a1656   // 多个账户共用发起人相同 · 归集地址相同

实例:0x001100bd…3ff16、0x043d01a9…669d,两个成员的字节码完全相同。

3.1 判定条件

扫描器筛出的漏洞记录按图 3 依次判定。条件一、二用于确认参数可控性和模拟执行是否成功;条件三只区分资金来源:付款方是授权者时标为授权滥用,资金来自公开流动性时标为公开套利。两类记录的后续复核不同,不能直接等同于真实漏洞。
vWojzh1OCKejPEII83FIMCiAt08PHPaIx4uqVB5g.jpeg

3.2 AI 审核

扫描器产出的待审核记录由 AI 自动复核(图 4)。AI 读取原始交易的调用和资金流,分别做换发起人和换收款人重放。模拟成功只证明替换参数后交易可执行;资金来源、授权关系或调用链证据不足时,记录标为“证据不足,待人工复核”,不自动判为漏洞。
YupNxNqT3jEQMWVStXMpaQz7hU7VaFrQKdaCBJ23.jpeg

AI 复核结果回写到面板(图 5)。图 5 展示单条记录的五阶段证据链、标签、备注和模拟编号;它不展示全局标签计数。
3z24TFlgqaewKpj7GRjW67ejK4oR7GVzw3bs2gFK.jpeg

4.1 已知攻击交易检测

Seneca Protocol Chamber 用于验证扫描器检出的漏洞:该事件有公开分析,相关调用模式也出现在扫描结果中。

Seneca Protocol 于 2024 年 2 月 28 日遭到攻击,损失达数百万美元。BlockSec、SlowMist 和 Rekt 分别分析了这起事件。受影响合约地址为0x65c210c5…91f06,其Chamber.sol源码已在 Etherscan 验证。图 6、图 7 对应的 PT-weETH 重放交易为0x6da8f7cb…e820d,调用目标为 clone0xbc83f271…7c05。0x23fcf9d4…01286是另一笔 PT-rsETH 交易,不与图混用。

漏洞代码如下,省略无关部分:

// 入口:任何人可调用,三个数组参数全部来自 calldata
function performOperations(
    uint8[] calldata actions,
    uint256[] calldata values,
    bytes[] calldata datas
) whenNotPaused external payable returns (uint256 value1, uint256 value2) {
    // ……
    } else if (action == Constants.OPERATION_CALL) {
        (bytes memory returnData, uint8 returnValues)
            = _call(values[i], datas[i], value1, value2);
    // ……
} function _call(uint256 value, bytes memory data, ...) internal returns (bytes memory, uint8) {
    // 调用者提供目标地址和 calldata,合约解码后直接使用
    (address callee, bytes memory callData, ...) = abi.decode(data, (address, bytes, ...));     // callee 只经过黑名单检查
    require(!blacklisted[callee], "Chamber: can't call");     // 通过 callee.call 执行外部调用;代币看到的调用者取决于当前调用帧
    (bool success, bytes memory returnData) = callee.call{value: value}(callData);
    require(success, "Chamber: call failed");
    return (returnData, returnValues);
}


这与第 1.2 节的 MetaAggregatorSwapContract 属于同一类外部调用风险:调用者把callee和callData编入顶层calldata,Chamber 解码后直接使用。在该历史状态中,Chamber 名下保留着用户为管理仓位授予的 ERC-20 授权,因此需要进一步核对实际 spender、受害者授权对象和资金路径,才能判定为授权转移漏洞。

扫描器重放这笔交易,用call_tracer记录完整调用树。在 Chamber 的内部调用帧中,它定位到callee.call(callData),并确认callee和callData都能追溯到顶层datas参数。系统将它们登记为可操控点,再把顶层calldata中对应的收款人地址替换为测试地址,在同一历史状态上重放。交易执行成功,测试地址收到 PT-weETH;资金来源和调用链证据另行记录。

图 6 展示这笔 PT-weETH 重放交易的 Invocation Flow Diff,图 7 展示对应的 Fund Flow Diff;两图共同呈现替换收款人前后的调用和资金差异。
BSipF3PvcOkYxfhVSTy0xIeaUnjybOOkRlvKbnKJ.jpeg

DfOGh6nlV2JfnAw3rRQgXToDKLG8VgWTRJgbl9zA.jpeg
thirdweb Pay UniversalGatewayV1(2025 年,以太坊)——公开事件交叉验证

thirdweb 的支付网关0x81d57dd01a15bc1c19563693902df621500d4d2a也出现在扫描结果中。thirdweb 的公开报告确认该旧合约存在授权余额风险并已停用。

该历史实现没有可直接核对的验证源码。签名绑定、假代币地址和callData的具体关系,需要与对应区块的代理实现和交易 trace 对齐;当前参考源码不能替代历史实现作为结论依据。

该案例的历史调用包含代币地址、转发数据和授权余额之间的组合关系。当前材料不足以把“假代币地址绕过扣款”确定为该历史实现的根因;在补充对应区块的实现代码和完整 trace 前,不将其作为已确认机制。

5.1 扫描器检出的风险路径

以下案例的证据类型不同:部分来自历史交易重放,部分还有源码、审计或事故报告支持。每节只对已列出的证据作判断,并区分扫描结果和外部资料。

案例状态以所引交易的区块状态或明确的查询时间为准;余额、授权和合约是否仍可调用,不从历史交易直接推导当前状态。

一、Maker Multicall2:没有调用者白名单的批量执行器

0x5ba1e12693dc8f9c48aad8770482f4739beed696

// 官方合约,2021 年部署,源码公开
function aggregate(Call[] memory calls)
    public returns (uint256 blockNumber, bytes[] memory returnData)
{
    blockNumber = block.number;
    returnData = new bytes[](calls.length);
    for (uint256 i = 0; i < calls.length; i++) {
        (bool success, bytes memory ret)
            = calls[i].target.call(calls[i].callData);   // 没有调用者白名单
        require(success, "Multicall aggregate: call failed");
        returnData[i] = ret;
    }
}

target和callData全部来自调用者,合约没有调用者白名单校验,但仍检查底层调用是否成功。它是通用批量执行器,风险取决于用户是否把代币授权给了这个执行器;本文样本中的授权和资金路径应按具体交易逐笔核对。

二、THORSwap TSAggregatorGeneric:目标限制不完整

0x0ccd5dd5bcf1af77dc358d1e2f06ee880ef63c3c

function swapIn(
    address router, address vault, string calldata memo,
    address token, uint amount,
    address swapRouter,          // 调用目标由参数提供
    bytes calldata data,         // 调用数据由参数提供
    uint deadline
) public nonReentrant {
    // 只禁止调用 TTP(THOR 的代币代理)
    require(swapRouter != address(tokenTransferProxy), "no calling ttp");
    tokenTransferProxy.transferTokens(token, msg.sender, address(this), amount);
    token.safeApprove(address(swapRouter), amount);     (bool success,) = swapRouter.call(data);   // 其他目标仍可调用
    require(success, "failed to swap");
    // ……
}

当前源码只排除了 TTP,没有把swapRouter限制到白名单,因此代币合约仍可作为目标。历史状态重放显示,调用者可以把swapRouter和data指向代币转账路径;是否构成授权滥用,还需同时核对 spender、授权人和资金来源。

三、Symbiosis MetaRouter:跨链路由的任意 calldata

0xf621fb08bbe51af70e7e0f4ea63496894166ff7f

metaRoute从网关提取用户授权的代币,并检查relayRecipient不是网关且目标地址有代码。随后,源码直接使用调用者提供的otherSideCalldata调用relayRecipient;这里没有按函数选择器建立白名单。

otherSideCalldata的字节内容没有按函数选择器做白名单校验,目标地址只受网关地址和代码存在性检查约束。扫描器检出的交易中,该参数包含USDT.transferFrom;如要认定为授权滥用,还需把交易中的 spender、授权人和资金接收方逐项列出。

四、LayerZero LZMultiCall:授权错位与无签名执行入口

0x5528cf58feb8fbfce94f43b33240fffb1312bde3

// 合约同时提供带签名和不带签名的两个 execute 重载
function execute(
    Call[] calldata _calls,
    bytes32 _quoteId
) public payable virtual {
    uint256 nonce = nonces[msg.sender]++;
    _executeCalls(_calls, msg.sender);
    emit Executed(msg.sender, _quoteId, nonce);
} function _executeCalls(Call[] calldata _calls, address signer) internal {
    for (uint256 i = 0; i < _calls.length; ++i) {
        if (_calls[i].target == address(TRANSFER_DELEGATE)) {
            _handleTransfer(_calls[i].data, signer);
        } else {
            _handleCall(_calls[i].target, _calls[i].data, _calls[i].value);
        }
    }
}

原始复核交易走的是两参数的无签名入口,不是带_signature的重载。该入口把msg.sender作为 signer;只有目标是 TransferDelegate 时,才检查 transfer 的from是否等于 signer。若调用列表直接把代币合约作为 target 并放入token.transferFrom(受害者, 自己, 金额),代码会走通用的_handleCall,由 LZMultiCall 作为 spender 发起转账。

LayerZero 的正常流程应把授权交给 TransferDelegate;如果用户把授权直接给了 LZMultiCall,公开的无签名execute就可能消耗这份额度。这里的风险来自授权对象与通用转发路径的错位,不涉及带签名入口。

五、thirdweb Pay UniversalGatewayV1:证据范围

0x81d57dd01a15bc1c19563693902df621500d4d2a

该案例已在 4.1 作为公开事件交叉验证。公开报告确认旧合约存在授权余额风险并已停用;历史实现的签名绑定、代币地址和callData的具体关系,需要与对应区块的代理实现和交易 trace 对齐。本文不使用当前UniversalBridgeV1参考源码替代历史实现下定论。

六、BSC BnbSettler:BASIC 任意调用消耗误授权

0x4c6f446dd88fd1be8b80d2940806002777dc12a2

这是 0x Protocol Settler 的 BSC 部署。风险入口由公开的execute和BASICaction 组成,转账路径通过 action 进入代币合约:

// 示意代码,省略 action dispatch 与结算,不能替代完整源码
function execute(
    AllowedSlippage calldata slippage,
    bytes[] calldata actions,
    bytes32
) public payable takerSubmitted returns (bool) {
    // actions 由调用者提供,BASIC 在这里分派
    // takerSubmitted 只记录 payer,不做调用者认证
} function basicSellToPool(
    IERC20 sellToken, uint256 bps, address pool,
    uint256 offset, bytes memory data
) internal {
    if (_isRestrictedTarget(pool)) revert ConfusedDeputy(); // 只限制 Permit2
    (bool success, bytes memory returnData) = payable(pool).call(data);
    if (!success) {
        assembly { revert(add(returnData, 32), mload(returnData)) }
    }
    if (returnData.length == 0 && pool.code.length == 0) revert InvalidTarget(); // 目标和 calldata 可控
}

用户若直接把 ERC-20 授权给 Settler,调用者就可以把pool填成代币合约,把data编成token.transferFrom(受害者, 自己, 金额)。Settler 以自身身份发起调用,代币会按这份授权执行。历史重放还显示该合约存在可改变收款人的滞留余额;这两条路径应分开计。


表中按主要利用前提归类;“扫描检出的漏洞”“历史重放确认”和“公开事件交叉验证”不是同一个证据等级:

形态案例链特征
设计取舍Multicall2ETH官方合约,无恶意代码,用户误授权
补丁不完整THORSwapETH只禁 TTP,其他外部调用目标仍开放
跨链任意指令SymbiosisETHcalldata 内容缺少语义白名单,目标有代码存在性检查
授权错位与无签名转发LayerZeroETH误授权给外壳,可绕过 TransferDelegate 的 from 校验
历史授权余额风险thirdwebETH公开报告确认旧合约已停用,具体历史调用路径待实现和 trace 对齐
BASIC 任意调用BnbSettlerBSC直接 approve 本体后,BASIC 可调用代币 transferFrom

这些案例的证据类型不同:部分有历史交易重放,部分只有源码或公开报告。扫描器能直接验证的是:在对应历史状态下,改变顶层可控参数是否仍能把资金导向测试地址;其余结论需要单独标注来源和证据范围。

5.2 漏洞记录汇总

扫描器在以太坊和 BSC 上汇总了超过四百条漏洞记录,涉及三百多个地址。同一地址可能对应多条检测记录,地址中也包括 EIP-7702 委托账户。

以太坊的记录主要集中在 Maker Multicall2;BSC 的记录分布在更多地址,单个地址对应的记录较少。其他记录还涉及 CallDataExecutor、UniswapInterfaceMulticall、SquidMulticall 和 0x Settler 等合约。完整地址清单见附录 A、B。

链合约或账户说明
以太坊0x5ba1e126…ed696Maker Multicall2(第 5.1 节案例一)
以太坊0xbc83f271…7c05Seneca Chamber(第 4.1 节案例)
以太坊0x5724b5bc…81a1Swap0x 转发器
以太坊0x65c210c5…91f06Seneca Chamber(另一实例)
以太坊0xd791fcf4…d001废弃合约
以太坊0x0ccd5dd5…3c3cTHORSwap(第 5.1 节案例二)
以太坊0x81d57dd0…4d2athirdweb Pay(第 4.1 节案例)
以太坊0x5528cf58…bde3LayerZero LZMultiCall(第 5.1 节案例四)
以太坊0xf621fb08…ff7fSymbiosis MetaRouter(第 5.1 节案例三)
BSC0xc17b234f…b9b5swapERC20(第 1.2 节案例)
BSC0x62ccef0b…27dcsmartSwapByOrderId
BSC0xca11daf5…4ca11—

5.3 Lynx:交易分析与模拟平台

Lynx 是我们自研的交易分析与模拟平台,支持以太坊和 BSC,接口与标准 JSON-RPC 兼容。本文的重放验证和资金流对比通过 Lynx 完成。平台支持基于归档节点历史状态的eth_call模拟,可替换发起人、修改 calldata 或覆盖账户余额。

Lynx 通过debug_traceCall及相应的 tracer 获取调用树,记录调用目标、calldata 和返回值,供扫描器追踪参数来源;界面同时展示存储变化。平台还分别生成原始交易和模拟交易的资金流图,对比资产的来源、去向和金额。第 4.1 节图 6、图 7 分别展示调用流程和资金流的差异,图 8 展示调用树界面。

每次模拟结果按唯一编号保存,可按编号复查。

结语

本文在 21 亿笔历史交易中扫描出超过一百个漏洞合约,涉及基础设施、跨链路由器、支付网关和工具合约等形态。其中一部分漏洞经历史状态重放确认;Seneca 和 thirdweb 提供了独立的公开事件作为交叉验证。

在已复现的案例中,授权额度在余额变化后仍可能存在,因此监控授权存量可以补充余额事件监控。这个结论不外推到所有案例。

防御建议:

用户:用完就撤销授权,或改用支持过期签名的授权方案(如 Permit2)。授权前确认 spender 对应的是协议预期的执行入口;如果协议通过代理或 Permit2 转发,还要核对实际 spender、目标合约和额度。

协议开发者:任意外部调用入口应限制目标和 selector/data;签名转发入口应把签名内容绑定到调用者和接收者。打补丁时审计所有调用路径;THORSwap 的历史补丁只排除了一个目标,其他目标仍需检查。

行业:可将授权存量纳入持续监控,记录 spender、授权人、区块状态和余额变化。本文展示的是历史重放;持续追踪不在本文范围。(GCSA Web3 Labs ZkSec)


附录 A:以太坊漏洞记录对应地址

地址名称/说明
0x5ba1e12693dc8f9c48aad8770482f4739beed696Maker Multicall2
0xbc83f2711d0749d7454e4a9d53d8594df0377c05Seneca Chamber (clone 1)
0x5724b5bc7f54a52f4014e5f496ae380f89c881a1Swap0x
0x65c210c59b43eb68112b7a4f75c8393c36491f06Seneca Chamber (clone 2)
0xd791fcf4ef5f2998e92cdc6928bb0807760cd001废弃合约
0x0ccd5dd5bcf1af77dc358d1e2f06ee880ef63c3cTHORSwap TSAggregator
0xb345bb198d4f789a204f53beb954be3bb7108eaeCallDataExecutor
0x2dc4f436abfc8307feadc8bd65b22f554527a57e未验证合约
0xac1ce734566f390a94b00eb9bf561c2625bf44eaUniswapInterfaceMulticall
0x4fd39c9e151e50580779bd04b1f7ecc310079fd3SquidMulticall
0x207e1074858a7e78f17002075739ed2745dbaece0x MainnetSettler
0xf621fb08bbe51af70e7e0f4ea63496894166ff7fSymbiosis MetaRouter
0x81d57dd01a15bc1c19563693902df621500d4d2athirdweb Pay Gateway
0x828191074740e479c86c0625542f4ba7bfd7a5c2EIP-7702 账户
0x5528cf58feb8fbfce94f43b33240fffb1312bde3LayerZero LZMultiCall
0x94f9958c03e8705338cdbe81b61e8f6b94dbcc54—
0x26dfd3bc0b4f2bc9c1cd108cf3e4b8da875be6f2未验证合约
0x4d5ceb42199c7f86d0fc0e2bc4367b63c78af674未验证合约
0x529ebb6d157dfe5ae2aa7199a6f9e0e9830e6dc1—
0xb358e03c01aa71302ea1c473745d2e74d3f171d9假 uniswapV3SwapCallback
0xa7be5627aff05e464f0f996111c21bbd5535c509—

附录 B:BSC 漏洞记录对应地址(部分)

地址入口 selector
0xc17b234fad8e40642662f1d2a6cbd1d609e7b9b50x8b20aa49
0x62ccef0b4545166f721caa9fee13c1d3767e27dc0x0c307f76
0xca11daf554079783545f5044c1e6ac8d29f4ca110x511abb0d
0xe4f42786d1bc06e4fa1018ee6ec9802ad4f4d9bc0x174dea71
0x5f842beff5203297fb07ab88e1803c7aa51f5af50x174dea71
0xe7bb57763020d3fadbd915fb14b723f1811f6ef00x174dea71
0x0000000036377a76df1ce37e98ebd5f1fff38ec30x174dea71
0x64f086118f424e310162a7c19a597b874e5335440x174dea71
0xa8bc4415855e9986d5a99a1a49f3275c3dfe3c8a0x174dea71
0xd07a07b6330035d546d52eda42a9dd8d24521aaa0x174dea71
0xdeade69dbb08114d684c6f38f6de6ce85d18dead0x174dea71
0xd95f9b7d5876523c44952f9bda788d80ec6e977c0x174dea71
0x56112d83ba59d79f09cd2ae25a24c343438955ec0x174dea71
0xc30eb7a80db96c69715e4f1a3640f4155ea480e00x174dea71
0x19bedf5c4c99d8499542fb432f6c0dba69cc790c0x174dea71
0xde62ccbb439d6288e1ea1af3525a6e9b945f2cdd0x174dea71
0x8393f7105b4ef216d2adc9fd50a25f19a9e582dd0x235b5278

完整附录见:https://web3labs.gcsa.com/blog/historical-transaction-replay-vulnerability-scanning

版权声明:本报告及相关技术分析由GCSA全球网络安全联盟独家发布。如需转载请完整保留GCSA官方出处及原始链接,并不得对报告核心观点进行恶意篡改。

来源:media.gcsa.com/news-3730122

GCSA推特:x.com/GCSAHK

GCSATelegram频道:t.me/GCSAofficial

来源:GCSA全球网络安全联盟
官网:www.gcsa.org