一
go环境配置
$ tar -C /usr/local -xzf go1.14.4.linux-amd64.tar.gz
$ vim ~/.bashrc
# GOROOT:go的安装路径
export GOROOT="/usr/local/go"
# GOPATH:go的开发路径(自定义就好)
export GOPATH="/home/xxx/gowork"
# GOBIN:go工具程序存放路径
export GOBIN=$GOPATH/bin
export PATH=$PATH:${GOPATH//://bin:}/bin:/usr/local/go/bin
$ source ~/.bashrc
$ go env
cd /home/xxx/gowork
mkdir bin # bin是生产目录
mkdir src # src 是开发目录
mkdir pkg # pkg 是包目录
二
go-fuzz安装
$ go get github.com/dvyukov/go-fuzz
$ unzip go-fuzz-master.zip
$GOPATH/src/github.com/dvyukov/go-fuzz
$GOPATH/src/github.com/dvyukov/go-fuzz-corpus
$ go install $GOPATH/src/github.com/dvyukov/go-fuzz/go-fuzz$ go install $GOPATH/src/github.com/dvyukov/go-fuzz/go-fuzz-build
三
go-fuzz基本流程
package png
import (
"bytes"
"image/png"
)
func Fuzz(data []byte) int {
png.Decode(bytes.NewReader(data))
return 0
}
$GOPATH/bin/go-fuzz -bin=./mypackage-fuzz.zip -workdir= .
2015/04/25 12:39:53 workers: 500, corpus: 186 (42s ago), crashers: 3, restarts: 1/8027, execs: 12009519 (121224/sec), cover: 2746, uptime: 1m39s
四
go-fuzz项目实战
$ go get github.com/arolek/ase
$ cd `go list -f '{{.Dir}}' github.com/arolek/ase`
$ git reset --hard b1bf7d7a70445821722b29395f07fcd13e940f8c
// +build gofuzz
package ase
import "bytes"
func Fuzz(data []byte) int {
if _, err := Decode(bytes.NewReader(data)); err != nil {
return 0
}
return 1
}
$ go-fuzz-build github.com/arolek/ase
$ mkdir -p workdir/corpus
$ cp samples/*.ase workdir/corpus
$ go-fuzz -bin=ase-fuzz.zip -workdir=workdir
2022/03/10 18:01:40 workers: 2, corpus: 3 (1m15s ago), crashers: 1, restarts: 1/11, execs: 299360 (3991/sec), cover: 221, uptime: 1m15s
null@ubuntu:~/gowork/src/github.com/arolek/ase/workdir$ ll crashers/total 20drwxrwx--- 2 null null 4096 Mar 10 05:33 ./drwxrwxr-x 5 null null 4096 Mar 10 05:32 ../-rw-rw---- 1 null null 20 Mar 10 05:33 919cd42975df835d9a41f76a1ae4dd2d17916ea9-rw-rw---- 1 null null 885 Mar 10 05:33 919cd42975df835d9a41f76a1ae4dd2d17916ea9.output-rw-rw---- 1 null null 42 Mar 10 05:33 919cd42975df835d9a41f76a1ae4dd2d17916ea9.quoted
panic: runtime error: slice bounds out of range [:-1]goroutine 1 [running]:github.com/arolek/ase.(*Color).readName(0xc000058050, 0x4e6600, 0xc00005a150, 0x59a7c0, 0x4a8080) /home/null/gowork/src/github.com/arolek/ase/color.go:67 +0x21fgithub.com/arolek/ase.(*Color).read(0xc000058050, 0x4e6600, 0xc00005a150, 0x0, 0x0) /home/null/gowork/src/github.com/arolek/ase/color.go:33 +0xfegithub.com/arolek/ase.Decode(0x4e6600, 0xc00005a150, 0x44d9c9, 0x1160437af97c4, 0x191f107c, 0x191f107c00000000, 0x6229fe1c, 0xc000074e98, 0x46c526, 0x6229fe1c, ...) /home/null/gowork/src/github.com/arolek/ase/ase.go:56 +0x69egithub.com/arolek/ase.Fuzz(0x7f5cadcdf000, 0x14, 0x14, 0x4) /home/null/gowork/src/github.com/arolek/ase/fuzz.go:7 +0xb5go-fuzz-dep.Main(0xc000074f70, 0x1, 0x1) go-fuzz-dep/main.go:36 +0x1admain.main() github.com/arolek/ase/go.fuzz.main/main.go:15 +0x52
color.Name = string(utf16.Decode(name[:len(name)-1]))
package ase
import (
"strings"
"testing"
)
func TestFuzzCrashers(t *testing.T) {
var crashers = []string{
"ASEF00\x00\x000000\x00\x010000\x00\x00",
}
for _, f := range crashers {
Decode(strings.NewReader(f))
}
}
$ go test--- FAIL: TestFuzzCrashers (0.00s)panic: runtime error: slice bounds out of range [:-1] [recovered] panic: runtime error: slice bounds out of range [:-1]goroutine 6 [running]:testing.tRunner.func1.1(0x5354e0, 0xc000012340) /usr/local/go/src/testing/testing.go:940 +0x2f5testing.tRunner.func1(0xc00008e120) /usr/local/go/src/testing/testing.go:943 +0x3f9panic(0x5354e0, 0xc000012340) /usr/local/go/src/runtime/panic.go:969 +0x166github.com/arolek/ase.(*Color).readName(0xc0000580a0, 0x570720, 0xc00000c0c0, 0x66d3c8, 0x511340) /home/null/gowork/src/github.com/arolek/ase/color.go:67 +0x1bagithub.com/arolek/ase.(*Color).read(0xc0000580a0, 0x570720, 0xc00000c0c0, 0x0, 0x0) /home/null/gowork/src/github.com/arolek/ase/color.go:33 +0x9egithub.com/arolek/ase.Decode(0x570720, 0xc00000c0c0, 0x4c0b40, 0x603090, 0x630840, 0x0, 0x1, 0xc000030748, 0x451fd9, 0x16b13735d06, ...) /home/null/gowork/src/github.com/arolek/ase/ase.go:56 +0x4e3github.com/arolek/ase.TestFuzzCrashers(0xc00008e120) /home/null/gowork/src/github.com/arolek/ase/ase_test.go:15 +0xdftesting.tRunner(0xc00008e120, 0x550370) /usr/local/go/src/testing/testing.go:991 +0xdccreated by testing.(*T).Run /usr/local/go/src/testing/testing.go:1042 +0x357exit status 2FAIL github.com/arolek/ase 0.006s
10.0.0.1
10.0.0.0/24
10.0.0.*
10.0.0.1-10
10.0.0.1, 10.0.0.5-10, 192.168.1.*, 192.168.10.0/24
package mainimport ( "log" "github.com/malfunkt/iprange")func main() { list, err := iprange.ParseList("10.0.0.1, 10.0.0.5-10, 192.168.1.*, 192.168.10.0/24") if err != nil { log.Printf("error: %s", err) } log.Printf("%+v", list) rng := list.Expand() log.Printf("%s", rng)}
// ParseList takes a list of target specifications and returns a list of ranges,// even if the list contains a single element.func ParseList(in string) (AddressRangeList, error) { lex := &ipLex{line: []byte(in)} errCode := ipParse(lex) if errCode != 0 || lex.err != nil { return nil, errors.Wrap(lex.err, "could not parse target") } return lex.output, nil}
$ go get github.com/malfunkt/iprange
$ git reset --hard 3a31f5ed42d2d8a1fc46f1be91fd693bdef2dd52
package iprange
func Fuzz(data []byte) int {
_, err := ParseList(string(data))
if err != nil {
return 0
}
return 1
}
$ go-fuzz-build ~/gowork/src/github.com/malfunkt/iprange
10.0.0.1, 10.0.0.5-10, 192.168.1.*, 192.168.10.0/24
10.0.0.1-10,10.0.0.0/24,
10.0.0.0/24
10.0.0.*, 192.168.0.*, 192.168.1-256
panic: runtime error: index out of range [3] with length 0goroutine 1 [running]:encoding/binary.bigEndian.Uint32(...) /usr/local/go/src/encoding/binary/binary.go:112github.com/malfunkt/iprange.(*ipParserImpl).Parse(0xc0000af800, 0x53db40, 0xc000064ff0, 0x0) /home/null/gowork/src/github.com/malfunkt/iprange/y.go:504 +0x29d7github.com/malfunkt/iprange.ipParse(...) /home/null/gowork/src/github.com/malfunkt/iprange/y.go:306github.com/malfunkt/iprange.ParseList(0xc000043e78, 0xa, 0xa, 0xa, 0xc000043e78, 0xa, 0xc000043e98) /home/null/gowork/src/github.com/malfunkt/iprange/y.go:61 +0x127github.com/malfunkt/iprange.Fuzz(0x7f2a2627b000, 0xa, 0xa, 0x3) /home/null/gowork/src/github.com/malfunkt/iprange/fuzz.go:4 +0x7dgo-fuzz-dep.Main(0xc000043f70, 0x1, 0x1) go-fuzz-dep/main.go:36 +0x1admain.main() github.com/malfunkt/iprange/go.fuzz.main/main.go:15 +0x52
111 func (bigEndian) Uint32(b []byte) uint32 {112 _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808113 return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24114 }
// Small program to test panic when calling Uint32(nil).
package main
import (
"encoding/binary"
)
func main() {
_ = binary.BigEndian.Uint32(nil)
}
$ go run test.go
panic: runtime error: index out of range [3] with length 0
goroutine 1 [running]:
encoding/binary.bigEndian.Uint32(...)
/usr/local/go/src/encoding/binary/binary.go:112
main.main()
/home/null/gowork/src/test.go:9 +0x1a
exit status 2
case 5:
ipDollar = ipS[ippt-3 : ippt+1]
//line ip.y:54
{
mask := net.CIDRMask(int(ipDollar[3].num), 32)
min := ipDollar[1].addrRange.Min.Mask(mask)
maxInt := binary.BigEndian.Uint32([]byte(min)) +
0xffffffff -
binary.BigEndian.Uint32([]byte(mask))
maxBytes := make([]byte, 4)
binary.BigEndian.PutUint32(maxBytes, maxInt)
maxBytes = maxBytes[len(maxBytes)-4:]
max := net.IP(maxBytes)
ipVAL.addrRange = AddressRange{
Min: min.To4(),
Max: max.To4(),
}
}
// CIDRMask returns an IPMask consisting of `ones' 1 bits
// followed by 0s up to a total length of `bits' bits.
// For a mask of this form, CIDRMask is the inverse of IPMask.Size.
func CIDRMask(ones, bits int) IPMask {
if bits != 8*IPv4len && bits != 8*IPv6len {
return nil
}
if ones < 0 || ones > bits {
return nil
}
// removed
}
case 5: ipDollar = ipS[ippt-3 : ippt+1] //line ip.y:54 { fmt.Printf("ipdollar[3]: %v\n", ipDollar[3].num) // print ipdollar[3] mask := net.CIDRMask(int(ipDollar[3].num), 32) fmt.Printf("mask: %v\n", mask) // print mask min := ipDollar[1].addrRange.Min.Mask(mask) fmt.Printf("min: %v\n", min) // print min maxInt := binary.BigEndian.Uint32([]byte(min)) + 0xffffffff - binary.BigEndian.Uint32([]byte(mask)) maxBytes := make([]byte, 4) binary.BigEndian.PutUint32(maxBytes, maxInt) maxBytes = maxBytes[len(maxBytes)-4:] max := net.IP(maxBytes) ipVAL.addrRange = AddressRange{ Min: min.To4(), Max: max.To4(), } }
// Small program to investigate a panic in iprange for invalid masks.package mainimport "github.com/malfunkt/iprange"func main() { _ = Fuzz([]byte("0.0.0.0/50")) //.quoted的内容}func Fuzz(data []byte) int { _, err := iprange.ParseList(string(data)) if err != nil { return 0 } return 1}
$ go run test2.go
ipdollar[3]:50
mask:<nil>
min:<nil>
panic: runtime error: index out of range [3] with length 0
goroutine 1 [running]:
encoding/binary.bigEndian.Uint32(...)
/usr/local/go/src/encoding/binary/binary.go:112
github.com/malfunkt/iprange.(*ipParserImpl).Parse(0xc0000b6000, 0x515080, 0xc0000800a0, 0x0)
yaccpar:354 +0x1e8e
github.com/malfunkt/iprange.ipParse(...)
yaccpar:153
github.com/malfunkt/iprange.ParseList(0xc00003ef58, 0xa, 0xa, 0xa, 0xc00003ef58, 0xa, 0x4063df)
ip.y:93 +0xdf
main.Fuzz(...)
/home/null/gowork/src/test2.go:10
main.main()
/home/null/gowork/src/test2.go:6 +0x75
exit status 2
$ go get github.com/bigwhite/gocmpp
github.com/bigwhite/gocmpp/fuzztest]$tree
.
├── fwd
│ ├── corpus
│ │ └── 0
│ ├── fuzz.go
│ └── gen
│ └── main.go
└── submit
├── corpus
│ ├── 0
├── fuzz.go
└── gen
└── main.go
package mainimport ( "github.com/dvyukov/go-fuzz/gen")func main() { data := []byte{ 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x31, 0x33, 0x35, 0x30, 0x30, 0x30, 0x30, 0x32, 0x36, 0x39, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x39, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x32, 0x31, 0x30, 0x00, 0x00, 0x00, 0x00, 0x31, 0x35, 0x31, 0x31, 0x30, 0x35, 0x31, 0x33, 0x31, 0x35, 0x35, 0x35, 0x31, 0x30, 0x31, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x30, 0x30, 0x30, 0x30, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x31, 0x33, 0x35, 0x30, 0x30, 0x30, 0x30, 0x32, 0x36, 0x39, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x6d, 0x4b, 0x8b, 0xd5, 0x00, 0x67, 0x00, 0x6f, 0x00, 0x63, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x70, 0x00, 0x20, 0x00, 0x73, 0x00, 0x75, 0x00, 0x62, 0x00, 0x6d, 0x00, 0x69, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, } gen.Emit(data, nil, true)}
$cd submit/gen
$go run main.go -out ../corpus/
$ll ../corpus/
total 8
drwxr-xr-x 3 tony staff 102 12 7 22:00 ./
drwxr-xr-x 5 tony staff 170 12 7 21:42 ../
-rw-r--r-- 1 tony staff 181 12 7 22:00 0
// +build gofuzz
package cmppfuzz
import (
"github.com/bigwhite/gocmpp"
)
func Fuzz(data []byte) int {
p := &cmpp.Cmpp2SubmitReqPkt{}
if err := p.Unpack(data); err != nil {
return 0
}
return 1
}
$cd submit
$go-fuzz-build github.com/bigwhite/gocmpp/fuzztest/submit
$go-fuzz -bin=./cmppfuzz-fuzz.zip -workdir=./
热文推荐