-
-
[原创]Go语言模糊测试工具:Go-Fuzz
-
发表于: 2022-3-11 16:34 17700
-
Go 安装包下载地址在:https://golang.org/dl/
1.下载二进制包,本次使用的是 go1.14.4.linux-amd64.tar.gz。
2.将下载的二进制包解压至指定目录,比如 /usr/local目录。
3.配置环境变量,进入.bashrc 配置:
4.在最后面添加如下代码:
5.保存,退出,使环境变量生效:
6.查看环境变量是否生效:
7.接着在开发目录创建文件夹:
完成,之后构建的go项目源代码就放到src下面, 生成的安装包会自动放在bin目录下,生成过程中的中间文件会放在pkg下面。
创建/home/xxx/gowork/src/github.com/dvyukov/
目录,手动下载 zip 包上传到该目录进行安装,解压文件:
路径是
$GOPATH/src/github.com/dvyukov/go-fuzz
接下来下载 go-fuzz提供的语料库。存放路径是
$GOPATH/src/github.com/dvyukov/go-fuzz-corpus
下载的东西准备好了,执行安装:
准备待测试程序,将待测试程序下载到本地。并分析待测程序,确定测试对象。
根据待测对象编写Fuzz函数。
go-fuzz规定在执行fuzz时要创建一个开启fuzz的go文件, 这是 go-fuzz 中要求的,并且对内容的格式有规定。函数 func Fuzz(data []byte) int{}
是固定的写法,它是 fuzzer 的入口点;
Fuzz 函数的参数 data 是 go-fuzz生成的随机输入;返回值是一个整数,如果输入是有效的,则返回1,否则返回0。该文件需要位于待测文件夹下。作者给出了简单的对于image/png包的Fuzz函数实例
构建fuzz包
利用 go-fuzz-build
创建 fuzzing zip 文件 ,执行完命令后会在当前文件下生成一个zip文件。
构建语料库
新建文件夹为corpus
,并向中添加种子文件,fuzz引擎会自动从中获取种子。
执行fuzz
-bin :指定测试对象的zip
-workdir:指定工作目录
查看Fuzz进度,fuzz开始后,终端每隔几秒钟就会打印以下形式的stderr:
workers
:并行运行的测试数量(-procs参数指定)
corpus
:语料库中的有效种子数量, 括号中的时间表示发现最后一个有趣输入的时间
crashers
:已发现bug的数量(workdir/crashes 目录下)
restarts
:fuzzer重新启动测试过程的速率, 速率应接近 1/10000(即计划的重启速率);如果它大大高于 1/10000,请考虑修复已发现的导致频繁重启的错误
execs
:测试执行的总数,括号中的数字是测试执行的平均速度 。
cover
:在散列覆盖位图中设置的位数,如果这个数字增长,Fuzzer会发现新的代码行;位图大小为 64K;理想情况下cover
值应小于 5000,否则由于哈希冲突,Fuzzer可能会错过新的有趣输入。
uptime
:进程的正常运行时间,该信息也通过 http 提供(见-http
标志)
Fuzz结果
Fuzz执行结束后,如果发现crash,会在工作文件夹下出现新的两个文件夹,分为是 suppressions 和 crashers 。 suppressions 中包含崩溃日志。它的作用是让go-fuzz跳过导致相同崩溃的输入 , crashers 文件中放着战利品,每次崩溃都会产生三个文件,文件名为输入的SHA-1哈希,无后缀名的文件为导致崩溃的实际输入、output为 crash dump 、 quoted 中放的是导致崩溃的输入,不过是以字符串形式展示 。
用于解码和编码 ASE (Adobe Swatch Exchange) 文件的 Golang 包, ASE 包公开了 Decode 和 Encode 方法,只需将 io.Reader 接口传递给 ase.Decode,它将返回解码数据的 ASE 结构 ,我们可以将Decode作为我们的Fuzz目标。
项目地址:https://github.com/arolek/ase
1.首先将下载项目到本地,并重置git到漏洞修复点之前
2.编写Fuzz.go
3.Build
4.创建工作文件夹,语料库选择作者给出的samples,并开始Fuzz
5.Fuzz执行过程中的显示,下面表明并行运行的数量为2,语料库中有3个有效种子,发现了1个crash 等。
此时workdir文件夹下多了两个目录:crashers
和suppressions
。查看crashers中的内容, 崩溃以输入的 sha1 命名,导致崩溃的实际数据是没有扩展名的文件,如下面的19cd42975df835d9a41f76a1ae4dd2d17916ea9
。 “.quoted”文件是作为字符串常量的数据,因此可以轻松地将其添加到测试文件中。 '.output' 文件是 panic() 或一些 go-fuzz 确定崩溃的输出。
查看919cd42975df835d9a41f76a1ae4dd2d17916ea9.output
的内容
根据堆栈跟踪,查看color.go
内容源码,可以看到如下代码,很明显对name[:len(name)-1])
的切面访问导致了越界错误。
接着,我们使用 919cd42975df835d9a41f76a1ae4dd2d17916ea9.quoted
中的数据编写测试代码重现该漏洞,编写fuzz_test.go
,内容如下
go test 启动测试,很容易发现此时的len(name) = 0
, 因此 len(name)-1
不是有效的切片索引。
iprange是一个库,可用于从nmap格式的字符串中解析IPv4地址 , 它接收一个字符串,并返回一个“Min-Max”格式的列表 , iprange支持以下格式:
iprange的使用方法示例:
该示例中,调用了 ParseList
函数 ,该函数十分合适作为我们Fuzz的对象。该函数来自于 iprange/y.go
文件中,下为该函数源码,这个函数的功能是:ParseList
接收一个目标规格的列表,并返回一个范围列表。
1.下载项目到本地,并执行hard reset
2.准备Fuzz函数,在项目文件夹下创建文件Fuzz.go
3.编译,编译成功后,会在当前文件夹下生成iprange-fuzz.zip
4.准备语料库, 为了进行有意义的 fuzz,我们需要尽可能提供格式正确的样本。可以直接从iprange 项目 README文件中复制示例,并创建一下3个文件,放入corpus文件夹。
test1
test2
test3
5.运行Fuzz
发现crash后,查看crasher文件夹下出现了3个文件,打开.out
文件查看堆栈跟踪:
首先是encoding/binary/binary.bigEndian.Uint32
,它是 go 的标准库,定位到源码 /usr/local/go/src/encoding/binary/binary.go:112
_ = b[3]
这一句很是可疑, 注意到它的注释中提到“给编译器的边界检查提示”,根据它提到的链接,去看看是什么情况 https://github.com/golang/go/issues/14808。在 issues 中讲到了边界检查,这是为了检查输入是否有足够的字节,如果没有,它将在字节被访问时发生 panic 异常。这说明这句可能存在漏洞。
于是构造下面这一小段可以引起 panic 的代码来测试下:
发现错误和之前的很相似,那么漏洞位置基本确定了。
接下来再看看这个漏洞的触发前提,即调用 bigEndian.Uint32
的函数iprange.Parse
。 查看github.com/malfunkt/iprange/y.go:504
附近代码:
传入 bigEndian.Uint32
的参数是 min
,min
来自于 mask
,而mask
又来自于 net.CIDRMask
。
查看 net.CIDRMask 的解释,https://golang.org/pkg/net/#CIDRMask
在 go 源码中可以查看到 CIDRMask 的源码:
可以发现如果ones
无效,函数将会返回nil
。Mask
为 nil
便是会是我们想要的结果,为了研究如何使 ones
无效,我们可以通过修改iprange包的源码,把 ipDollar[3]
打印出来看看。
代码修改完毕后,接着用 fuzz时导致 crash 的输入复现一下,代码在之前 fuzz 程序的基础上稍加改动即可,创建文件test2.go,内容如下:
运行
可以看出,程序中将 50 传递给 net.CIDRMask ,会导致 mask 为 nil ,进而导致 min 也为 nil,这样的 min 再作为参数传入bigEndian.Uint32 便会出现越界索引 。
gocmpp 是一个实现中国移动点对点(cmpp)协议的库 , 可以使用该库来实现任何在客户端和服务器端都使用 cmpp 协议的应用程序、工具或系统。 gocmpp中的每种协议包都实现了Packer接口,其中的Unpack尤其适合模糊测试。
项目地址:https://github.com/bigwhite/gocmpp
先说说每个fuzz test单元(比如fwd或submit)下的gen/main.go
,这是一个用于生成初始语料的可执行程序,我们以submit/gen/main.go
为例:
在这个main.go
中,我们借用submit
包的单元测试中的数据作为fuzz test的初始语料数据,通过go-fuzz提供的gen包将数据输出到文件中:
该程序在corpus下生成了一个文件“0”,作为submit fuzz test的初始语料。
接下来我们看看submit/fuzz.go: submit/fuzz.go
:
接下来就是go-fuzz-build和go-fuzz登场
https://github.com/dvyukov/go-fuzz
https://parsiya.net/blog/2018-04-29-learning-go-fuzz-1-iprange/
https://dgryski.medium.com/go-fuzz-github-com-arolek-ase-3c74d5a3150c
https://studygolang.com/articles/5461
http://blog.nsfocus.net/go-fuzz-0806/
$ tar
-
C
/
usr
/
local
-
xzf go1.
14.4
.linux
-
amd64.tar.gz
$ tar
-
C
/
usr
/
local
-
xzf go1.
14.4
.linux
-
amd64.tar.gz
$ vim ~
/
.bashrc
$ 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
# 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
$ source ~
/
.bashrc
$ go env
$ go env
cd
/
home
/
xxx
/
gowork
mkdir
bin
# bin是生产目录
mkdir src
# src 是开发目录
mkdir pkg
# pkg 是包目录
cd
/
home
/
xxx
/
gowork
mkdir
bin
# bin是生产目录
mkdir src
# src 是开发目录
mkdir pkg
# pkg 是包目录
$ go get github.com
/
dvyukov
/
go
-
fuzz
$ go get github.com
/
dvyukov
/
go
-
fuzz
$ unzip go
-
fuzz
-
master.
zip
$ unzip go
-
fuzz
-
master.
zip
$ go install $GOPATH
/
src
/
github.com
/
dvyukov
/
go
-
fuzz
/
go
-
fuzz
$ go install $GOPATH
/
src
/
github.com
/
dvyukov
/
go
-
fuzz
/
go
-
fuzz
-
build
$ go install $GOPATH
/
src
/
github.com
/
dvyukov
/
go
-
fuzz
/
go
-
fuzz
$ go install $GOPATH
/
src
/
github.com
/
dvyukov
/
go
-
fuzz
/
go
-
fuzz
-
build
package png
import
(
"bytes"
"image/png"
)
func Fuzz(data []byte)
int
{
png.Decode(bytes.NewReader(data))
return
0
}
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
=
.
$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
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 get github.com
/
arolek
/
ase
$ cd `go
list
-
f
'{{.Dir}}'
github.com
/
arolek
/
ase`
$ git reset
-
-
hard b1bf7d7a70445821722b29395f07fcd13e940f8c
$ 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
}
/
/
+
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
$ go
-
fuzz
-
build github.com
/
arolek
/
ase
$ mkdir
-
p workdir
/
corpus
$ cp samples
/
*
.ase workdir
/
corpus
$ go
-
fuzz
-
bin
=
ase
-
fuzz.
zip
-
workdir
=
workdir
$ 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
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
20
drwxrwx
-
-
-
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
null@ubuntu:~
/
gowork
/
src
/
github.com
/
arolek
/
ase
/
workdir$ ll crashers
/
total
20
drwxrwx
-
-
-
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
+
0x21f
github.com
/
arolek
/
ase.(
*
Color).read(
0xc000058050
,
0x4e6600
,
0xc00005a150
,
0x0
,
0x0
)
/
home
/
null
/
gowork
/
src
/
github.com
/
arolek
/
ase
/
color.go:
33
+
0xfe
github.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
+
0x69e
github.com
/
arolek
/
ase.Fuzz(
0x7f5cadcdf000
,
0x14
,
0x14
,
0x4
)
/
home
/
null
/
gowork
/
src
/
github.com
/
arolek
/
ase
/
fuzz.go:
7
+
0xb5
go
-
fuzz
-
dep.Main(
0xc000074f70
,
0x1
,
0x1
)
go
-
fuzz
-
dep
/
main.go:
36
+
0x1ad
main.main()
github.com
/
arolek
/
ase
/
go.fuzz.main
/
main.go:
15
+
0x52
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
+
0x21f
github.com
/
arolek
/
ase.(
*
Color).read(
0xc000058050
,
0x4e6600
,
0xc00005a150
,
0x0
,
0x0
)
/
home
/
null
/
gowork
/
src
/
github.com
/
arolek
/
ase
/
color.go:
33
+
0xfe
github.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
+
0x69e
github.com
/
arolek
/
ase.Fuzz(
0x7f5cadcdf000
,
0x14
,
0x14
,
0x4
)
/
home
/
null
/
gowork
/
src
/
github.com
/
arolek
/
ase
/
fuzz.go:
7
+
0xb5
go
-
fuzz
-
dep.Main(
0xc000074f70
,
0x1
,
0x1
)
go
-
fuzz
-
dep
/
main.go:
36
+
0x1ad
main.main()
github.com
/
arolek
/
ase
/
go.fuzz.main
/
main.go:
15
+
0x52
color.Name
=
string(utf16.Decode(name[:
len
(name)
-
1
]))
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))
}
}
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
+
0x2f5
testing.tRunner.func1(
0xc00008e120
)
/
usr
/
local
/
go
/
src
/
testing
/
testing.go:
943
+
0x3f9
panic(
0x5354e0
,
0xc000012340
)
/
usr
/
local
/
go
/
src
/
runtime
/
panic.go:
969
+
0x166
github.com
/
arolek
/
ase.(
*
Color).readName(
0xc0000580a0
,
0x570720
,
0xc00000c0c0
,
0x66d3c8
,
0x511340
)
/
home
/
null
/
gowork
/
src
/
github.com
/
arolek
/
ase
/
color.go:
67
+
0x1ba
github.com
/
arolek
/
ase.(
*
Color).read(
0xc0000580a0
,
0x570720
,
0xc00000c0c0
,
0x0
,
0x0
)
/
home
/
null
/
gowork
/
src
/
github.com
/
arolek
/
ase
/
color.go:
33
+
0x9e
github.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
+
0x4e3
github.com
/
arolek
/
ase.TestFuzzCrashers(
0xc00008e120
)
/
home
/
null
/
gowork
/
src
/
github.com
/
arolek
/
ase
/
ase_test.go:
15
+
0xdf
testing.tRunner(
0xc00008e120
,
0x550370
)
/
usr
/
local
/
go
/
src
/
testing
/
testing.go:
991
+
0xdc
created by testing.(
*
T).Run
/
usr
/
local
/
go
/
src
/
testing
/
testing.go:
1042
+
0x357
exit status
2
FAIL github.com
/
arolek
/
ase
0.006s
$ 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
+
0x2f5
testing.tRunner.func1(
0xc00008e120
)
/
usr
/
local
/
go
/
src
/
testing
/
testing.go:
943
+
0x3f9
panic(
0x5354e0
,
0xc000012340
)
/
usr
/
local
/
go
/
src
/
runtime
/
panic.go:
969
+
0x166
github.com
/
arolek
/
ase.(
*
Color).readName(
0xc0000580a0
,
0x570720
,
0xc00000c0c0
,
0x66d3c8
,
0x511340
)
/
home
/
null
/
gowork
/
src
/
github.com
/
arolek
/
ase
/
color.go:
67
+
0x1ba
github.com
/
arolek
/
ase.(
*
Color).read(
0xc0000580a0
,
0x570720
,
0xc00000c0c0
,
0x0
,
0x0
)
/
home
/
null
/
gowork
/
src
/
github.com
/
arolek
/
ase
/
color.go:
33
+
0x9e
github.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
+
0x4e3
github.com
/
arolek
/
ase.TestFuzzCrashers(
0xc00008e120
)
/
home
/
null
/
gowork
/
src
/
github.com
/
arolek
/
ase
/
ase_test.go:
15
+
0xdf
testing.tRunner(
0xc00008e120
,
0x550370
)
/
usr
/
local
/
go
/
src
/
testing
/
testing.go:
991
+
0xdc
created by testing.(
*
T).Run
/
usr
/
local
/
go
/
src
/
testing
/
testing.go:
1042
+
0x357
exit status
2
FAIL 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
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 main
import
(
"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)
}
package main
import
(
"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
}
/
/
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
$ 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
}
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
$ 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.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
赞赏
- [原创]CVE-2022-0847:脏管道漏洞对容器的影响 12210
- [原创]Seccomp BPF与容器安全 21399
- [原创]go语言模糊测试与oss-fuzz 22805
- [原创]CVE-2018-15664:符号链接替换漏洞 15539
- [原创]go语言原生模糊测试:源码分析与实战 15985