本文将探讨如何利用模糊测试工具go-fuzz,成功发现并分析了gomarkdown项目中的一个重要漏洞,即CVE-2024-44337。该漏洞涉及输入处理不当,能够被恶意攻击者利用,造成程序崩溃或拒绝服务。这个漏洞的ID编号已经申请出来了,但是细节还没来的急写上去,这是我挖到的第一个CVE,所以记录分析一下!
CVE-2024-44337简介:
包“github.com/gomarkdown/markdown”是一个 Go 库,用于解析 Markdown 文本并呈现为 HTML。在伪版本 ‘v0.0.0-20240729232818-a2a9c4f’ 对应于提交’a2a9c4f76ef5a5c32108e36f7c47f8d310322252’ 之前,在parser/block.go文件的paragraph函数中存在逻辑问题,此漏洞允许远程攻击者通过提供导致无限循环的特制输入来导致拒绝服务(DoS)条件,从而导致程序挂起并无限期地消耗资源。提交’a2a9c4f76ef5a5c32108e36f7c47f8d310322252’包含此问题的修补程序。
该漏洞修复的diff链接:
这里的漏洞成因非常微小,就只是一个if条件判断考虑失误造成的!
存在漏洞问修复的代码,代码位置parser/block.go:
...
if p.extensions&DefinitionLists != 0 {
if i < len(data)-1 && data[i+1] == ':' {
listLen := p.list(data[prev:], ast.ListTypeDefinition, 0, '.')
return prev + listLen
}
}
...
这段代码的主要功能是在段落中遇到定义列表项时,判断其是否符合定义列表的语法(是否有冒号 :
),并调用相应的函数 p.list
来处理列表条目。如果成功解析出定义列表,函数返回定义列表的结束位置,确保段落处理逻辑能够正确跳过定义列表部分继续解析。
在未修复的代码中,调用 p.list()
方法后会立即返回 prev + listLen
,但是没有验证 listLen
是否有效(即是否大于 0)。
漏洞修复后的代码:
...
if p.extensions&DefinitionLists != 0 {
if i < len(data)-1 && data[i+1] == ':' {
listLen := p.list(data[prev:], ast.ListTypeDefinition, 0, '.')
return prev + listLen
if listLen > 0 {
return prev + listLen
}
}
}
...
如果 p.list()
返回 0 或者其他异常值,程序没有足够的检查机制来处理这种情况,这可能导致程序进入一个无限循环或者挂起状态&