Poly Network攻击事后分析

  • Dedaub
  • 发布于 2023-02-08 23:59
  • 阅读 13

Poly Network 在2023年7月2日遭受攻击,攻击的根本原因可能并非智能合约的逻辑漏洞,而是Poly Network的4个keeper中3个的私钥被盗或滥用。

NEVILLE GRECH

Poly Network 黑客攻击事后分析

UTC 时间 2023 年 7 月 2 日下午 6:47:20,Poly Network 遭受了一次最初报告为名义上的 340 亿美元的黑客攻击(由于大多数代币缺乏流动性,实际实现的金额要少得多)。Poly 团队暂停了其智能合约 EthCrossChainManager 在多个链上,最值得注意的是 Metis、BSC 和 Ethereum。在我们的团队重建了攻击之后,我们得出结论,根本原因不是智能合约上的逻辑错误,而是 Poly network 的 4 个 keeper(由团队控制的链下系统)中的 3 个 keeper 的私钥被盗(或被滥用)。为了理解攻击是如何发生的,我们需要理解 Poly 的跨链管理器的架构。

Poly 运行着一个跨链管理合约网络,允许代币从源链“转移”到目标链。这些合约接受源链上代币转账变更的证明,以及用于在当前链上提取这些代币的交易的编码参数。

function verifyHeaderAndExecuteTx(bytes memory proof, bytes memory rawHeader, bytes memory headerProof, bytes memory curRawHeader,bytes memory headerSig) whenNotPaused public returns (bool)
// proof = Poly 链交易 Merkle 证明
// rawHeader = 包含 crossStateRoot 以验证上述交易 Merkle 证明的头部
// headerSig = 从 Poly 链 keeper 导出的用于 solidity 的转换后的签名变量

允许用户在源链上“锁定”的“目标”链上“解锁”代币的主要入口点

在 Poly 中,从源链转移代币的操作被称为“锁定”,而检索代币的函数被称为“解锁”。Poly 采用所谓的“共识节点”系统,这些节点本质上是 EOA,通过包含来自源链的相关熵来确认目标链上的“解锁”事件,从而进行签名,确认锁定事件。此熵包含反映源链上锁定代币的状态根。以下是检查“header”结构是否由“共识节点”正确签名的相关代码。“header”包含 Merkle 树的状态根。由于整个“header”都已签名,因此状态根已签名,并且通过扩展,整个状态也由 Merkle 树见证。

function verifySig(bytes memory _rawHeader, bytes memory _sigList, address[] memory _keepers, uint _m) internal pure returns (bool){
        // (Dedaub comment)
        //_rawHeader = 0x0000000000000000000000001e8bb7336ce3a75ea668e10854c6b6c9530dab7...
        //_sigList = // List of 3 signatures from 0x3dFcCB7b8A6972CDE3B695d3C0c032514B0f3825,0x4c46e1f946362547546677Bfa719598385ce56f2,0x51b7529137D34002c4ebd81A2244F0ee7e95B2C0
        //_keepers = ["0x3dFcCB7b8A6972CDE3B695d3C0c032514B0f3825","0x4c46e1f946362547546677Bfa719598385ce56f2","0xF81F676832F6dFEC4A5d0671BD27156425fCEF98","0x51b7529137D34002c4ebd81A2244F0ee7e95B2C0"]
        //_m = 3

        bytes32 hash = getHeaderHash(_rawHeader);

        uint sigCount = _sigList.length.div(POLYCHAIN_SIGNATURE_LEN);
        address[] memory signers = new address[](sigCount);

        // (Dedaub comment)
        //   signers = [\
        //     0x4c46e1f946362547546677Bfa719598385ce56f2,\
        //     0x3dFcCB7b8A6972CDE3B695d3C0c032514B0f3825,\
        //     0x51b7529137D34002c4ebd81A2244F0ee7e95B2C0\
        // ]
        bytes32 r;
        bytes32 s;
        uint8 v;
        for(uint j = 0; j  < sigCount; j++){
            r = Utils.bytesToBytes32(Utils.slice(_sigList, j*POLYCHAIN_SIGNATURE_LEN, 32));
            s =  Utils.bytesToBytes32(Utils.slice(_sigList, j*POLYCHAIN_SIGNATURE_LEN + 32, 32));
            v =  uint8(_sigList[j*POLYCHAIN_SIGNATURE_LEN + 64]) + 27;
            signers[j] =  ecrecover(sha256(abi.encodePacked(hash)), v, r, s);
            if (signers[j] == address(0)) return false;
        }
        return Utils.containMAddresses(_keepers, signers, _m);
    }

验证已签名 header 的函数,其中包含非常重要的状态根。Dedaub 添加的评论。

我们的团队验证了上面的代码被正确调用,并且 header 确实由 3 个中心化的 keeper 签名,满足(k-1)/ k keeper 签名方案。我们还检查了 keeper 列表在攻击之前是否被修改。事实上,在 2 年多的时间里,keeper 列表保持不变,并且由 4 个 EOA 组成。去中心化协议通常采用“keeper”,即由开发团队控制的外部系统,这些系统将重要信息输入到智能合约中。这有时是必要的,因为智能合约无法自主运行,需要从外部调用。然而,不太常见的是,在一个高 TVL 的跨链桥中,依赖 3 个 keeper 来实现端到端的安全性。

继续我们的调查,假设攻击者无法控制 3 个 EOA,那么 Merkle prover 可能是智能合约中逻辑错误的可能原因。因此,我们接下来对此进行了研究。

/* @notice                  Verify Poly chain transaction whether exist or not
    *  @param _auditPath        Poly chain merkle proof
    *  @param _root             Poly chain root
    *  @return                  The verified value included in _auditPath
    */
    function merkleProve(bytes memory _auditPath, bytes32 _root) internal pure returns (bytes memory) {
        uint256 off = 0;
        bytes memory value;
        //_auditPath = 0xef20a106246297a2d44f97e78f3f402804011ce360c224ac33b87fe8b6d7b7e618c306000000000000002000000000000000000000000000000000000000000000000000000000000382fc20114c912bcc8ae04b5f5bd386a4bddd8770ae2c3111b7537327c3a369d07179d6142f7ac9436ba4b548f9582af91ca1ef02cd2f1f03020000000000000014250e76987d838a75310c34bf422ea9f1ac4cc90606756e6c6f636b4a14cd1faff6e578fa5cac469d2418c95671ba1a62fe14e0afadad1d93704761c8550f21a53de3468ba5990008f882cc883fe55c3d18000000000000000000000000000000000000000000
        (value, off)  = ZeroCopySource.NextVarBytes(_auditPath, off);

        bytes32 hash = Utils.hashLeaf(value);
        uint size = _auditPath.length.sub(off).div(33);
        bytes32 nodeHash;
        byte pos;
        for (uint i = 0; i < size; i++) {
            (pos, off) = ZeroCopySource.NextByte(_auditPath, off);
            (nodeHash, off) = ZeroCopySource.NextHash(_auditPath, off);
            if (pos == 0x00) {
                hash = Utils.hashChildren(nodeHash, hash);
            } else if (pos == 0x01) {
                hash = Utils.hashChildren(hash, nodeHash);
            } else {
                revert("merkleProve, NextByte for position info failed");
            }
        }
        require(hash == _root, "merkleProve, expect root is not equal actual root");
        return value;
    }

Poly Network 黑客攻击 | Poly 链的 Merkle prover

上面的 Merkle prover 接受一个字节序列(_auditPath)作为输入,其中包含叶节点,后跟 Merkle 树中的一条路径,该路径证明叶节点的存在,给定状态根(_root)。请记住,此状态根已由 keeper 签名。如果你不熟悉 Merkle 树的工作原理,下图描述了一个 Merkle 树,它是一种密码学安全的数据结构。该算法的关键在于 Merkle 树的根包含(传递地)来自树中所有叶节点的熵。因此,可以轻松构建证明(通常称为“witness”),并且可以廉价地验证证明。我们只需要信任树的根,如果它被信任,那么 Merkle 树 witness 验证的任何其他内容也会被信任。

Poly Network Hack

这里的关键在于,为了简化漏洞利用场景,攻击者充分利用了验证器实现所提供的灵活性。事实证明,验证器允许零长度的 witness。本质上,攻击者传入了叶节点(在这种情况下,叶节点正好是 240 字节),以及空路径作为证明。事实证明,在这种情况下,叶节点的哈希值需要与状态根(哈希值)相对应,才能使此证明成功。这进一步增加了 Poly 链 keeper 可能已遭到破坏并签署了人为构造的状态根的假设。其中包含的唯一信息是向攻击者发送代币的解锁命令。

不幸的是,值得注意的是,Poly network 此前曾受到一位灰帽黑客的 攻击,大约在两年前。

最后,Poly network 花了 7 个小时才对今天的攻击做出反应,在此期间,攻击者精心策划了多个链上的多笔交易来利用这一点。

尽管有上述说法,但到目前为止,还没有确凿的证据表明密钥被盗。这可能是一场 rugpull,也可能是运行在 4 个 keeper 中的 3 个上的链下软件遭到破坏。就我们所能观察到的而言,效果是一样的。在 Poly network 黑客攻击中,似乎明确的是,执行代币转账的智能合约中没有利用逻辑错误,并且 keeper 签署了恶意制作的证明。如果 Poly network 开发人员确实确认攻击与签名密钥被盗有关(很可能就是这种情况),那么这会让人质疑中心化桥梁控制如此多资金的适用性。此次攻击还表明 Poly network 团队对底层桥梁的监控不够完善。如果协议设置了一个快速监控解决方案,例如 Dedaub Watchdog,这将大大缩短反应时间,并可能节省一些资金。

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

0 条评论

请先 登录 后评论
Dedaub
Dedaub
Security audits, static analysis, realtime threat monitoring