区块链漏洞风险提示|Cosmos Hub 链节点崩溃漏洞

  • A+
所属分类:安全漏洞
        区块链漏洞风险提示       


    Cosmos Hub 链节点崩溃漏洞



北京时间3月11日凌晨,知名区块链项目 Cosmos Hub 的节点客户端 Gaia 发布更新,修复了一个严重漏洞,该漏洞可能造成Cosmos Hub链节点崩溃,影响范围为Gaia <=V4.0.6。


区块链漏洞风险提示|Cosmos Hub 链节点崩溃漏洞


长亭区块链安全团队第一时间跟进分析,现公开分析报告,提醒并帮助相关方尽快检查修复。


漏洞摘要


Gaia项目未限制distribution模块账户作为直接转账收款人。这使得DistributionAccount和FeePoolCommunity之间的平衡可能被打破,从而触发Crisis模块的节点状态异常告警。最终导致链节点崩溃。


经分析,漏洞细节如下:


漏洞详情


Gaia项目中Crisis模块的AssertInvariants函数用于检查节点的状态是否正常。一旦节点状态异常,将会触发panic使节点崩溃。


// AssertInvariants asserts all registered invariants. If any invariant fails,// the method panics.func (k Keeper) AssertInvariants(ctx sdk.Context) {  ...  for i, ir := range invarRoutes {    ...    if res, stop := ir.Invar(ctx); stop {      // TODO: Include app name as part of context to allow for this to be      // variable.      panic(fmt.Errorf("invariant broken: %sn"+        "tCRITICAL please submit the following transaction:n"+        "tt tx crisis invariant-broken %s %s", res, ir.ModuleName, ir.Route))    }  }    ...}


Gaia各模块的状态检测项互不相同,其中我们来看distribution模块做了什么样的检查。检查的对应代码在x/distribution/keeper/invariants.go,L136-L162:


// ModuleAccountInvariant checks that the coins held by the distr ModuleAccount// is consistent with the sum of validator outstanding rewardsfunc ModuleAccountInvariant(k Keeper) sdk.Invariant {  return func(ctx sdk.Context) (string, bool) {        ...    communityPool := k.GetFeePoolCommunityCoins(ctx)        ...    macc := k.GetDistributionAccount(ctx)    balances := k.bankKeeper.GetAllBalances(ctx, macc.GetAddress())
broken := !balances.IsEqual(expectedInt) return sdk.FormatInvariant(...), broken }}


我们看到,正常状态下DistributionAccount的余额应等于FeePoolCommunity要发放的手续费奖励。

如果我们可以向DistributionAccount或FeePoolCommunity中转账,使其不等,就可以触发状态异常,crisis安全检测无法通过,最终导致节点崩溃。


为了实现这个攻击思路,我们需要关注BankKeeper中"向ModuleAccount转账"的功能实现。

稍微阅读一下代码我们可以发现,ModuleAccount会被列入黑名单而无法作为转账的收款地址。

对应的限制代码如下:


// BlockedAddrs returns all the app's module account addresses that are not// allowed to receive external tokens.func (app *GaiaApp) BlockedAddrs() map[string]bool {  blockedAddrs := make(map[string]bool)  for acc := range maccPerms {    blockedAddrs[authtypes.NewModuleAddress(acc).String()] = !allowedReceivingModAcc[acc]  }
return blockedAddrs}


但处于allowedReceivingModAcc中的ModuleAccount被视为特例,并不会被拉黑。

我们跟进allowedReceivingModAcc,看看都有哪些ModuleAccount可以被转账呢。


// module accounts that are allowed to receive tokens  allowedReceivingModAcc = map[string]bool{    distrtypes.ModuleName: true, // ModuleName = "distribution"  }


可以看到,这个被Gaia视为特列,可以作为直接转账的收款地址的ModuleAccount刚好就是DistributionAccount。

这使得我们可以向DistributionAccount转账来打破DistributionAccount和FeePoolCommunity之间的平衡,从而触发panic。


至此,我们分析出了完整的漏洞利用链。就是这里的非预期转账权限,造成了此次链节点崩溃的漏洞。


利用场景


攻击者通过client发布send交易,向DistributionAccount账户地址转账,即可使Gaia节点崩溃。


修复情况


最新版v4.1.0中,漏洞已被修复。

在Gaia Pull Request 755中,将/app/app.go第247行中的app.BlockedAddrs()改为了
app.ModuleAccountAddrs(),将distribution ModuleAccount加入了bank模块转账接收方的黑名单中使其不能作为直接转账的收款地址,修复了该链崩溃漏洞。


应对建议


如果您是Cosmos Hub的参与者,且运行着自己的Gaia节点,那么请及时升级您的Gaia至最新版本(V4.1.0)。


如果您是使用Cosmos-SDK进行公链开发的项目方,请您关闭distribution的被转账权限或者更新Cosmos-SDK版本。


此外,如果您仍然对该漏洞有疑问,或有其他安全顾虑,欢迎联系长亭区块链安全团队,我们可提供专业的安全咨询与审计服务,帮助您完善项目的安全建设。


区块链漏洞风险提示|Cosmos Hub 链节点崩溃漏洞

区块链漏洞风险提示|Cosmos Hub 链节点崩溃漏洞


本文始发于微信公众号(长亭安全课堂):区块链漏洞风险提示|Cosmos Hub 链节点崩溃漏洞

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: