月亮链 月亮链
Ctrl+D收藏月亮链
首页 > TUSD > 正文

PEER:IOST公链P2P远程拒绝服务漏洞_ESS

作者:

时间:1900/1/1 0:00:00

漏洞分析

IOST公链使用Go语言开发,Go语言的make函数如果参数控制不当容易产生拒绝服务漏洞。在IOST的公链代码中搜索make,找到了一处貌似可以利用的地方。

func(sy*SyncImpl)getBlockHashes(startint64,endint64)*msgpb.BlockHashResponse{resp:=&msgpb.BlockHashResponse{BlockInfos:make(*msgpb.BlockInfo,0,end-start1),}node:=sy.blockCache.Head()ifnode!=nil&&end>node.Head.Number{end=node.Head.Number}省略...

Line3make的第3个参数为end-start1,end和start来自handleHashQuery

func(sy*SyncImpl)handleHashQuery(rh*msgpb.BlockHashQuery,peerIDp2p.PeerID){ifrh.End<rh.Start||rh.Start<0{return}varresp*msgpb.BlockHashResponseswitchrh.ReqType{casemsgpb.RequireType_GETBLOCKHASHES:resp=sy.getBlockHashes(rh.Start,rh.End)casemsgpb.RequireType_GETBLOCKHASHESBYNUMBER:resp=sy.getBlockHashesByNums(rh.Nums。省略...

可以看到并没有限制end-start1的大小,只要end足够大,start足够小就可以导致拒绝服务。所以现在问题就只剩下如何触发这个漏洞。

漏洞利用

IOST节点之间的P2P通信使用的是libp2p,libp2p是一个模块化的网络堆栈,汇集了各种传输和点对点协议,使开发人员可以轻松构建大型,强大的p2p网络。

来看一看IOST节点的P2Pservice启动流程。

首先创建一个NetService,代码如下:

跨链流动性协议Symbiosis已将其治理代币SIS部署至BNB链:3月2日消息,跨链流动性协议Symbiosis已将其治理代币SIS部署在BNB链上,相关代币用例也将在BNB上实现。

此前消息,Symbiosis SIP-2提案在上个月以100%的投票支持率获得通过,根据该提案,Symbiosis协议功能将把SIS代币从以太坊转移到BNB链;在BNB上部署新的流动性池SIS/BNB;以及在BNB链上实现veSIS逻辑。[2023/3/2 12:37:55]

//NewNetServicereturnsaNetServiceinstancewiththeconfigargument.funcNewNetService(config*common.P2PConfig)(*NetService,error){ns:=&NetService{config:config,}iferr:=os.MkdirAll(config.DataPath,0755);config.DataPath!=""&&err!=nil{ilog.Errorf("failedtocreatep2pdatapath,err=%v,path=%v",err,config.DataPath)returnnil,err}privKey,err:=getOrCreateKey(filepath.Join(config.DataPath,privKeyFile))iferr!=nil{ilog.Errorf("failedtogetprivatekey.err=%v,path=%v",err,config.DataPath)returnnil,err}host,err:=ns.startHost(privKey,config.ListenAddr)iferr!=nil{ilog.Errorf("failedtostartahost.err=%v,listenAddr=%v",err,config.ListenAddr)returnnil,err}ns.host=hostns.PeerManager=NewPeerManager(host,config)ns.adminServer=newAdminServer(config.AdminPort,ns.PeerManager)returnns,nil}

Nabox上线稳定币跨链桥Symbiosis Finance:据官方消息,DeFi应用钱包Nabox宣布上线稳定币跨链桥Symbiosis Finance。[2022/1/4 8:25:06]

主要看Line18的startHost,该函数调用libp2p库创建了一个host

//startHoststartsalibp2phost.func(ns*NetService)startHost(pkcrypto.PrivKey,listenAddrstring)(host.Host,error){tcpAddr,err:=net.ResolveTCPAddr("tcp",listenAddr)iferr!=nil{returnnil,err}if!isPortAvailable(tcpAddr.Port){returnnil,ErrPortUnavailable}opts:=libp2p.Option{libp2p.Identity(pk),libp2p.NATPortMap(),libp2p.ListenAddrStrings(fmt.Sprintf("/ip4/%s/tcp/%d",tcpAddr.IP,tcpAddr.Port)),libp2p.Muxer(protocolID,mplex.DefaultTransport),}h,err:=libp2p.New(context.Background(),opts...)iferr!=nil{returnnil,err}h.SetStreamHandler(protocolID,ns.streamHandler)returnh,nil}

该host的流处理逻辑在ns.streamHandler中

func(ns*NetService)streamHandler(slibnet.Stream){ns.PeerManager.HandleStream(s,inbound。

steamHandler又调用PeerManager的HandleStream函数

//HandleStreamhandlestheincomingstream.////Itcheckswhethertheremotepeeralreadyexists.//Ifthepeerisnewandtheneighborcountdoesn'treachthethreshold,itaddsthepeerintotheneighborlist.//Ifpeeralreadyexits,justaddthestreamtothepeer.//Inothercases,resetthestream.func(pm*PeerManager)HandleStream(slibnet.Stream,directionconnDirection){remotePID:=s.Conn().RemotePeer()pm.freshPeer(remotePID)ifpm.isStreamBlack(s){ilog.Infof("remotepeerisinblacklist.pid=%v,addr=%v",remotePID.Pretty(),s.Conn().RemoteMultiaddr())s.Conn().Close()return}ilog.Debugf("handlenewstream.pid=%s,addr=%v,direction=%v",remotePID.Pretty(),s.Conn().RemoteMultiaddr(),direction)peer:=pm.GetNeighbor(remotePID)ifpeer!=nil{s.Reset()return}ifpm.NeighborCount(direction)>=pm.neighborCap{if!pm.isBP(remotePID){ilog.Infof("neighborcountexceeds,closeconnection.remoteID=%v,addr=%v",remotePID.Pretty(),s.Conn().RemoteMultiaddr())ifdirection==inbound{bytes,_:=pm.getRoutingResponse(string{remotePID.Pretty(。)iflen(bytes)>0{msg:=newP2PMessage(pm.config.ChainID,RoutingTableResponse,pm.config.Version,defaultReservedFlag,bytes)s.Write(msg.content()。time.AfterFunc(time.Second,func(){s.Conn().Close(。。else{s.Conn().Close(。return}pm.kickNormalNeighbors(direction。pm.AddNeighbor(NewPeer(s,pm,direction))return}

IOST链上DeFi项目Donnie Finance总锁仓突破2300万美金:据官方消息,IOST链上DeFi项目Donnie Finance总锁仓突破2300万美金。目前单币质押挖矿包含7个项目通证:IOST、DON、HUSD、PPT、iwBLY、iwBTC、iwBNB,其中IOST矿池总质押量超过1亿8000万IOST。

Donnie Finance是韩国技术团队Donnie在IOST链上开发的DeFi项目,除支持现有的DeFi存贷款业务外,还提供去中心化交易平台、资产管理、支付和信用分析等多种服务。此前DonnieFinance已向IOST用户空投DON总供应量的5%,帮助于IOST用户初步了解Donnie Finance。 DON目前已登陆MXC、BigOne、Coinone, Bitkub、IOSTDEX、xigua、waxgourd等交易平台。[2021/4/15 20:22:55]

对于新建立连接的peer,IOST会启动该peer并添加到neighborlist中

//AddNeighborstartsapeerandaddsittotheneighborlist.func(pm*PeerManager)AddNeighbor(p*Peer){pm.neighborMutex.Lock()deferpm.neighborMutex.Unlock()ifpm.neighbors==nil{p.Start()pm.storePeerInfo(p.id,multiaddr.Multiaddr{p.addr})pm.neighbors=ppm.neighborCount}}

peer启动之后,IOST会调用peer的readLoop和writeLoop函数对该peer进行读写。

//Startstartspeer'sloop.func(p*Peer)Start(){ilog.Infof("peerisstarted.id=%s",p.ID())gop.readLoop()gop.writeLoop(。

我们主要看readLoop,看IOST对我们发送的数据如何处理。

func(p*Peer)readLoop(){header:=make(byte,dataBegin)for{_,err:=io.ReadFull(p.stream,header)iferr!=nil{ilog.Warnf("readheaderfailed.err=%v",err)break}chainID:=binary.BigEndian.Uint32(header)ifchainID!=p.peerManager.config.ChainID{ilog.Warnf("mismatchedchainID.chainID=%d",chainID)break}length:=binary.BigEndian.Uint32(header)iflength>maxDataLength{ilog.Warnf("datalengthtoolarge:%d",length)break}data:=make(byte,dataBeginlength)_,err=io.ReadFull(p.stream,data)iferr!=nil{ilog.Warnf("readmessagefailed.err=%v",err)break}copy(data,header)msg,err:=parseP2PMessage(data)iferr!=nil{ilog.Errorf("parsep2pmessagefailed.err=%v",err)break}tagkv:=mapstring{"mtype":msg.messageType().String(。byteInCounter.Add(float64(len(msg.content())),tagkv)packetInCounter.Add(1,tagkv)p.handleMessage(msg。p.peerManager.RemoveNeighbor(p.id。

IOST与Tweebaa推易吧达成深度战略合作:据官方消息,近日,IOST与基于多维价值体系的价值社交平台“Tweebaa推易吧”达成深度战略合作。双方将围绕区块链技术创新、品牌共建、政企合作、全球社区拓展、B/C端业务布局等方面展开深度合作,共同打造开放共赢的区块链商业应用。

IOST是全球化的企业级区块链技术应用平台,致力于将区块链技术应用,推广至商业端各类行业和客户端各类应用场景中。

推易吧是基于多维价值体系的价值社交平台,致力于打造人人都能创新变现的价值社交生态圈,实现物质财富、精神财富、社会财富的共同增长。[2020/6/9]

主要是读取一个固定长度的header,然后根据header中的length来读取data,通过header和data创建一个P2PMessage,最后调用handleMessage来处理这个msg。节点发送的数据包结构如下:

/*P2PMessageprotocol:0123(bytes)01234567012345670123456701234567--------------------------------|ChainID|--------------------------------------------------------------|MessageType|Version|--------------------------------------------------------------|DataLength|---------------------------------------------------------------|DataChecksum|---------------------------------------------------------------|Reserved|---------------------------------------------------------------||.Data.||---------------------------------------------------------------*/

handleMessage会根据messageType对message进行处理

动态 | 跨ETH/EOS/TRON/IOST四大公链,DApp活跃度排行榜:据 DAppTotal 02月17日数据显示,过去一周,综合对比ETH、EOS、TRON、IOST四大公链的DApp生态情况发现:总用户量(个): ETH(285,049) > TRON(63,024) > EOS(26,210) > IOST(4,188);总交易次数(笔):EOS(262,572,804) > IOST(5,541,896) > TRON(2,693,364) > ETH(1,266,827);总交易额(美元):EOS(170,939,080) > ETH(110,107,769) > TRON(39,971,078) > IOST(3,391,798);跨四条公链按用户量TOP3 DApps为:MillionMoney(ETH)、Origin Protocol(ETH)、Oasis 金库(ETH);按交易次数TOP3 DApps分别为:EIDOS(EOS)、POW(EOS)、iPirates(IOST);按交易额TOP3 DApps分别为:Newdex(EOS)、Maker(ETH)、CDP Portal(ETH)。[2020/2/17]

//HandleMessagehandlesmessagesaccordingtoitstype.func(pm*PeerManager)HandleMessage(msg*p2pMessage,peerIDpeer.ID){data,err:=msg.data()iferr!=nil{ilog.Errorf("getmessagedatafailed.err=%v",err)return}switchmsg.messageType(){caseRoutingTableQuery:gopm.handleRoutingTableQuery(msg,peerID)caseRoutingTableResponse:gopm.handleRoutingTableResponse(msg)default:inMsg:=NewIncomingMessage(peerID,data,msg.messageType())ifm,exist:=pm.subs.Load(msg.messageType());exist{m.(*sync.Map).Range(func(k,vinterface{})bool{select{casev.(chanIncomingMessage)<-*inMsg:default:ilog.Warnf("sendingincomingmessagefailed.type=%s",msg.messageType()。returntrue}。}

了解了IOST节点之间P2P通信的处理逻辑,再来看看如何触发存在漏洞的handleHashQuery函数。messageLoop中调用了handlerHashQuery

func(sy*SyncImpl)messageLoop(){defersy.wg.Done()for{select{casereq:=<-sy.messageChan:switchreq.Type(){casep2p.SyncBlockHashRequest:varrhmsgpb.BlockHashQueryerr:=proto.Unmarshal(req.Data(),&rh)iferr!=nil{ilog.Errorf("UnmarshalBlockHashQueryfailed:%v",err)break}gosy.handleHashQuery(&rh,req.From())省略...

可以看到当messageType为p2p.SyncBlockHashRequest,Data为BlockHashQuery时,handlerHashQuery函数会被调用。BlockHashQuery的结构如下,End和Start的值可控。

typeBlockHashQuerystruct{ReqTypeRequireType`protobuf:"varint,1,opt,name=reqType,proto3,enum=msgpb.RequireType"json:"reqType,omitempty"`Startint64`protobuf:"varint,2,opt,name=start,proto3"json:"start,omitempty"`Endint64`protobuf:"varint,3,opt,name=end,proto3"json:"end,omitempty"`Numsint64`protobuf:"varint,4,rep,packed,name=nums,proto3"json:"nums,omitempty"`XXX_NoUnkeyedLiteralstruct{}`json:"-"`XXX_unrecognizedbyte`json:"-"`XXX_sizecacheint32`json:"-"`}

因此,我们可以构造一个Message,将Start的值设为0,End的值设为math.MaxInt64,将该Message发送给节点,就可以触发make函数的capoutofrange,导致拒绝服务。

POC见https://github.com/fatal0/poc/blob/master/go-iost/p2p_dos.go

漏洞修复

官方的修复方式也很简单,限制end-start1的大小。

https://github.com/iost-official/go-iost/commit/9824cfce3bb4b14f43b60f470cbba86e879dd32a#diff-4e27320b328b8f0d452f10e1ed383d73R330

标签:PEEREERREAESSPEER币PMEER价格ethereal寓意PESS币

TUSD热门资讯
DRAG:DragonEx 开放平台1.0全新上线_ONE

DragonEx开放平台1.0全新上线2019-04-30亲爱的用户:DragonEx开放平台1.0将于2019年4月30日15:00正式上线,开放平台1.0将会采用新的架构.

1900/1/1 0:00:00
BCH:5.2早间行情:是震荡蓄势还是二次探底?_MACPO价格

文章系金色财经专栏作者供稿,发表言论仅代表其个人观点,仅供学习交流!金色盘面不会主动提供任何交易指导,亦不会收取任何费用指导交易,请读者仔细甄别,谨防上当.

1900/1/1 0:00:00
加密货币:美国SEC主席:正用现有法律处置加密货币实体不合规行为_数字资产评估

美国证券交易委员会主席在4月8日的一次讲话中重申了对加密货币领域的关注。美国证券交易委员会主席杰伊?克莱顿(JayClayton)在华盛顿举行的“证券交易委员会发言会议”(SECSpeaks)上.

1900/1/1 0:00:00
DEX:币安链的强势崛起会导致以太坊的没落吗?_BNB

在上个月币安链正式上线运行时,有不少蓝狐笔记的读者朋友问:币安链对以太坊会有影响吗?可见币安链和币安DEX上线的影响力.

1900/1/1 0:00:00
ETH:JEX上线周ETH期权0509公告_CUSDT

ETH看涨期权代码周ETH看涨0509期权标的ETH合约类型欧式看涨期权计价单位USDT最小价格单位0.0001USDT合约比例10:1.

1900/1/1 0:00:00
区块链:人民创投:区块链 共享经济创新发展研究报告_区块链个人怎么买

4月4日,人民创投区块链研究院传媒实验室发布了《区块链共享经济创新发展研究报告》。报告指出,共享经济呈现出高速增长之势,但其发展过程中出现了诸如资源配置效率低下、资产和服务质量不高、资产安全无法.

1900/1/1 0:00:00