Go Fuzzing:发现你未曾发现的漏洞

这篇具有很好参考价值的文章主要介绍了Go Fuzzing:发现你未曾发现的漏洞。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Fuzzing(模糊测试)

go fuzz文档

对于软件开发者而言,一项重要的任务就是确保程序的安全性。而其中一种风险就是软件中可能存在的漏洞。传统的测试方法往往需要耗费大量的时间和人力,而使用Fuzzing技术则可在短时间内大规模发现潜在的漏洞。

那什么是Fuzzing技术呢?简单说,它就是让程序自动生成大量随机的输入数据,然后运行被测试的程序,观察是否会出现异常行为。通过这种方式,Fuzzing技术可以快速发现和定位程序中的漏洞,帮助开发者提高程序的安全性。

那在Go语言中,如何使用Fuzzing技术呢?下面就让我们一起来了解一下。

Fuzzing,又叫fuzz testing,中文叫做模糊测试或随机测试。其本质上是一种自动化测试技术,更具体一点,它是一种基于随机输入的自动化测试技术,常被用于发现处理用户输入的代码中存在的bug和问题。

在具体实现上,Fuzzing不需要像单元测试那样使用预先定义好的数据集作为程序输入,而是会通过数据构造引擎自行构造或基于开发人员提供的初始数据构造一些随机数据,并作为输入提供给我们的程序,然后监测程序是否出现panic、断言失败、无限循环等。这些构造出来的随机数据被称为语料(corpus)。另外Fuzz testing不是一次性执行的测试,如果不限制执行次数和执行时间,Fuzz testing会一直执行下去,因此它也是一种持续测试的技术。

Fuzzing是对其他形式的测试、代码审查和静态分析的补充,它通过生成一个有趣的输入语料库,而这些输入几乎不可能用手去想去写出来,因此极易被传统类型的测试所遗漏。Fuzzing可以帮助开发人员发现难以发现的稳定性、逻辑性甚至是安全性方面的错误,特别是当被测系统变得更加复杂时。

Go 1.18版本正式接受了原生支持Fuzzing这个特性,Fuzzing成为Go的“一等公民”。

要求

Go Fuzz结构如图:

Go Fuzzing:发现你未曾发现的漏洞

模糊测试必须遵循下⾯的规则:

  1. 模糊测试函数名必须是 FuzzXxx ,参数是 *testing.F ,没返回值 ,如 func FuzzXxx(f
    *testing.F)

  2. 模糊测试必须放在以 *_test.go 后缀的⽂件中

  3. fuzz target 必须是调⽤ (*testing.F).Fuzz ,第⼀个参数 *testing.T , 后⾯是模糊测试的参数

  4. ⼀个模糊测试只能有⼀个fuzz target

  5. 种⼦语料(seed corpus )的数据类型必须和 fuzzing arguments⼀样,顺序⼀致。包括调⽤ (*testing.F).Add 增加种⼦语料,以及写在testdata/fuzz⽂件夹下语料
    fuzzing arguments 只能是下⾯的类型。如果你要测试复杂的struct,需要使⽤这些参数组装你的struct,然后进⼀步测试:

    • string , []byte
    • int , int8 , int16 , int32 / rune , int64
    • uint , uint8 / byte , uint16 , uint32 , uint64
    • float32 , float64
    • bool

示例

下面我们使用Fuzz对DNP3协议进行测试

func FuzzDnp3(f *testing.F) {
	f.Add([]byte{
		0x05, 0x64, 0x20, 0x44, 0x03, 0x00, 0x04, 0x00, 0x95, 0xe3, 0x85, 0x00, 0x01, 0x00, 0x00, 0x00,
		0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xef, 0xdc, 0x00, 0x01, 0x00, 0x00,
		0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x1f,
	})
	f.Fuzz(func(t *testing.T, data []byte) {
		Decode(data)
	})
}

可以使用命令运行

go test -v -fuzz  .

在Goland中也可以直接运行点击函数旁边的运行符号选择Fuzz进行运行,

D:\dev\Go\go1.20.1\bin\go.exe test -json app_go/pkg/dnp3 -fuzz ^\QFuzzDnp3\E$ -run ^$ #gosetup
kg/dnp3"}
=== RUN   FuzzDnp3
fuzz: elapsed: 0s, gathering baseline coverage: 0/23 completed
fuzz: elapsed: 0s, gathering baseline coverage: 23/23 completed, now fuzzing with 8 workers
fuzz: elapsed: 3s, execs: 99037 (32828/sec), new interesting: 1 (total: 24)
fuzz: elapsed: 6s, execs: 133383 (11479/sec), new interesting: 1 (total: 24)
fuzz: elapsed: 8s, execs: 133383 (0/sec), new interesting: 1 (total: 24)
--- PASS: FuzzDnp3 (8.02s)
PASS
ok  	app_go/pkg/dnp3	8.530s

fuzz testing默认会一直执行下去,直到遇到crash。如果要限制fuzz testing的执行时间,可以使用-fuzztime,比如下面的命令允许fuzz testing只执行10

go test -v  -fuzztime 10s -fuzz .

在上面fuzz执行过程中,Go fuzzing会将其缓存在cache路径下:

Go Fuzzing:发现你未曾发现的漏洞

go fuzzing会为每个FuzzXxx函数建立对应的语料缓存。目前fuzz cache的默认路径为$GOCACHE/fuzz/包路径/FuzzXxx,后续可能会提供环境变量或cmd option,以允许开发人员自定义fuzzing语料的缓存路径。

fuzzing test默认会一直执行下去,如果不限制执行次数和执行时间,执行Fuzzing test的机器要有足够的存储才行。而要想清理过多的fuzz缓存,用gotip clean -cache是不行的,需要为clean加上**-fuzzcache**才可以清除fuzz的cache。

模拟crash

当我们在代码中模拟一个crash的产生来看看:fuzzing test过程中发现代码bug时

我们看到go fuzzing在执行测试时就发生crash,fuzzing将crash输出了crash报告,并将引发这一crash的语料放入了testdata/fuzz/FuzzSubmit目录下:

Go Fuzzing:发现你未曾发现的漏洞

=== RUN   FuzzDnp3
fuzz: elapsed: 0s, gathering baseline coverage: 0/24 completed
failure while testing seed corpus entry: FuzzDnp3/seed#13
fuzz: elapsed: 0s, gathering baseline coverage: 12/24 completed
--- FAIL: FuzzDnp3 (0.22s)
    --- FAIL: FuzzDnp3 (0.00s)
        testing.go:1485: panic: interface conversion: cache.Value is nil, not *dnp3.DNP3
            goroutine 28 [running]:
            runtime/debug.Stack()
            	D:/dev/Go/go1.20.1/src/runtime/debug/stack.go:24 +0x9e
            testing.tRunner.func1()
            	D:/dev/Go/go1.20.1/src/testing/testing.go:1485 +0x1f6
            panic({0xec5240, 0xc0001149c0})
            	D:/dev/Go/go1.20.1/src/runtime/panic.go:884 +0x213
            app_go/pkg/dnp3.Decode({0xc00017e140, 0x124, 0x140})
            	D:/workspace/project/**/pkg/dnp3/dnp3.go:137 +0xf49
            app_go/pkg/dnp3.FuzzDnp3.func1(0x0?, {0xc00017e140?, 0x0?, 0xc182f9?})
            	D:/workspace/project/**/pkg/dnp3/dnp3_test.go:254 +0x45
            reflect.Value.call({0xeba2c0?, 0xf2f248?, 0xbff076?}, {0xf00b82, 0x4}, {0xc000114960, 0x2, 0x2?})
            	D:/dev/Go/go1.20.1/src/reflect/value.go:586 +0xb07
            reflect.Value.Call({0xeba2c0?, 0xf2f248?, 0x107dd00?}, {0xc000114960?, 0xf00080?, 0xc000112678?})
            	D:/dev/Go/go1.20.1/src/reflect/value.go:370 +0xbc
            testing.(*F).Fuzz.func1.1(0x0?)
            	D:/dev/Go/go1.20.1/src/testing/fuzz.go:335 +0x3f3
            testing.tRunner(0xc0001249c0, 0xc00012a630)
            	D:/dev/Go/go1.20.1/src/testing/testing.go:1576 +0x10b
            created by testing.(*F).Fuzz.func1
            	D:/dev/Go/go1.20.1/src/testing/fuzz.go:322 +0x5b9
        
  

FAIL
exit status 1
FAIL	**/dnp3	0.597s

进程 已完成,退出代码为 1


如果是真实的fuzz测试引发了crash,我们可以将该语料提取出来,建立针对它的TestXxx或为现有TestXxx添加一条测试数据来验证目标方法是否真实存在缺陷,如果的确存在缺陷,我们就需要修复它,并在修复后再次运行TestXxx,以保证我们的修复是有效的。

总结

Go fuzzing正式成为Go的“一等公民”,Go原生支持Fuzzing。我们可以利用fuzzing发现bug和安全问题。

参考资料

  1. fuzz-beta
  2. go.dev/doc/tutorial/fuzz
  3. fuzz

推荐一个零声学院免费教程,个人觉得老师讲得不错,分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,
fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,
TCP/IP,协程,DPDK等技术内容,点击立即学习文章来源地址https://www.toymoban.com/news/detail-428612.html

到了这里,关于Go Fuzzing:发现你未曾发现的漏洞的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 从前端JS逆向到发现后端越权漏洞的渗透测试之旅

    前言 本篇文章首发先知社区,作者为本公众号。 前端分析 首先搜索请求接口,未发现关键加密点 根据请求参数进行搜索 在js文件中找到aes加密key、iv 继续跟进,发现了两个加密函数:RsaEncrypt、AesEncrypt 搜索这两个函数没有太多信息。我们继续阅读混淆的js代码。 这里在进行

    2024年04月08日
    浏览(33)
  • 1漏洞发现

    相关名词解释: CVSS(Common Vulnerability Scoring System,即“通用漏洞评分系统”) CVSS是安全内容自动化协议(SCAP)的一部分 通常CVSS与CVE一同由每个国家漏洞库(NVD)发布并保持数据的更新 分值范围:0-10 不同机构按CVSS分值定义威胁的中、高、低威胁级别 CVSS体现弱点的风险,

    2024年02月05日
    浏览(29)
  • 漏洞发现

    如果我们要对特定的目标进行扫描的话,思路: 做好信息搜集(WEB、服务、中间件、框架、操作系统等信息) 根据所得到的信息使用各种工具来进行漏洞扫描 如果有些漏洞无法使用工具扫描到,那么就需要人工测试。 如果可以得到源码,还可以进行白盒测试。 优点:测试

    2024年02月19日
    浏览(24)
  • clickhouse 代替 es 如何对文档做模糊查询?

    模糊查询在日志存储的场景中非常普遍。 ClickHouse 作为大数据分布式引擎,理所当然地会被作为日志存储的备选方案。事实上使用 ClickHouse 作为日志存储方案,业界目前也已经在多家企业落地,比如 Uber 、石墨文档、映客、快手、携程、唯品会等。 日志查询的一个最大的特点

    2024年01月21日
    浏览(58)
  • 漏洞发现-API接口服务之漏洞探针类型利用修复(45)

    这里能探针到开放的端口,可以判断出端口的所属类型,这里涉及到证明检测,然后是证明利用可以对端口进行攻击, 端口服务开发这个端口,可以对这个端口进行攻击的。 apl接口, 主要针对应用上面的接口,有支付的,有订单的各种各样的端口, 最后一个就是补充的知识

    2024年02月08日
    浏览(35)
  • elasticSearch7版本文档中文属性模糊查询不准确

    1、问题:es文档中的某个属性值name的值如下所示 name\\\":\\\"catalog=Catalog(value=699015935012372480, displayName=/默认分组), status=3, updaterName=admin, updateTime=2023-02-01 14:33:17)status:已发布” 通过java模糊查询的api(QueryBuilders.fuzzyQuery)查询name为“已”的时候可以查询,查询为“已发布”的时候查

    2024年02月02日
    浏览(51)
  • Ghostscript开源PDF库中发现关键漏洞

    在Linux中广泛使用的PostScript语言和PDF文件开源解释器Ghostscript被发现存在严重远程代码执行漏洞。 该漏洞被标记为CVE-2023-3664,CVSS v3评级为9.8,影响10.01.2之前的所有Ghostscript版本,10.01.2是三周前发布的最新版本。 据Kroll公司的分析师G. Glass和D. Truman称,他们针对该漏洞开发了

    2024年02月16日
    浏览(33)
  • 思科路由器发现重大漏洞,解决方法是……

    晚上好,我是老杨。 思科知名度高,待遇也好,很多网工心生向往,也有很多人考过思科认证的相关证书,对思科的印象还是不错吧? 而且,作为美国著名的网络设备厂商,思科是全球路由器巨头,很多企业使用的关键路由器都离不开思科系列产品。 毕竟好用,还有知名度

    2023年04月14日
    浏览(48)
  • 【go-zero】docker镜像直接部署go-zero的API与RPC服务 如何实现注册发现?docker network 实现 go-zero 注册发现

    使用docker直接部署go-zero微服务会发现API无法找到RPC服务 用docker直接部署 我们会发现API无法注册发现RPC服务 原因是我们缺少了docker的network网桥 RPC服务运行正常 API服务启动,通过docker logs 查看日志还是未发现RPC API的yaml配置 RPC服务的IP是 127.0.0.1 与对应的端口 下图为改成了定

    2024年02月13日
    浏览(45)
  • 模糊测试面面观 | 模糊测试工具知多少

    自1988年威斯康星大学的Barton Miller首次提出模糊测试这一概念以来,模糊测试领域经历了持续长久发展。模糊测试作为一种软件测试方法,旨在通过向程序输入模糊、随机、异常的数据,探测和发现潜在的漏洞和错误。这种方法备受安全研究人员的青睐。随着时间的推移,这

    2024年02月09日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包