VulFi,即“漏洞发现者”,它是一个IDA Pro插件,可以帮助广大研究人员在二进制文件中查找漏洞。
它的的主要目标是在一个单一视图中给研究人员提供包含了各种函数交叉引用的相关信息。
对于可以使用Hexrays反编译器的情况,该工具还可以尝试排除针对这些函数的调用。
注意事项
在运行VulFi之前,请确保已经了解了你说要测试的代码,然后尝试识别所有的标准函数(例如strcpy和memcpy等),然后确保它们正确命名。
插件是大小写不敏感的,因此MEMCPY、Memcpy和memcpy都是可以识别的。
需要注意的是,搜索函数时需要精确匹配。这意味着or (或任何其他变体)不会被检测为标准函数,因此在寻找潜在漏洞时不会被考虑。
除此之外,VulFi将尽最大努力来过滤所有明显的误报。
请注意,虽然插件与特定架构没有任何联系,但某些处理器不完全支持指定类型,在这种情况下,VulFi 将简单地将所有交叉引用标记为潜在危险的标准函数,以便您继续进行手动分析. 在这些情况下,您可以从插件的跟踪功能中受益。
将vulfi.py、vulfi_prototypes.json和vulfi_rules.json文件放在 IDA 插件文件夹 ( cp vulfi* <IDA_PLUGIN_FOLDER>) 中。
用法
扫描
要启动扫描,请从顶部栏菜单中选择Search>选项。
VulFi这将启动新的扫描,或者它将读取存储在idb/i64文件中的先前结果。每当您保存数据库时,数据都会自动保存。
扫描完成或加载先前的结果后,将显示一个包含以下列的视图:
IssueName - 用作可疑问题的标题。
FunctionName - 函数的名称。
FoundIn - 包含可能感兴趣的引用的函数。
地址- 检测到的呼叫的地址。
状态- 审查状态,初始Not Checked分配给每个新项目。其他状态是False Positive和。这些可以使用给定项目上的右键单击菜单进行设置,并且应该反映给定函数调用的手动审查结果。SuspiciousVulnerable
优先级- 尝试将更有趣的呼叫优先于不太有趣的呼叫。可能的值为High和。优先级与文件中的其他规则一起定义。MediumLowvulfi_rules.json
评论- 给定项目的用户定义评论。
idb如果/文件内没有数据i64或用户决定执行新扫描。
该插件将询问它是否应该使用默认包含的规则运行扫描,或者是否应该使用自定义规则文件。
请注意,使用现有数据运行新扫描不会覆盖先前找到的由规则标识的与先前存储结果同名的项目。
因此,再次运行扫描不会删除现有的评论和状态更新。
在 VulFi 视图中的右键单击上下文菜单中,您还可以从结果中删除项目或删除所有项目。
请注意,执行此操作后,任何评论或状态更新都将丢失。
调查
每当您想检查检测到的可能存在漏洞的函数的实例时,只需双击所需行中的任意位置,IDA 就会将您带到被识别为可能感兴趣的内存位置。
使用右键单击和选项Set Vulfi Comment,您可以为给定实例输入注释(例如,证明状态)。
添加更多功能
该插件还允许创建自定义规则。这些规则可以在 IDA 接口中定义(适用于单个功能)或作为自定义规则文件提供(适用于旨在涵盖多个功能的规则)。
界面内
当您想要跟踪在分析期间识别的自定义函数时,只需将 IDA 视图切换到该函数,右键单击其主体内的任意位置并选择Add current function to VulFi
。
也可以加载具有多个规则集的自定义文件。要创建具有以下结构的自定义规则文件,您可以在此处使用包含的模板文件。
[ // 规则数组
{
"name" : " RULE NAME " , // 规则的名称
"alt_names" :[
" function_name_to_look_for " // 应与此规则中定义的条件匹配的所有函数名称的列表
],
"wrappers" : true , // 也寻找上述函数的包装器(注意包装的函数也必须匹配规则)
"mark_if" :{
"High" : " True " , // If 计算结果为 True,标记为高优先级(参见下面的规则)
“中”:“假”,//如果计算结果为真,则标记为优先中(参见下面的规则)
“低”:“假” //如果计算结果为真,优先标记低(见下面的规则)
}
}
]
查找所有对函数的交叉引用malloc并检查其参数是否不是常量以及是否检查函数的返回值的示例规则如下所示:
{
“名称”:“可能的空指针取消引用”,
“ alt_names” :[
“ malloc ”,
“ _ malloc” ,
“. malloc ”
],
“包装器”:假,
“mark_if”:{
“高”:“不是 param[0].is_constant() 而不是 function_call.return_value_checked() ”,
“中”:“假”,
“低”:“假”
}
}
规则
可用变量
param[<index>]: 用于访问函数调用的参数(索引从 开始0)
function_call:用于访问函数调用事件
param_count: 保存传递给函数的参数计数
可用功能
参数是否为常数:param[<index>].is_constant()
获取参数的数值:param[<index>].number_value()
获取参数的字符串值:param[<index>].string_value()
调用后参数是否设置为null:param[<index>].set_to_null_after_call()
是否检查函数的返回值:function_call.return_value_checked(<constant_to_check>)
例子
标记对第三个参数大于 5 的函数的所有调用:param[2].number_value() > 5
标记对第二个参数包含“%s”的函数的所有调用:"%s" in param[1].string_value()
标记对第二个参数不是常量的函数的所有调用:not param[1].is_constant()
标记对函数的所有调用,其中根据等于参数数量的值验证返回值:function_call.return_value_checked(param_count)
标记对返回值针对任何值进行验证的函数的所有调用:function_call.return_value_checked()
标记对一个函数的所有调用,其中从第三个开始的参数都不是常量:all(not p.is_constant() for p in param[2:])
标记对任何参数为常量的函数的所有调用:any(p.is_constant() for p in param)
标记对函数的所有调用:True
下载地址:https://github.com/Accenture/VulFi
声明:本公众号所分享内容仅用于网安爱好者之间的技术讨论,禁止用于违法途径,所有渗透都需获取授权!否则需自行承担,本公众号及原作者不承担相应的后果.
好文推荐
欢迎关注 系统安全运维