BCH 升级攻击事件安全分析
5 月 15 日 BCH 升级遭到攻击,慢雾安全团队及时跟进,并在社区里注意到相关分析工作,通过交流将此分析文完整转载于此。这是一场真实攻击,从行为上分析来看确实预谋已久,但 BCH 响应很及时,成功化解了一场安全危机。
攻击导致了矿工节点无法打包,BCH 方面通过类似于空块攻击的方式,紧急挖出十个空块以触发滚动检查点保证升级。攻击发生约 1 小时后,BCH 矿池上线紧急修复后的代码成功继续出块。
不过同时也有人观察到,在 582698 区块高度,有矿工挖出了哈希结尾为 6bf418af 的区块,大小 139369 字节。但随后该区块被 10 分钟后 BTC.top 挖出的哈希结尾为 449e2bb4 区块所重组。或许是一次误伤,不过可见 BCH 对于升级防守之严密。
攻击原理分析
攻击载荷
捕捉到的攻击载荷 TXID 为
4c83ab55623633c86ec711b3d68ccdea506b228178ff1533f287ab744b006c44
其内容点击 附件 查看。
该攻击载荷由 1334 个 Input 构成,每一个 Input 均是 P2SH 格式。
其内容为
OP_FALSE OP_IF OP_CHECKDATASIG OP_CHECKDATASIG OP_CHECKDATASIG OP_CHECKDATASIG OP_CHECKDATASIG OP_CHECKDATASIG OP_CHECKDATASIG OP_CHECKDATASIG OP_CHECKDATASIG OP_CHECKDATASIG OP_CHECKDATASIG OP_CHECKDATASIG OP_CHECKDATASIG OP_CHECKDATASIG OP_14 OP_CHECKDATASIG OP_ENDIF OP_TRUE
该攻击载荷利用了一个 CORE 曾经帮 ABC 修复,但未完全修复的漏洞,制造了组块和验证之间的差异,从而导致矿工组出的区块不被节点接受。
漏洞背景
OP_CHECKDATASIG 是一种椭圆曲线签名校验指令(SigOP),这类指令由于需要进行椭圆曲线运算,执行开销远高于其他指令。因此在节点代码中,对于这类指令的数量做出了限制,以避免拒绝服务攻击。相关代码位置: src/consensus/consensus.h#L27
static const uint64_t MAX_TX_SIGOPS_COUNT = 20000;
漏洞原理
细心的话,你已经发现了,攻击载荷的 SigOP 数量为 1334 * 15 = 20010,这个攻击载荷 TX 会被节点拒绝,报错即是 too many sigops,这是导致节点拒绝包含该 TX 的区块的原因。相关代码位置: src/validation.cpp#L1936
if (nSigOpsCount > nMaxSigOpsCount) {
return state.DoS(100, error("ConnectBlock(): too many sigops"),
REJECT_INVALID, "bad-blk-sigops");
}
补丁位置: https://reviews.bitcoinabc.org/D3053
相关代码位置: src/validation.cpp#L592
// 原代码
int64_t nSigOpsCount = GetTransactionSigOpCount(tx, view, STANDARD_SCRIPT_VERIFY_FLAGS);// 补丁代码
int64_t nSigOpsCount = GetTransactionSigOpCount(tx, view, STANDARD_CHECKDATASIG_VERIFY_FLAGS);
所在的函数为:AcceptToMemoryPoolWorker
可见原代码组块过程中在计算 Transaction 中的 SigOP 数量时,错误地使用了 STANDARD_SCRIPT_VERIFY_FLAGS,而非 STANDARD_CHECKDATASIG_VERIFY_FLAGS。
这两个标志有什么区别呢?
在 policy 中我们可以找到他们。
相关代码位置: src/policy/policy.h#L108
static const uint32_t STANDARD_CHECKDATASIG_VERIFY_FLAGS =
STANDARD_SCRIPT_VERIFY_FLAGS | SCRIPT_ENABLE_CHECKDATASIG;
所以我们可以见到,当仅使用了 STANDARD_SCRIPT_VERIFY_FLAGS 时,计算脚本中 SigOP 数量时,是不包含 OP_CHECKDATASIG 的。所以这个包含 20010 个 SigOP 的攻击载荷,在组块时,统计出来的 SigOP 数量为零。
因此,攻击载荷会在矿工组块的时候被包含进区块中,然而,由于其他代码正确地统计了 SigOP,节点会拒绝该区块,这导致了 BCH 无法出块。
总结
攻击者利用了 BCH 引入 OP_CHECKDATASIG 时产生的,又未完全修复的漏洞,巧妙地构造了攻击载荷。攻击者应该高度了解客户端代码,并熟悉 OP_CHECKDATASIG 漏洞。
来源:慢雾科技
위믹스3.0 최초의 DAO ‘원더다오’, 노드 카운슬 파트너 합류
위믹스3.0 최초의 DAO ‘원더다오’, 노드 카운슬 파트너 합류 l 탈중앙화 자율조직 형태로 결성…구성원 모두가 위믹스3.0 운영에 참여 가능l 스마트 컨트랙트 기반 모듈화 ...
[주간톡톡] 양의 탈을 쓴 늑대는 양일까? 늑대일까?
주간톡톡은 한주간의 블록체인 소식을 재구성해 독자들과 재미있게 이야기해보는 코너입니다. 이번주는 페이스북의 스테이블 코인 프로젝트 '디엠(Diem)'에 대해 알아보겠습니다. 그럼 ...
IBM, 블록체인 와인 추적 서비스 '빈어슈어(Assure)' 공개
IBM이 재배지부터 매장까지 와인 공급망을 추적할 수 있는 블록체인 기반 플랫폼을 공개했다.10일(현지시간) 발표에 따르면 IBM은 와인 모니터링 업체 e프로브넌스(eProven...