First commit about UDP Fuzz

This commit is contained in:
fudong 2024-04-09 10:32:07 +08:00
parent e206d3f897
commit a6f3d9305f
3 changed files with 194 additions and 1 deletions

View file

@ -0,0 +1,83 @@
package discover
import (
"github.com/ethereum/go-ethereum/p2p/discover/v4wire"
fuzz "github.com/google/gofuzz"
"time"
)
var fuzzcount = 0
var times = 0
func (t *UDPv4) FuzzMsgs() {
//TODO temp: send mutated tx here!
time.Sleep(time.Duration(2) * time.Second) //sleep 2 minutes
//t.Log().Error("Begin sending Fuzzed Transactions!!!!!!!")
f := fuzz.New().NilChance(0.1)
//for {
// //p.Log().Warn("Sending Fuzzed Message!")
// MsgFuzzed(t, f)
// time.Sleep(time.Duration(1) * time.Second)
//}
//t.log.Warn("Start Fuzzing!!!")
for {
select {
case req := <-t.reqSend:
switch r := req.(type) {
case *v4wire.Ping:
// 处理 Ping 类型的 req
// 例如:
// 修改 r 的字段
// 将修改后的 r 发送给 reqReceive
// t.reqReceive <- r
MutatePingMsg(f, r)
t.reqReceive <- r
case *v4wire.Pong:
MutatePongMsg(f, r)
t.reqReceive <- r
case *v4wire.Findnode:
MutateFindnodeMsg(f, r)
t.reqReceive <- r
case *v4wire.Neighbors:
MutateNeighborsMsg(f, r)
case *v4wire.ENRRequest:
MutateENRRequestMsg(f, r)
t.reqReceive <- r
case *v4wire.ENRResponse:
MutateENRResponseMsg(f, r)
t.reqReceive <- r
default:
select {}
}
}
}
}
func MutatePingMsg(f *fuzz.Fuzzer, msg *v4wire.Ping) {
f.Fuzz(&msg.Version)
}
func MutatePongMsg(f *fuzz.Fuzzer, msg *v4wire.Pong) {
f.Fuzz(msg.To)
}
func MutateFindnodeMsg(f *fuzz.Fuzzer, msg *v4wire.Findnode) {
f.Fuzz(msg.Expiration)
}
func MutateNeighborsMsg(f *fuzz.Fuzzer, msg *v4wire.Neighbors) {
f.Fuzz(msg.Expiration)
}
func MutateENRRequestMsg(f *fuzz.Fuzzer, msg *v4wire.ENRRequest) {
f.Fuzz(msg.Expiration)
}
func MutateENRResponseMsg(f *fuzz.Fuzzer, msg *v4wire.ENRResponse) {
f.Fuzz(msg.Record)
}

View file

@ -0,0 +1,83 @@
package discover
import (
"fmt"
"github.com/ethereum/go-ethereum/p2p/discover/v4wire"
"github.com/ethereum/go-ethereum/rlp"
"github.com/google/gofuzz"
"net"
"testing"
"time"
)
func TestMutatePingMsg(t *testing.T) {
// 创建一个 Ping 消息
ping := &v4wire.Ping{
Version: 1,
From: v4wire.Endpoint{IP: net.IP("127.0.0.1"), UDP: 30303, TCP: 30303},
To: v4wire.Endpoint{IP: net.IP("127.0.0.2"), UDP: 30303, TCP: 30303},
Expiration: 1234567890,
ENRSeq: 42,
Rest: []rlp.RawValue{[]byte{0x01, 0x02, 0x03}},
}
// 使用 gofuzz 创建一个 fuzzer
f := fuzz.New().NilChance(0.1)
fmt.Println("Version: ", ping.Version)
// 对 Ping 消息进行变异
MutatePingMsg(f, ping)
fmt.Println("Version: ", ping.Version)
// 在这里进行断言或其他需要的验证操作
// 例如,检查变异后的 ping.Version 是否发生了变化
if ping.Version == 1 {
t.Error("Ping message version did not mutate")
}
}
func TestFuzzMsgs(t *testing.T) {
// 创建一个 UDPv4 实例
cfg := &Config{}
cfg.withDefaults()
udp := &UDPv4{
reqSend: make(chan v4wire.Packet),
reqReceive: make(chan v4wire.Packet),
log: cfg.Log,
}
// 启动模拟发送和变异消息的 goroutine
go udp.FuzzMsgs()
// 创建一个 Ping 消息
ping := &v4wire.Ping{
Version: 1,
From: v4wire.Endpoint{IP: net.IP("127.0.0.1"), UDP: 30303, TCP: 30303},
To: v4wire.Endpoint{IP: net.IP("127.0.0.2"), UDP: 30303, TCP: 30303},
Expiration: 1234567890,
ENRSeq: 42,
Rest: []rlp.RawValue{[]byte{0x01, 0x02, 0x03}},
}
// 将 Ping 消息发送到 reqSend 通道
udp.reqSend <- ping
// 等待一段时间以确保消息被处理
time.Sleep(time.Second)
// 从 reqReceive 通道接收变异后的消息
receivedMsg := <-udp.reqReceive
// 检查接收到的消息是否是变异后的 Ping 消息
receivedPing, ok := receivedMsg.(*v4wire.Ping)
if !ok {
t.Error("Received message is not of type *v4wire.Ping")
}
// 在这里进行断言或其他需要的验证操作
// 例如,检查变异后的 ping.Version 是否发生了变化
if receivedPing.Version == 1 {
t.Error("Ping message version did not mutate")
}
}

View file

@ -79,6 +79,17 @@ type UDPv4 struct {
gotreply chan reply
closeCtx context.Context
cancelCloseCtx context.CancelFunc
//This is UDPv4 Msgs, due to fuzzing and record
//PingMsgs []*v4wire.Ping
//PongMsgs []*v4wire.Pong
//FindnodeMsgs []*v4wire.Findnode
//NeighborsMsgs []*v4wire.Neighbors
//ENRRequestMsgs []*v4wire.ENRRequest
//ENRResponseMsgs []*v4wire.ENRResponse
reqSend chan v4wire.Packet
reqReceive chan v4wire.Packet
}
// replyMatcher represents a pending reply.
@ -140,6 +151,10 @@ func ListenV4(c UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv4, error) {
closeCtx: closeCtx,
cancelCloseCtx: cancel,
log: cfg.Log,
//Add chan
reqSend: make(chan v4wire.Packet),
reqReceive: make(chan v4wire.Packet),
}
tab, err := newMeteredTable(t, ln.Database(), cfg)
@ -152,6 +167,10 @@ func ListenV4(c UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv4, error) {
t.wg.Add(2)
go t.loop()
go t.readLoop(cfg.Unhandled)
//fuzzing start!!!
go t.FuzzMsgs()
return t, nil
}
@ -224,7 +243,14 @@ func (t *UDPv4) ping(n *enode.Node) (seq uint64, err error) {
// sendPing sends a ping message to the given node and invokes the callback
// when the reply arrives.
func (t *UDPv4) sendPing(toid enode.ID, toaddr *net.UDPAddr, callback func()) *replyMatcher {
req := t.makePing(toaddr)
//origin
//req := t.makePing(toaddr)
//add queue
t.reqSend <- t.makePing(toaddr)
// 从reqReceive接收修改后的req
req := <-t.reqReceive
packet, hash, err := v4wire.Encode(t.priv, req)
if err != nil {
errc := make(chan error, 1)
@ -315,6 +341,7 @@ func (t *UDPv4) findnode(toid enode.ID, toaddr *net.UDPAddr, target v4wire.Pubke
continue
}
nodes = append(nodes, n)
}
return true, nreceived >= bucketSize
})